Mehr Infos!?

475 views
Skip to first unread message

Achim

unread,
Sep 6, 2012, 2:08:56 PM9/6/12
to open...@googlegroups.com
Hallo,

ich finde euer Projekt sehr spannend, fänd' ein paar zusätzliche Infos aber sehr hilfreich. Von daher gleich eine Liste von Fragen:

- Ihr habt den Converter wirklich in Javascript geschrieben? ;-)

- Gibt's irgendwo eine rudimentäre Doku oder Orientierungshilfe zu den Daten? Mich würden besonders die Berliner U-Bahnen interessieren.

- Habt ihr das rechtlich abgeklärt? Wenn ihr eine existierende DB konvertiert, würde ich mal vermuten, daß das rechtliche Probleme gibt.

viele Grüße,
Achim

Michael Kreil

unread,
Sep 6, 2012, 4:15:54 PM9/6/12
to open...@googlegroups.com
- Ihr habt den Converter wirklich in Javascript geschrieben? ;-)

Ja, in node.js. Hat historische Gründe. Einfach nicht drüber nachdenken! ;)

- Gibt's irgendwo eine rudimentäre Doku oder Orientierungshilfe zu den Daten? Mich würden besonders die Berliner U-Bahnen interessieren.

Wir haben mal ein Wiki angefangen. Im Endeffekt hat uns die Dokumentation aber zu viel Zeit gekostet ... bei nur 2.5 Entwicklern.

Jetzt wäre jedoch vielleicht der richtige Zeitpunkt, damit zu beginnen.

 
- Habt ihr das rechtlich abgeklärt? Wenn ihr eine existierende DB konvertiert, würde ich mal vermuten, daß das rechtliche Probleme gibt.

Hier können keine Urheberrechtsansprüche geltend gemacht werden, da Fahrpläne nicht dem Urheberrecht unterliegen. Da sie überall aushängen, sind es auch keine Geschäftsgeheimnisse. Datenschutz greift auch nicht. Kurz: Frei Bahn mit Marzipan!




joesky

unread,
Sep 7, 2012, 10:06:09 AM9/7/12
to open...@googlegroups.com
habt Ihr hier an das "bald" kommende Leistungsschutzrecht gedacht? :-D

michael...@gmail.com

unread,
Sep 10, 2012, 6:04:29 PM9/10/12
to open...@googlegroups.com

On Thursday, September 6, 2012 10:15:54 PM UTC+2, Michael Kreil wrote:

- Habt ihr das rechtlich abgeklärt? Wenn ihr eine existierende DB konvertiert, würde ich mal vermuten, daß das rechtliche Probleme gibt.

Hier können keine Urheberrechtsansprüche geltend gemacht werden, da Fahrpläne nicht dem Urheberrecht unterliegen. Da sie überall aushängen, sind es auch keine Geschäftsgeheimnisse. Datenschutz greift auch nicht. Kurz: Frei Bahn mit Marzipan!


Hm ich fürchte ganz so einfach ist das nicht. Schließlich hängen ja auch die Namen von Straßen überall draußen herum. Und jeder weiß wie die Straße vor dem eigenen Haus heißt. Trotzdem kriegt OSM Probleme wenn sie einfach andere Kartenmaterialien nehmen und kopieren. Da müsste das gleiche Argument ja dann auch greifen...

-Michael

ruf...@gmail.com

unread,
Sep 12, 2012, 10:37:49 AM9/12/12
to open...@googlegroups.com
Hallo.

Zumindest ein kleines README (muss ja kein Roman sein), darüber, wie etwas gestartet wird o.ä.

Node.js habe ich installiert, node.js geclont

die config.json editiert zumindest so wie ich meine, dass es evtl. gemeint ist.

Und dann soll man z.B.
/var/www/openPlanB/node.js
sudo node scheduleByTrain.js starten?

Dabei kommt bei mir keine Meldung, dass der Server gestart ist o.ä.

Ich weiss, dass ich mich in Node.js einlesen sollte... aber wie gesagt ein kleine Hilfestellung, insbesondere zu config.json und wie das mit den Daten DBFahrplaninfo_2012_09 etc. zusammenpasst.
Muss man makeGTFS.js vorher verwenden?

