Umstellung: Generisches Schreiben und Lesen von (Konfigurations-) Dateien

Begonnen von betateilchen, 26 April 2014, 12:52:46

Vorheriges Thema - Nächstes Thema

betateilchen

Hallo Rudi,

diese Lösung ist wirklich prima, allerdings scheitert sie aktuell in der 01_FHEMWEB.pm

Dort müssen wir in "Edit files" unterscheiden, ob die Datei im Dateisystem oder in der Datenbank liegt, und dann die Datei von der entsprechenden Stelle lesen.


  } elsif($a[1] eq "edit") {
...
    if ($cfgDB eq 'configDB') {
      my $filePath = FW_fileNameToPath($fileName);
      my ($err,@content) = cfgDB_FileRead($filePath);
      $data = join("\n",@content);
    } else {
      $fileName =~ s,.*/,,g;        # Little bit of security
      my $filePath = FW_fileNameToPath($fileName);
      my($err, @data) = FileRead($filePath);
      if($err) {
        FW_pO "<div id=\"content\">$err</div>";
        return;
      }
      $data = join("\n", @data);
      close(FH);
    }


Es wird an dieser Stelle unterschieden, ob der Eintrag "configDB" am Ende des Links steht oder nicht.
Falls ja, wird die Datei aus der Datenbank gelesen => Völlig korrekt.

Falls nein, wird die Datei zum Lesen an FileRead() übergeben. FileRead stellt stellt dann anhand configDBUsed() fest, dass es auf die Datenbank zugreifen soll, obwohl das genau in dem Moment eine falsche Entscheidung ist. In dem Moment, wo in den obigen else() Zweig übergeben wird, muss die Datei immer aus dem Dateisystem gelesen werden.

Entweder sollte FileRead() einen (optionalen) Parameter bekommen, um das Lesen von einer bestimmten Stelle zu erzwingen oder wir brauchen eine systemisch andere Lösung.

Gleiches trifft vermutlich auch auf FileWrite() zu, das habe ich aber aktuell noch nicht geprüft.

Problemthread auch hier: http://forum.fhem.de/index.php/topic,24132.0.html
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

Danke fuer den Hinweis.

FileRead/FileWrite kann statt filename einen Hash als ersten Parameter bekommen, das schaut dann so aus:

FileRead({FileName=>$filePath, ForceType=>"file"} );

betateilchen

Tolle Lösung, danke :)

Ich denke, das ist ein Spezialfall, der ohnehin nur in der FHEMWEB auftreten wird. Aber mit der Lösung kann ich mir jetzt nochmal Gedanken machen, ob wir auf die Sonderbehandlung in der FHEMWEB vielleicht komplett verzichten können.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Hallo Rudi,

Zitat von: betateilchen am 01 Juni 2014, 16:48:18
mit der Lösung kann ich mir jetzt nochmal Gedanken machen, ob wir auf die Sonderbehandlung in der FHEMWEB vielleicht komplett verzichten können.

das scheint recht einfach zu klappen. Mit dem untenstehenden Patch kann ich auf die Sonderbehandlung in "style edit" und "style save" verzichten. Kannst Du da mal bitte drüberschauen? Ich habe das sowohl mit Dateien in der configDB als auch im Filesystem erfolgreich getestet.

Damit bleiben in der FHEMWEB nur noch zwei logikbedingt unvermeidbare Abfragen auf configDBUsed() übrig:


  • für das Ausblenden der fhem.cfg in "Edit files"
  • für das Lesen der FileList aus der Datenbank

Ich hoffe, das sollte nun alles in allem Deinen geäußerten Wünschen entsprechen.


Viele Grüße
Udo



Index: 01_FHEMWEB.pm
===================================================================
--- 01_FHEMWEB.pm (revision 6027)
+++ 01_FHEMWEB.pm (working copy)
@@ -1635,21 +1635,15 @@
     my $fileName = $a[2];
     my $data = "";
     my $cfgDB = defined($a[3]) ? $a[3] : "";
