Christoph Schnauß: Betriebsblindheit :-(

hallo Forum ;-)

vor wenigen Tagen hatte ich mal was nachgefragt, was jetzt zu Recht im Archiv gelandet ist (http://forum.de.selfhtml.org/archiv/2002/5/11571/). Die Problemstellung hatte sich auflösen lassen.

Aber jetzt habe ich plötzlich ein neues Problem mit demselben Script: vor der Umarbeitung konnte es Zeilenumbrüche schreiben, die hab ich bei der Überarbeitung irgendwo irgendwie rausgeschmissen (aus Versehen) und finde jetzt die Stelle nicht mehr.

Zur Erinnerung: es ist ein Forumscript, sehr ähnlich dem, was auch hier noch vor anderthalb Jahren in Betrieb war. Es macht (vom Aussehen her) fast dasselbe, nur kriegen die postings keine Zeilenumbrüche mehr mit. Das steckt irgendwo in der Textarea  -  und da wohl auch noch immer in den RegExpressions, mit denen die Variable, die den Inhalt der Textarea enthält, "verarbeitet" wird. Konkret ist es irgendwas an der Konstruktion

print NEU "<td><textarea name="body" cols="80" rows="20">";
   @zeilen1 = split(/&lt;p&gt;/,$hidden_body);
   foreach $zeile1 (@zeilen1) {
      @zeilen = split(/&lt;br&gt;/,$zeile1);
      foreach $zeile (@zeilen) {
         print NEU "»» $zeile\n";
      }
   }

Da wird ein Zeilenumbruch ausgelassen.

Eventuell hängt es auch schon dort, wo der Inhalt der Textarea in eine Variable $body geschrieben wird  -  die in dem Schnipsel verwendete Variable $hidden_body wird so gefüllt:

$hidden_body = "$body";
   $hidden_body =~ s/</&lt;/g;
   $hidden_body =~ s/>/&gt;/g;
   $hidden_body =~ s/"/&quot;/g;

Das gesamte Script ist einsehbar unter (link:http://www.christoph-schnauss.de/misc/kurs/forum/forumscript.txt]  und ich muß jetzt erstmal irgendwoanders hin schauen, um meine "Betriebsblindheit" loszuwerden.

Grüße aus Berlin

Christoph S.

  1. hallo Forum ;-)

    hallo Christoph,

    Konkret ist es irgendwas an der Konstruktion

    print NEU "<td><textarea name="body" cols="80" rows="20">";
       @zeilen1 = split(/&lt;p&gt;/,$hidden_body);
       foreach $zeile1 (@zeilen1) {
          @zeilen = split(/&lt;br&gt;/,$zeile1);
          foreach $zeile (@zeilen) {
             print NEU "»» $zeile\n";
          }
       }

    Da wird ein Zeilenumbruch ausgelassen.

    die funktion split teilt deinen String so auf

    x1|x2|x3||

    ('x1','x2,'x3',undef)

    foreach gibt dann natürlich nur 3 Elemente

    ich hoffe das gibt einen Denkanstoss.

    PS. übrigens ist foreach Perl4 Syntax

    mfg. oesi50

    1. guten Morgen,

      die funktion split teilt deinen String so auf
      x1|x2|x3||
      ('x1','x2,'x3',undef)

      oh. Das ist mir völlig neu, und das kann ich auch nicht nachvollziehen. Nach meiner Lesart ist "split" keine Funktion, sondern eine Perl-Anweisung, die lediglich zwei Parameter übergeben bekommt. Die Backslashes sind "Maskierungen"

      PS. übrigens ist foreach Perl4 Syntax

      Jaein. Aber _diese_ Diskussion hatten wir bereits. Ich habs mehr oder weniger aus Bequemlichkeit und/oder Nostalgie stehengelassen und nicht in "for" verwandelt, was im übrigen an der Fragestellung meines postings leider nix verändern würde

      Grüße aus Berlin

      Christoph S.

      1. Hallo Christoph,

        die funktion split teilt deinen String so auf
        x1|x2|x3||
        ('x1','x2,'x3',undef)

        oh. Das ist mir völlig neu, und das kann ich auch nicht nachvollziehen. Nach meiner Lesart ist "split" keine Funktion, sondern eine Perl-Anweisung, die lediglich zwei Parameter übergeben bekommt. Die Backslashes sind "Maskierungen"

        Auszug aus der Perldoku (Kapitel perlfunc):

        split /PATTERN/,EXPR,LIMIT

        split /PATTERN/,EXPR

        split /PATTERN/

        split

        Splits a string into a list of strings and returns that list. By default, empty leading fields are preserved, and empty trailing ones are deleted.
        If not in list context, returns the number of fields found and splits into the @_ array. (In list context, you can force the split into @_ by using ?? as the pattern delimiters, but it still returns the list value.) The use of implicit split to @_ is deprecated, however, because it clobbers your subroutine arguments.

        If EXPR is omitted, splits the $_ string. If PATTERN is also omitted, splits on whitespace (after skipping any leading whitespace). Anything matching PATTERN is taken to be a delimiter separating the fields. (Note that the delimiter may be longer than one character.)

        If LIMIT is specified and positive, splits into no more than that many fields (though it may split into fewer). If LIMIT is unspecified or zero, trailing null fields are stripped (which potential users of pop would do well to remember). If LIMIT is negative, it is treated as if an arbitrarily large LIMIT had been specified.

        Split ist eine Perlfunktion und teilt einen String in Teilstrings auf.
        Das Ergebnis ist eine Liste mit einzelnen Elementen.
        Eine Liste ist entweder das mit der Schnecke dran (@liste)
        oder eine Liste von Variablen ($a1,$a2,..,usw)

        mfg oesi

        1. hi,

          ähm, ja, oesi ...

          Auszug aus der Perldoku (Kapitel perlfunc):

          die Doku kenne ich ganz gut. Und ich mag dich jetzt auch nicht "verprellen", weil du versucht hast, einen gutgemeinten Rat zu geben, aber du hättest dir

          split /PATTERN/,EXPR,LIMIT

          eben mal genau ankucken und mit meinem Script vergleichen müssen. Dann wäre dir aufgefallen, daß ich eben genau und penibel diese Form eingehalten habe. Was Du verwechselt bzw. übershen hast, ist ganz einfach, daß ich in meinem Script noch ein paar Backslashes stehen habe, und daß es einen sehr großen Unterschied macht, ob man einen Backslash oder einen Slash schreibt ;-)

          danke dir trotzdem für den Versuch einer Antwort.

          Grüße aus Berlin

          Christoph S.

  2. Hallo Christoph,

    nachdem sich oesi50 so in die Nesseln gesetzt hat, schreibe ich mal,
    was mir zu dem Script so auffaellt.

    Zunaechst waere das einmal, dass Du das Meta 'strict' nicht benutzt.
    Das wuerde ich an deiner Stelle dringend tun, dann wirds auch weniger
    mit den Fehlern. Dann oeffnest du jegliche Dateien mit ohne
    Filelocking. Auch das musst du *dringend* aendern. Du kannst ja z.B.
    das Modul vom Selfforum nehmen, das ist da sehr einfach zu
    bedienen und IMHO relativ sicher. Dann wuerde ich an deiner Stelle
    statt 'parse_form' 'use CGI qw/param/' benutzen. Dann laesst sich
    eine Stelle ganz stark verkuerzen:

    if ($followup == 1) {
          foreach $followup_num (@followup_num) {
             print NEU "$followup_num,";
          }
       }

    in:

    print NEU join(',',@followup_num),',' if $followup;

    Dann weiter:

    @zeilen1 = split(/&lt;p&gt;/,$hidden_body);

    Es ist ein Fehler, zuviel zu maskieren:

    @zeilen1 = split(/<p>/,$hidden_body);

    Dann kannst du den ganzen Abschnitt

    foreach $zeile1 (@zeilen1) {
          @zeilen = split(/&lt;br&gt;/,$zeile1);
          foreach $zeile (@zeilen) {
             print NEU "»» $zeile\n";
          }
       }

    Viel besser so schreiben:

    $hidden_body =~ s/<p>/\n\n/sg;
    $hidden_body =~ s/<br>/\n/sg;
    print $hidden_body;

    Das ist erstens viel schneller und zweitens viel kuerzer.

    Dann ist mir aufgefallen, dass du in den open()-Aufrufen ab und zu
    den Open-Modus nicht mit angibst. Das wuerde ich an deiner Stelle
    tun. Also anstelle von 'open(MAIN,"$basedir/$mainfile")' besser
    'open(MAIN,"<$basedir/$mainfile")'. Gut, weiter:

    open(MAIN,"$basedir/$mainfile") || die $!;
       @main = <MAIN>;
       close(MAIN);

    Das wuerde ich an deiner Stelle so nicht tun. Das ist erstens sehr
    langsam und zweitens sehr Speicherintensiv. Schreibe lieber die
    neue Datei erstmal in eine temporaere Datei (z. B.
    "$basedir/$mainfile.$$") und benenne die dann um. Dann kannst du
    naemlich statt dem 'foreach $main_line (@main)' ein sinnvolleres
    'while($main_line = <MAIN>)' machen. Dasselbe natuerlich in 'sub
    thread_pages' auch. Und dann wuerde ich an deiner Stelle den Einsatz
    von Here-Dokumenten mir ganz schwer ueberlegen :-) Dann folgende
    Zeile:

    print "<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">\n";

    Bist du dir *sicher*, dass du diesen Charset benutzen willst? Der
    ist ziemlich boese...

    Dann Aufrufe wie '&rest_of_form;'. Die wuerde ich aendern in
    'rest_of_form();', einfach aus dem Grunde, dass bei der ersten
    Version @_ nicht neu gesetzt wird. Wenn ich also schreibe '@_ =
    qw(hallo du da);', dann enthaelt @_ in der Funktion immer noch
    ('hallo','du','da').

    Dann das hier:

    $FORM{'body'} =~ s/\r\n/\n/g;

    Schreib besser

    $FORM{body} =~ s/\015\012|\012|\015/\012/g;

    Dann gilt das ganze Plattformunabhaengig.

    Gruesse,
     CK

    1. hi Christian,

      schönen Dank für deine Hinweise. Mein "Grundkonflikt" mit dem verwendeten Script ist einfach der, daß ich über die "Schwächen" des alten Scripts, die du mal wieder ziemlich genau herausgefischt hast, auch ganz gut unterrichtet bin (siehe der im Ausgangsposting zitierte Thread vor ein paar Tagen)  -  aber ich hatte schlicht und einfach keine Lust, "alles" neu zu schreiben. Jedenfalls nicht für diesen Einsatz.

      Ich baue ja schon an einer anderen Konstruktion, bei der mir der Vergleich mit den Forumsourcen sehr hilft, bin da aber noch nicht fertig. Und solange ich nicht "fertig" bin, muß ich halt erstmal das nehmen, was (wenn auch nicht mehr ganz zeitgemäß) jedenfalls funktioniert. Interessant ist vielleicht noch der Hinweis, daß mein Script _wirklich_ bei einem der ganz wenigen Provider läuft, die als Sever den IIS einsetzen, also nicht den Apache. Da gibts dann, wenn man tiefer in die Details gehen möchte, doch noch ein paar Unterschiede, auch in bezug auf Serverlast (und ihre "Bewältigung") und sowlches Zeugs

      Ich will jetzt nicht auf deine einzelnen Anmerkungen eingehen, nur eins will ich dazu sagen:
      Du hast eine ziemlich fundierte Kritik des Gesamtscripts geliefert, die ich auch dankbar annehme  -  aber die eigentliche Frage lösen deine Hinweise auch nicht :-(

      na gut. Ich werde mich doch dazu aufraffen, die alte Vorlage zu verlassen und ein wirklich "eigenes" Script schreiben. Bei den "Zielgruppen", für die ich bisher überhaupt so ein Forumscript benötigt habe, brauche ich nicht ganz so viel Rücksicht auf Traffic usw. zu nehmen wie du das für das aktuelle Forumscript-Konvolut tun mußt.

      <themenwechsel>
      hehe, aber da gibts in den Sourcen auf sourceforge plötzlich allerhand cpp-files, ja, warum denn das ? Ist das bloß Spiel- und Bastelfreude oder genügt die bisherige Konstruktion aus XML und PERL doch den Anforderungen nicht mehr ?
      </themenwechsel>

      Man sollte die Matt-Wright-Scripts wohl doch ins Museum stellen. Aber ich gebe gerne zu, daß sie mir im Lauf der Zeit sehr viel weitergeholfen haben.

      Grüße aus Berlin

      Christoph S.

      1. Hallo Christoph,

        Ich will jetzt nicht auf deine einzelnen Anmerkungen eingehen,
        nur eins will ich dazu sagen:
        Du hast eine ziemlich fundierte Kritik des Gesamtscripts
        geliefert, die ich auch dankbar annehme  -  aber die eigentliche
        Frage lösen deine Hinweise auch nicht :-(

        Ich habe dein Script mal genommen und Filelocking eingebaut und das
        mit den Zeilenumbruechen verbessert. Du musst nur noch die Pfade
        wieder anpassen. Leider ist es zu lang fuer einen Beitrag, also
        schick ichs dir per Mail.

        hehe, aber da gibts in den Sourcen auf sourceforge plötzlich
        allerhand cpp-files,

        Bin ich blind? Ich seh da nur .pm, .xml und .pl Dateien.

        ja, warum denn das?

        Weil das neue Forum in C geschrieben wird :-)

        Ist das bloß Spiel- und Bastelfreude

        Nein.

        oder genügt die bisherige
        Konstruktion aus XML und PERL doch den Anforderungen nicht mehr?

        Genau.

        Gruesse,
         CK

        1. hallo Christian,

          Ich habe dein Script mal genommen und Filelocking eingebaut und das
          mit den Zeilenumbruechen verbessert. Du musst nur noch die Pfade
          wieder anpassen. Leider ist es zu lang fuer einen Beitrag, also
          schick ichs dir per Mail.

          danke, ist inzwischen gelandet -  will allerdings mit dem "lock.pm", das ich habe, nicht richtig:  "Can't locate object method "new" via package "Lock" (perhaps you forgot to load "Lock"?) at forum.pl line 92". Die Zeile, an der das Script hängenbleibt, ist
          my $lock = new Lock("$basedir/$datafile");

          hehe, aber da gibts in den Sourcen auf sourceforge plötzlich
          allerhand cpp-files,
          Bin ich blind? Ich seh da nur .pm, .xml und .pl Dateien.

          'tschuldigung, ich war im selfsuche-Verzeichnis. Im Forumsverzeichnis gibts nur c- und h-files ;-)

          Grüße aus Berlin

          1. Hoi Christoph,

            Ich habe dein Script mal genommen und Filelocking eingebaut und
            das mit den Zeilenumbruechen verbessert. Du musst nur noch die
            Pfade wieder anpassen. Leider ist es zu lang fuer einen Beitrag,
            also schick ichs dir per Mail.

            danke, ist inzwischen gelandet -  will allerdings mit dem "lock.pm",
            das ich habe, nicht richtig:

            Dann kopiere dir die Dateien von

            http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/selfforum/selfforum-cgi/shared/

            Du brauchst die Datei 'Lock.pm' und alle Dateien aus dem Verzeichnis
            'Lock'. Die Datei 'Lock.pm' einfach in das Verzeichnis vom Script
            kopieren, die anderen Dateien aus dem Verzeichnis 'Lock' in ein
            Verzeichnis 'Lock' im Script-Verzeichnis kopieren.

            hehe, aber da gibts in den Sourcen auf sourceforge plötzlich
            allerhand cpp-files,
            Bin ich blind? Ich seh da nur .pm, .xml und .pl Dateien.
            'tschuldigung, ich war im selfsuche-Verzeichnis. Im
            Forumsverzeichnis gibts nur c- und h-files ;-)

            Ich glaube, du bist auf dem falschen Server. Bei SF.net im CVS gibt
            es keine derartigen Dateien.

            Gruesse,
             CK

            1. hi,

              Du brauchst die Datei 'Lock.pm' und alle Dateien aus dem Verzeichnis
              'Lock'. Die Datei 'Lock.pm' einfach in das Verzeichnis vom Script
              kopieren, die anderen Dateien aus dem Verzeichnis 'Lock' in ein
              Verzeichnis 'Lock' im Script-Verzeichnis kopieren.

              ja, hatte ich eben bei genauerem Nachsehen in Lock.pm gemerkt. Jetzt funktionierts erstmal lokal, jetzt muß ich sehen, was der Provider dazu sagt.

              Ich glaube, du bist auf dem falschen Server. Bei SF.net im CVS gibt
              es keine derartigen Dateien.

              Ich habe unter http://cvs.teamone.de/cgi-bin/cvsweb.cgi/selfforum/src/ nachgeschaut, einige Dateien dort sind noch sehr jung, und es sind alles c- und h-files

              Grüße

              Christoph S.

              1. Hoi,

                ja, hatte ich eben bei genauerem Nachsehen in Lock.pm gemerkt.
                Jetzt funktionierts erstmal lokal,

                Na also :-)

                jetzt muß ich sehen, was der Provider dazu sagt.

                Oehm... FTP nehmen und hochladen geht nicht? Hast du keinen Zugriff
                auf dein eigenes cgi-bin?

                Ich glaube, du bist auf dem falschen Server. Bei SF.net im CVS
                gibt es keine derartigen Dateien.
                Ich habe unter
                http://cvs.teamone.de/cgi-bin/cvsweb.cgi/selfforum/src/
                nachgeschaut,

                *seufz* Die URL sollte eigentlich noch nicht Publik gemacht
                werden ;-) erst nach der Neueroeffnung des Forums.

                einige Dateien dort sind noch sehr jung, und es sind alles c-
                und h-files

                Ja, das ist das neue SELFHTML Forum. Das wird in C geschrieben, weil
                Perl uns zu langsam wurde ;-) Ausserdem verfolgt es ein *komplett*
                anderes Konzept.

                Gruesse,
                 CK

                1. hi,

                  Oehm... FTP nehmen und hochladen geht nicht? Hast du keinen Zugriff
                  auf dein eigenes cgi-bin?

                  dochdoch, aber da sind zur Zeit keine *.pm-Dateien möglich, vielleicht gibts nen Trick mit einem Unterverzeichnis  -  der IIS läßt sich gelegentlich so austricksen

                  *seufz* Die URL sollte eigentlich noch nicht Publik gemacht
                  werden ;-) erst nach der Neueroeffnung des Forums.

                  ups ... wenn ich damit unbeabsichtigt einen "Notfall" produziert habe, kann das posting ja wieder gelöscht werden

                  Grüße

                  Christoph S.

                  1. Hoi Christoph,

                    Oehm... FTP nehmen und hochladen geht nicht? Hast du keinen Zugriff
                    auf dein eigenes cgi-bin?

                    dochdoch, aber da sind zur Zeit keine *.pm-Dateien möglich, vielleicht gibts
                    nen Trick mit einem Unterverzeichnis  -  der IIS läßt sich gelegentlich so
                    austricksen

                    Oh man, bin ich froh, nix mit dem zu tun zu haben.

                    *seufz* Die URL sollte eigentlich noch nicht Publik gemacht
                    werden ;-) erst nach der Neueroeffnung des Forums.
                    ups ... wenn ich damit unbeabsichtigt einen "Notfall" produziert habe, kann
                    das posting ja wieder gelöscht werden

                    Iwo, so schlimm ists nun auch wieder nicht ;-)

                    Gruesse,
                     CK