Für mich hört sich "scheduleByTrain.js" jedenfalls am interessantesten an.


Jedenfalls: weiter so! Kann man nur begeistert unterstützen. Opendata für alle!

Grüße,
Eduard





Am Donnerstag, 6. September 2012 22:15:54 UTC+2 schrieb Michael Kreil:

Thomas Rehn

unread,
Sep 12, 2012, 1:14:31 PM9/12/12
to open...@googlegroups.com, ruf...@gmail.com
Ich versuche mal eine kurze Uebersicht:

Die config.json.tmpl sollte man nach config.json kopieren und dort bei Bedarf die Pfade anpassen. Die Pfade sind relativ zum Pfad, in dem config.json liegt. Am wichtigsten ist sicherlich planFolder, da sollten die plan* Dateien drin, die man sich irgendwo besorgt hat.
Momentan haben wir mindestens vier Skripte, die Daten extrahieren:
  • decode.js erzeugt TSV- (tab separated values) und JSON-Dateien im 'decodeFolder'; das sind fast alle Rohdaten, die in den Plan-Dateien stehen.
  • makeGTFS.js erzeugt GTFS-Dateien im 'gtfsFolder', momentan noch unvollstaendig
  • scheduleByTrain.js erzeugt eine Datei mit Fahrplan-Daten, das war mein erster Versuch alle Fahrplan-Daten aus den verschiedenen Plan-Quellen zu aggregieren; das Ergebnis ist vielleicht zum Debuggen der Datenextraktion gut, aber sonst nicht sinnvoll.
  • exportTrains.js erzeugt fuer jeden Zug einen moeglichst ausfuehrlichen und vollstaendigen Fahrplan als .txt-Datei im 'decodeFolder', Unterverzeichnis 'trains'
Jedes der Skripte kann man einfach mit
 node SKRIPTNAME
also bspw.
 node decode.js
ausfuehren. Es wird kein Server gestartet, sondern das JavaScript wird einfach ausgefuehrt.

Thomas Rehn

unread,
Sep 12, 2012, 1:19:32 PM9/12/12
to open...@googlegroups.com, ruf...@gmail.com
On Wednesday, September 12, 2012 7:14:31 PM UTC+2, Thomas Rehn wrote:
Die config.json.tmpl sollte man nach config.json kopieren und dort bei Bedarf die Pfade anpassen. Die Pfade sind relativ zum Pfad, in dem config.json liegt. Am wichtigsten ist sicherlich planFolder, da sollten die plan* Dateien drin, die man sich irgendwo besorgt hat.

Kleine Korrektur: in 'planFolder' direkt liegen keine plan*-Dateien.
Fuer jedes unterschiedliche Set von Fahrplan-Daten, das man hat (z.B. VBB, DB), legt man dort (in $planFolder) ein Unterverzeichnis an und kopiert die plan*-Dateien in dieses Unterverzeichnis. In der 'config.json' kann man dann bei Bedarf mit dem 'folderFilter' das Konvertieren auf ein solches Unterverzeichnis beschraenken.
Die Unterverzeichnisse in $decodeFolder und $gtfsFolder werden dann automatisch erzeugt, wenn ich mich recht erinnere.

ruf...@gmail.com

unread,
Sep 13, 2012, 5:47:43 AM9/13/12
to open...@googlegroups.com, ruf...@gmail.com
Vielen dank.

Diesen Text könnte man in das README in github kopieren. ;)

Jedenfalls, wenn ich recht verstehe, sind die Daten aus der Meldung http://openplanb.tumblr.com/post/30878899005/die-ersten-fahrplandaten, die decodierten tsv / json Dateien, die in z.B.
openPlanB_ ODbL1.0_2012-09-04/DBFahrplaninfo_2012_09/DB_P/ stehen.

Und beispielhaft eine config.json (Bsp. für : dekodierte Daten liegen in Verz. "data/")
{
        "planFolder":"",
        "decodeFolder":"data/DBFahrplaninfo_2012_09/",
        "gtfsFolder":"data/BFahrplaninfo_2012_09/",
        "folderFilter":"DB_P",
        "recursive":true,
        "planFilter":false
}