-    if ($cfgDB eq 'configDB') {
-      my $filePath = FW_fileNameToPath($fileName);
-      my ($err,@content) = cfgDB_FileRead($filePath);
-      $data = join("\n",@content);
-    } else {
-      $fileName =~ s,.*/,,g;        # Little bit of security
-      my $filePath = FW_fileNameToPath($fileName);
-      my($err, @data) = FileRead({FileName=>$filePath, ForceType=>"file"} );
-      if($err) {
-        FW_pO "<div id=\"content\">$err</div>";
-        return;
-      }
-      $data = join("\n", @data);
-      close(FH);
+    my $forceType = ($cfgDB eq 'configDB') ? $cfgDB : "file";
+    $fileName =~ s,.*/,,g;        # Little bit of security
+    my $filePath = FW_fileNameToPath($fileName);
+    my($err, @content) = FileRead({FileName=>$filePath, ForceType=>$forceType} );
+    if($err) {
+      FW_pO "<div id=\"content\">$err</div>";
+      return;
     }
+    $data = join("\n", @content);

     $data =~ s/&/&amp;/g;

@@ -1670,35 +1664,23 @@
   } elsif($a[1] eq "save") {
     my $fileName = $a[2];
     my $cfgDB = defined($a[3]) ? $a[3] : "";
+    my $forceType = ($cfgDB eq 'configDB') ? $cfgDB : "file";
     $fileName = $FW_webArgs{saveName}
         if($FW_webArgs{saveAs} && $FW_webArgs{saveName});
     $fileName =~ s,.*/,,g;        # Little bit of security
     my $filePath = FW_fileNameToPath($fileName);

-    if($cfgDB ne 'configDB') { # save file to filesystem
-
-      $FW_data =~ s/\r//g;
-      my $err = FileWrite({FileName=>$filePath, ForceType=>"file"}, split("\n", $FW_data));
-      if($err) {
-        FW_pO "<div id=\"content\">$filePath: $!</div>";
-        return;
-      }
-      my $ret = FW_fC("rereadcfg") if($filePath eq $attr{global}{configfile});
-      $ret = FW_fC("reload $fileName") if($fileName =~ m,\.pm$,);
-      $ret = ($ret ? "<h3>ERROR:</h3><b>$ret</b>" : "Saved the file $fileName");
-      FW_style("style list", $ret);
-      $ret = "";
-
-    } else { # save file to configDB
-      $FW_data =~ s/\r//g if($^O !~ m/Win/);
-      my @content = split(/\n/,$FW_data);
-      cfgDB_FileWrite($filePath,@content);
-      my $ret = FW_fC("reload $fileName") if($fileName =~ m,\.pm$,);
-      $ret = ($ret ? "<h3>ERROR:</h3><b>$ret</b>" :
-                        "Saved the file $fileName to configDB");
-      FW_style("style list", $ret);
-      $ret = "";
+    $FW_data =~ s/\r//g;
+    my $err = FileWrite({FileName=>$filePath, ForceType=>$forceType}, split("\n", $FW_data));
+    if($err) {
+      FW_pO "<div id=\"content\">$filePath: $!</div>";
+      return;
     }
+    my $ret = FW_fC("rereadcfg") if($filePath eq $attr{global}{configfile});
+    $ret = FW_fC("reload $fileName") if($fileName =~ m,\.pm$,);
+    $ret = ($ret ? "<h3>ERROR:</h3><b>$ret</b>" : "Saved the file $fileName to $forceType");
+    FW_style("style list", $ret);
+    $ret = "";

   } elsif($a[1] eq "iconFor") {
     FW_iconTable("iconFor", "icon", "style setIF $a[2] %s", undef);
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rudolfkoenig

ZitatIch hoffe, das sollte nun alles in allem Deinen geäußerten Wünschen entsprechen.

Ja, sehr, habs eingecheckt.

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!