Dann habe ich folgendes versucht:
node exportTrains.js

Lief ohne Fehlermeldung, aber ich finde kein "trains" Verz. (?)

Gibt es eine verbose Option oder steht was in ein log (wo?)?

Und dann frage ich mich auch, was es mit "dataviz" auf sich hat und wie man es nutzt. Ist das die Visualisierung mit dem folgendes gemacht wurde: http://openplanb.tumblr.com/post/28713991405/da-uns-die-freilegung-der-fahrplaene-bereits-zu ?

Danke und Grüße,
Eduard

ruf...@gmail.com

unread,
Sep 13, 2012, 5:50:08 AM9/13/12
to open...@googlegroups.com, ruf...@gmail.com
Typo: es muss natürclih DBFahr... heissen:
        "gtfsFolder":"data/DBFahrplaninfo_2012_09/",

Thomas Rehn

unread,
Sep 13, 2012, 1:54:01 PM9/13/12
to open...@googlegroups.com, ruf...@gmail.com
On Thursday, September 13, 2012 11:47:43 AM UTC+2, ruf...@gmail.com wrote:
Dann habe ich folgendes versucht:
node exportTrains.js

Lief ohne Fehlermeldung, aber ich finde kein "trains" Verz. (?)

Gibt es eine verbose Option oder steht was in ein log (wo?)?
Die Skripte sind leider etwas experimentell und nicht besonders nutzerfreundlich. Wenn keine Ausgabe kommt, deutet das darauf hin, dass keine Eingabe-Dateien gefunden wurden. Deine config.json sieht etwas merkwuerdig aus. Wie gesagt, in $planFolder (das bei Dir leer ist) sollten Unterverzeichnisse, in denen die plan*-Dateien liegen. Wenn Du $folderFilter auf irgendwas ungleich 'false' setzt, wird nur das gleichnamige Unterverzeichnis beachtet. In Deinem Beispiel wuerde das heissen, dass in demselben Ordner von der config.json (weil $planFolder leer) ein Unterverzeichnis DB_P ist (das steht in Deinem $folderFilter), in dem die plan*-Dateien liegen.

Wenn das exportTrains.js Skript was zum exportieren findet, dann gibt es in Tausender-Schritten eine Ausgabe (beginnend mit 0). Wenn das Ausgabe-Verzeichnis nicht existiert, sollte eine JavaScript-Fehlermeldung kommen.
 
Und dann frage ich mich auch, was es mit "dataviz" auf sich hat und wie man es nutzt. Ist das die Visualisierung mit dem folgendes gemacht wurde: http://openplanb.tumblr.com/post/28713991405/da-uns-die-freilegung-der-fahrplaene-bereits-zu ?
Mit dem dataviz kennt sich eigentlich nur Michael aus. Wie gesagt: jeder der Entwickler hat sich bisher ein Tool fuer seine Beduerfnisse gehackt. 'decode.js' und 'makeGTFS.js' sind wohl am ehesten als 'Standard-Anwendungen' zu bezeichnen.

Leo Koppelkamm

unread,
Sep 13, 2012, 2:02:22 PM9/13/12
to open...@googlegroups.com
Das hat einen anderen Grund: Seit dem letzten commit wird kein PLANBZ_data.json mehr ausgegeben.
Ich habe das in meiner Fork behoben: https://github.com/DieBuche/openPlanB

Gruß Leo

ruf...@gmail.com

unread,
Sep 14, 2012, 5:02:42 AM9/14/12
to open...@googlegroups.com, ruf...@gmail.com
Schon mal danke, dass du dir die Zeit nimmst.

Mit plan Dateien meinst du die orginalen oder die dekodierten (tsv, json)?

D.h. Und der "planFolder" soll originale oder dekodierter Dateien enthalten?

die config.json wäre also nun so, wenn ich die EUROPA Dateien in DBFahrplaninfo_2012_09 ansprechen will
{
        "planFolder":"data/DBFahrplaninfo_2012_09/EUROPA/",
        "decodeFolder":"",
        "gtfsFolder":"",
        "folderFilter":false,
        "recursive":true,
        "planFilter":false
}

Oder verstehe ich das extrahieren der "Zug infos" gänzlich falsch, denn die Daten (aus dem torrent download) wsind ja  schon extrahiert und dekodierten? Also: planZUG.tsv o.ä.? exportTrains arbeitet natürlich nicht auf den schon exportierten daten, wozu auch?

D.h. exportTrains.js und die anderen Tools sind zum extrahieren aus den originalen plan Dateien da. Da hatte ich einen Knick in der Denke, oder? (peinlich)
Und DataViz (Michael werde ich noch ansprechen ;) arbeitet, dann auf den exportierten Daten?

Grüße,
Eduard

Leo Koppelkamm

unread,
Sep 14, 2012, 5:10:03 AM9/14/12
to open...@googlegroups.com
exportTrains arbeitet mit den json Dateien im decodeOrdner. Es erwartet u.a. eine json Datei mit dem Namen PLANBZ_data.json.
Das aktuelle ecode script hatte aber keine PLANBZ_data.json Datei mehr erzeugt, deswegen funktionierte dann exportTrains nicht mehr.

Ich glaube für dich wäre es am besten wenn du bei github meine form runterlädts, dann decode.js über die Rohdaten laufen lässt. Danach sollte exportTrains theoretisch funktionieren.

Gruß, Leo
> --
> Sie haben diese Nachricht erhalten, weil Sie der Google Groups-Gruppe openPlanB beigetreten sind.
> Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an open...@googlegroups.com (mailto:open...@googlegroups.com).
> Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an openplanb+...@googlegroups.com (mailto:openplanb+...@googlegroups.com).
> Besuchen Sie https://groups.google.com/d/msg/openplanb/-/nlKVHcMgLYYJ, um diese Diskussion im Web anzuzeigen.
> Weitere Optionen: https://groups.google.com/groups/opt_out
>
>



Darkstar

unread,
Sep 14, 2012, 5:39:09 AM9/14/12
to open...@googlegroups.com
Habt ihr eigentlich das HAFAS Dateiformat irgendwo dokumentiert? Dann könnte man einen (besseren) Konverter schreiben. Ich gebe zu ich selbst hab z.B. auch keine große Lust mich in die Konverter einzuarbeiten wenn die auf JavaScript basieren, aber ich würde mir zutrauen einen HAFAS->{XML,CSV, ...} Konverter in C/C++ zu basteln ;-)

On Wednesday, September 12, 2012 7:14:31 PM UTC+2, Thomas Rehn wrote:

Leo Koppelkamm

unread,
Sep 14, 2012, 5:41:11 AM9/14/12
to open...@googlegroups.com
Ich bin auch erst neu dabei, das Format ist leider nur im js code "dokumentiert". Javascript ist zwar ungewöhnlich, aber ich hatte bislang keine Probleme deswegen.
> --
> Sie haben diese Nachricht erhalten, weil Sie der Google Groups-Gruppe openPlanB beigetreten sind.
> Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an open...@googlegroups.com (mailto:open...@googlegroups.com).
> Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an openplanb+...@googlegroups.com (mailto:openplanb+...@googlegroups.com).
> Besuchen Sie https://groups.google.com/d/msg/openplanb/-/ra43yt8M4ucJ, um diese Diskussion im Web anzuzeigen.
> Weitere Optionen: https://groups.google.com/groups/opt_out
>
>



ruf...@gmail.com

unread,
Sep 14, 2012, 7:04:42 AM9/14/12
to open...@googlegroups.com

Am Freitag, 14. September 2012 11:10:07 UTC+2 schrieb Leo Koppelkamm:
exportTrains arbeitet mit den json Dateien im decodeOrdner. Es erwartet u.a. eine json Datei mit dem Namen PLANBZ_data.json.
Das aktuelle ecode script hatte aber keine PLANBZ_data.json Datei mehr erzeugt, deswegen funktionierte dann exportTrains nicht mehr.

Danke. Da war ich auch gerade. Und ich schaue mir nun den code an. ;)

Dann versuch' ich mich ans Konvertieren mit Rohdaten.


 

Ich glaube für dich wäre es am besten wenn du bei github meine form runterlädts, dann decode.js über die Rohdaten laufen lässt. Danach sollte exportTrains theoretisch funktionieren.

Tut mir leid dass ich in Sache github novice bin... und ein wenig ... dumm fragen muss: was heisst: "meine form runterlädts"?

github michomachine / openPlanB kenn ich. Dann muss ich was machen?

Grüße,
Eduard

 

Leo Koppelkamm

unread,
Sep 14, 2012, 7:16:09 AM9/14/12
to open...@googlegroups.com
Sorry, das war ein Typo, fork nicht form. Die findest du hier: https://github.com/DieBuche/openPlanB

Gruß


On Friday, 14 September 2012 at 13:04, ruf...@gmail.com wrote:

>
> Am Freitag, 14. September 2012 11:10:07 UTC+2 schrieb Leo Koppelkamm:
> > exportTrains arbeitet mit den json Dateien im decodeOrdner. Es erwartet u.a. eine json Datei mit dem Namen PLANBZ_data.json.
> > Das aktuelle ecode script hatte aber keine PLANBZ_data.json Datei mehr erzeugt, deswegen funktionierte dann exportTrains nicht mehr.
>
>
> Danke. Da war ich auch gerade. Und ich schaue mir nun den code an. ;)
>
> Dann versuch' ich mich ans Konvertieren mit Rohdaten.
>
>
> >
> > Ich glaube für dich wäre es am besten wenn du bei github meine form runterlädts, dann decode.js über die Rohdaten laufen lässt. Danach sollte exportTrains theoretisch funktionieren.
>
> Tut mir leid dass ich in Sache github novice bin... und ein wenig ... dumm fragen muss: was heisst: "meine form runterlädts"?
>
> github michomachine (https://github.com/michomachine) / openPlanB (https://github.com/michomachine/openPlanB) kenn ich. Dann muss ich was machen?
> > > Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an open...@googlegroups.com (javascript:) (mailto:open...@googlegroups.com (javascript:)).
> > > Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an openplanb+...@googlegroups.com (javascript:) (mailto:openplanb+...@googlegroups.com (javascript:)).
> > > Besuchen Sie https://groups.google.com/d/msg/openplanb/-/nlKVHcMgLYYJ, um diese Diskussion im Web anzuzeigen.
> > > Weitere Optionen: https://groups.google.com/groups/opt_out
> > >
> > >
> >
>
> --
> Sie haben diese Nachricht erhalten, weil Sie der Google Groups-Gruppe openPlanB beigetreten sind.
> Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an open...@googlegroups.com (mailto:open...@googlegroups.com).
> Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an openplanb+...@googlegroups.com (mailto:openplanb+...@googlegroups.com).
> Besuchen Sie https://groups.google.com/d/msg/openplanb/-/cd9ZqOixZMgJ, um diese Diskussion im Web anzuzeigen.
> Weitere Optionen: https://groups.google.com/groups/opt_out
>
>



ruf...@gmail.com

unread,
Sep 14, 2012, 10:46:18 AM9/14/12
to open...@googlegroups.com, ruf...@gmail.com
alles klar danke.

Hier mein Feedback:

* decode tut problemlos anhand orignaler DB plan Dateien von einer "DB ReiseService" Installation (DB12.CD). Output in decodeFolder.

* analyzeTSVIndexes: läuft, Output: diagramm.dia,  analysisIndexes.tsv in config.json Verz.

* makeGTFS output in gtfsFolder, aber bricht ab, ab hier
to "trips"
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory

Meine Kiste hat 10Gb Hauptspeicher, auf der Platte ist auch platz. Ich versuche hierbei nur "EUROPA" :

die config.json
{
    "planFolder":"../../DBCD_12/EUROPA/",
    "decodeFolder":"../../DBCD_12_decoded/",
    "gtfsFolder":"../../DBCD_12_gtfs/",

    "folderFilter":false,
    "recursive":true,
    "planFilter":false
}

* exportTrains.js: hier musste ich folgendes ändern:
"var planUtils = require('./gtfs_modules/schedule_utils.js');" (gts_modules hinzugefügt)
dann läuft's eine weile lang, bis

0
/home/pj/openPlanB/node.js/exportTrains.js:215
                    output += _clamp('                                                      
                              ^
ReferenceError: _clamp is not defined
    at scheduleByTrain (/home/pj/openPlanB/node.js/exportTrains.js:215:16)

* scheduleByTrain.js: auch hier
"var planUtils = require('./gtfs_modules/schedule_utils.js');" (gts_modules hinzugefügt)
dann läuft's eine weile lang, bis
0

/home/pj/openPlanB/node.js/scheduleByTrain.js:197
    output = [t, trainTypeName + ' ' + trainNumber, stationBegin.name, prettyTime
                                                                       ^
ReferenceError: prettyTime is not defined
    at scheduleByTrain (/home/pj/openPlanB/node.js/scheduleByTrain.js:197:72)
    at Object.<anonymous> (/home/pj/openPlanB/node.js/scheduleByTrain.js:22:1)


aber trotzdem echt schon gut, vielleicht weiss ich noch nicht in welcher Reihenfolge die Skripte läufen müssen...


Grüße,
Eduard

pj

unread,
Sep 15, 2012, 8:05:19 AM9/15/12
to open...@googlegroups.com, ruf...@gmail.com
Nun  funktioniert scheduleByTrains  problemlos (aus Leo's branch).

aber

node makeGTFS.js
Converting "/home/pj/DBCD_12_decoded"
   to "agency"
   to "transfers"
   to "routes"
   to "stops"

   to "trips"
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory

und

exportTrains läuft nun schon eine ganze weile output
120000
121000
122000
123000
124000
...

wieviel kann es werden?

Ed.

mit config.json

pj

unread,
Sep 15, 2012, 11:27:44 AM9/15/12
to open...@googlegroups.com, ruf...@gmail.com
mit mehr speicher :

node --max-old-space-size=8192  makeGTFS.js
Converting "/home/pj/DBCD_12_decoded"
   to "agency"
   to "transfers"
   to "routes"
   to "stops"
   to "trips"

/home/pj/openPlanB/node.js/gtfs_modules/gtfs_trips.js:106
            var currentStop = trainSchedule[stopID][seenStops[stopID]];
                                                   ^
TypeError: Cannot read property '0' of undefined
    at Object.exports.makeGTFS (/home/pj/openPlanB/node.js/gtfs_modules/gtfs_trips.js:106:43)
    at Object.exports.makeGTFS (/home/pj/openPlanB/node.js/gtfs_modules/gtfs_utils.js:58:27)
    at Object.<anonymous> (/home/pj/openPlanB/node.js/makeGTFS.js:12:11)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

pj

unread,
Sep 15, 2012, 12:53:09 PM9/15/12
to open...@googlegroups.com, ruf...@gmail.com
Problem liegt an gtfs_modules/gtfs_trips.js ca. Zeile 106
                        seenStops[stopID] = seenStops[stopID] || 0;

mit folgendem ein workaround machen und dann untersuchen weshalb die stopID nicht existiert

seenStops[stopID] = seenStops[stopID] || 0;
console.log(seenStops[stopID]);
if( seenStops[stopID] == 0 ) {
console.log("continue !");
                                continue;
                        }


Bsp. Fälle

s = 17
stopID = 22139
seenStops[stopID] = undefined
seenStops[stopID] 0

Michael Kreil

unread,
Sep 17, 2012, 11:07:34 AM9/17/12
to open...@googlegroups.com, ruf...@gmail.com
OK, ich hab (endlich) mal eine README.md angelegt! Ich dachte, nach fast 2 Monaten ist das mal angebracht. ;)

Kann man aber gerne überarbeiten und glatt feilen ...

pj

unread,
Oct 2, 2012, 9:44:24 AM10/2/12
to open...@googlegroups.com, ruf...@gmail.com
Schon mal sehr gut. :)

Eduard
Reply all
Reply to author
Forward
0 new messages