#1 23. März 2010 WKW Birthday AutoPoster Hi! Hab schon oft überlegt einen AutoPoster für Wer-Kennt-Wen zu schreiben, damit ich meinen Bekannten automatisch zum Geburtstag gratuliere. Sowas hab ich dann mal programmiert. Der Bot fragt euch bei jeder Person, die heute Geburtstag hat, ob ihr eine Nachricht sendet möchtet und ob der Name, der bei WKW angegeben wurde auch korrekt ist. Andernfalls könnt ihr den Namen verwenden, den ihr möchtet. Version: Python 2.6 Plattform: nur Win getestet 3rd party Libs: mechanize (hier ladbar) wkw.py: PHP: # -*- coding: iso-8859-1 -*- import mechanizeimport reimport urllibimport timeimport randomimport getpassimport sys browser = mechanize . Browser () browser . set_handle_robots ( False ) # "robots.txt" ignorieren def Login ( user , password ): global browser browser . open ( 'http://www.wer-kennt-wen.de/' ) # Seite oeffnen browser . select_form ( nr = 0 ) # Erste (und einzige) Form auf der Seite anwaehlen browser [ 'loginName' ] = user # Die Werte fuer die Form setzen browser [ 'pass' ] = password browser . submit () # Die form mit den Werten abschicken f = browser . open ( 'http://www.wer-kennt-wen.de/start' ) content = f . read () if content . find ( '<h1>Persönliche Startseite</h1>' ) != - 1 : return True else: return False def LogOut (): global browser browser . open ( 'http://www.wer-kennt-wen.de/logout' ) def getFriendCount (): global browser f = browser . open ( 'http://www.wer-kennt-wen.de/person' ) content = f . read () regex_count = '<h2><span>Du kennst ([0-9]+) Leute</span></h2>' pat_count = re . compile ( regex_count , re . I ) count = - 1 if pat_count . search ( content ): count = pat_count . search ( content ). group ( 1 ) else: pass return int ( count ) def getTodaysBirthdays (): global browser wkw_url = 'http://www.wer-kennt-wen.de/' f = browser . open ( wkw_url + 'start' ) content = f . read () regex_bday = "<a href=\"/(person/[a-zA-Z0-9]+)\">([^<]+)</a> hat\r\n(?:\s*)heute\r\n(?:\s+)Geburtstag!" pat_bday = re . compile ( regex_bday , re . I ) bdays = None if pat_bday . search ( content ): bdays = [] for x in pat_bday . finditer ( content ): tmp_bday = wkw_url + x . group ( 1 ), x . group ( 2 ) bdays . append ( tmp_bday ) return bdays def leaveMessage ( url , message ): global browser wkw_url = 'http://www.wer-kennt-wen.de/' f = browser . open ( url ) content = f . read () regex_hash = '<input type=\"hidden\" name=\"_hash\" value=\"([a-f0-9]+)\" id=\"_hash\"></span>' regex_hashkey = '<input type=\"hidden\" name=\"_hashKey\" value=\"([0-9]+)\" id=\"_hashKey\"></span><span>' regex_url = '<form action=\"/(guestbook/new/[a-z0-9]+)\" method=\"post\" id=\"writeFormGuestbook\">' pat_hash = re . compile ( regex_hash , re . I ) pat_hashkey = re . compile ( regex_hashkey , re . I ) pat_url = re . compile ( regex_url , re . I ) hash = "" hashkey = "" url = "" if pat_hash . search ( content ) and pat_hash . search ( content ) and pat_url . search ( content ): hash = pat_hash . search ( content ). group ( 1 ) hashkey = pat_hashkey . search ( content ). group ( 1 ) post_url = wkw_url + pat_url . search ( content ). group ( 1 ) params = urllib . urlencode ({ '_hashKey' : hashkey , '_hash' : hash , 'body' : message }) f = browser . open ( post_url , params ) content = f . read () if content . find ( 'Dein Gästebucheintrag wurde gespeichert.' ) != - 1 : return True else: return False else: return False def readMessages ( file , repl_name , name , namepart ): # namepart can be 'f', 'l' or 'b' be # f: first name # l: last name # b: both try: f = open ( file , 'r' ) content = f . read () nameparts = name . split ( ' ' ) names = { 'f' : nameparts [ 0 ], 'l' : nameparts [- 1 ], 'b' : name } content = content . replace ( repl_name , names [ namepart ]) messages = content . split ( ';;\n' ) f . close () return messages except : return None # ENTRY POINT!!!!! if len ( sys . argv ) != 3 : print '#######################################################' print '########## Wer-Kennt-Wen Birthday Autoposter ##########' print '################### by cable © 2010 ###################' print '#######################################################' print '# Usage: wkw.py <file> <random> #' print '# -------------------------------------------------- #' print '# Example: wkw.py messages.txt 1 #' print '# Messages are divided by ;; and newline #' print '# %NAME% in a message will be replaced with the name #' print '# Random (bool): use random message or always the 1st #' print '#######################################################' exit() file = sys . argv [ 1 ] rand = sys . argv [ 2 ] # get email address to log in print '#######################################################' print '########## Wer-Kennt-Wen Birthday Autoposter ##########' print '################### by cable © 2010 ###################' print '#######################################################' print 'Please type in your E-Mail address:' , # anonyme version mail = raw_input () mail = mail . replace ( '\r' , '' ) # mail = 'wkwbot@rockstheplanet.com' # get password# anonyme version password = getpass . getpass ( 'Please type in your password: ' ) # password = '' if Login ( mail , password ): print 'Login was successful!' friendCount = getFriendCount () if friendCount > - 1 : print 'You have ' + str ( friendCount ) + ' friends!\n' else: print 'An unexpected error occurred,' print 'Could not parse the friend count!\n' bdays = getTodaysBirthdays () if bdays : print 'Birthdays of today:' bcount = 0 for b in bdays : print b [ 1 ] + ': ' + b [ 0 ] + ' ...' print 'Want to send greetings? [y/n]:' , if raw_input (). find ( 'y' ) != - 1 : if bcount > 0 : print 'Waiting 15 seconds until next post...' time . sleep ( 15 ) bcount += 1 print 'Is' , b [ 1 ], 'the right name? [y/n]:' , if raw_input (). find ( 'y' ) != - 1 : messages = readMessages ( file , '%NAME%' , b [ 1 ], 'f' ) else: n = raw_input ( 'Type in the person\'s correct name: ' ) messages = readMessages ( file , '%NAME%' , n , 'b' ) if messages : mes_count = len ( messages ) if rand != 0 : if leaveMessage ( b [ 0 ], messages [ random . randint ( 0 , mes_count - 1 )]): print 'Message posted!' else: print 'An unexpected error occurred :(' else: if leaveMessage ( b [ 0 ], messages [ 0 ]): print 'Message posted!' else: print 'An unexpected error occurred :(' else: print 'There is no message. File could not be opened!' else: print 'There is no Birthday today :(' # log out as last step LogOut () print '\nYou have been logged out!' else: print 'Login failed!' print '\n--- END ---' Wenn ihr keine Lust habt euren Namen und das Passwort immer wieder selbst einzutragen, dann könnt ihr das ändern, in dem ihr folgendes anpasst: Vorher: PHP: print 'Please type in your E-Mail address:' , # anonyme version mail = raw_input () mail = mail . replace ( '\r' , '' ) # mail = 'wkwbot@rockstheplanet.com' # get password# anonyme version password = getpass . getpass ( 'Please type in your password: ' ) # password = '' Nachher: PHP: #print 'Please type in your E-Mail address:',# anonyme version#mail = raw_input()#mail = mail.replace('\r', '') mail = 'wkwbot@rockstheplanet.com' #<-- EURE E-Mail Adresse # get password# anonyme version# password = getpass.getpass('Please type in your password: ') password = 'geheim' #<-- EUER Passwort messages.txt Code: Hey %NAME%, ich wünsche dir alles Gute zum Geburtstag. Hoffe du feierst schön :) Gruß, <deinname>;; Wünsche dir alles Gute zum Geburtstag!;; Happy Birthday %NAME% :);; Auch von mir alles Gute!;; Oh, schon wieder ein Jahr älter. Lass es ordentlich krachen und feier schön. Gruß, <deinname>;; Herzlichen Glückwunsch zu deinem Geburtstag, %NAME% Gruß, <deinname> Hier müsst ihr <deinname> durch euren Namen ersetzen. %NAME% wird automatisch ausgefüllt. Ihr könnt die Liste der Geburtstagswünsche beliebig erweitern nur müssen einzelne Nachrichten durch ;;<newline> getrennt werden. Start-Batch: Code: python.exe wkw.py messages.txt 1 + Multi-Zitat Zitieren
#2 25. August 2010 AW: WKW Birthday AutoPoster Hi cable, Zunächst einmal vielen lieben Dank für das nützliche Skript. Ich habe mir das Skript gegoogelt, weil ich eigentlich selbst ein PHP-Skript für ähnliche Zwecke schreiben wollte. Leider funktioniert weder meins noch deins: ( Irgendwas scheinen die Admins bei wkw geändert zu haben, jedenfalls funktioniert die Methode mit dem auslesen des Hash/HashKey jetzt leider irgendwie nicht mehr. Hast Du eine Ahnung, woran das liegen könnte? Ich habe ja die Hoffnung, dass du dich in der Zwischenzeit noch etwas mehr mit werkenntwen auseinandergesetzt hast (ich hatte heute nur tagsüber Zeit, als ein paar Stunden - bin aber momentan etwas ratlos, weil ich nicht weiß, was ich denn nun falsch mache). Wenn jemand anderes eine Idee hat, ist diese natürlich auch immer willkommen Liebe Grüße und Danke im Voraus Chris + Multi-Zitat Zitieren
#3 25. August 2010 AW: WKW Birthday AutoPoster Hey, Ich habe gerade nochmal den Beitrag oben geändert, da da noch eine kleine Änderung vorgenommen werden musste. Ich sitze gerade im Urlaub und schaue nur zufällig hier vorbei. Am Freitag hatte es bei mir noch ohne Probleme funktioniert. Werde Samstag oder Sonntag wieder zu Hause sein und dann werde ich mich dem Problem noch mal annehmen. Nimm den Quellcode von oben nochmal und versuche dein Glück. Ansonsten musste du warten bis zu Wochenende und dann werde ich das hoffentlich fixxen können. greez + Multi-Zitat Zitieren
#4 25. August 2010 AW: WKW Birthday AutoPoster nope, hat leider nichts genutzt... Code: ####################################################### ########## Wer-Kennt-Wen Birthday Autoposter ########## ################### by cable © 2010 ################### ####################################################### Login was successful! You have 338 friends! Birthdays of today: Henning Annen: http://www.wer-kennt-wen.de/person/kchnkubv ... Want to send greetings? [y/n]: y Is Henning Annen the right name? [y/n]: y An unexpected error occurred :( You have been logged out! --- END --- Ich hab mal ein paar Print-Statements eingefügt, um zu schauen, was er macht. Also, die Seite des Freundes wird aufgerufen und dort auch wie gedacht das Formular zum absenden des Gästebuches gefunden, inklusive auslesen von _hash/_hashKey. Dann wird das Formular per Post-Request abgeschickt. Normalerweise wird man dann von wkw auf die Success-Seite weitergeleitet. Hier aber nicht. Stattdessen landet man unverrichteter Dinge wieder auf der Seite des Freundes. Ich hab keine Ahnung, was wir falsch machen. Naja, jetzt erstmal viel Spaß noch im Urlaub! Liebe Grüße Chris ups, Berichtigung: Irgendwie scheint es doch funktioniert zu haben, zumindest wurde etwas gepostet. Auch, wenn das Skript selber meldet, es hätte nicht funktioniert. Allerdings wird die Messages Datei nicht richtig gesplittet, so dass immer die komplette Datei gepostet wird. Das könnte aber auch an meinem Unix-System und dessen Zeilenumbrüchen liegen. Trotzdem irgendwie komisch, dass man nicht auf die Success-Seite weitergeleitet wird. Kennst du dich eventuell auch mit PHP aus, so dass ich dir mein Skript mal mailen könnte? Das funktioniert nämlich leider immer noch nicht und ich konnte nicht herausfinden, was da der Unterschied ist zwischen deinem und meinem Ansatz (konzeptionell gehe ich nämlich genauso vor: Personen-Seite laden, Parameter finden (_hash/_hashKey), Post-Request zusammenbauen und abschicken und dann sollte eigentlich die Success-Seite als location im response header auftauchen. Tut sie aber leider nicht. Naja, bei dir ja auch nicht, aber bei dir wird wenigstens die Nachricht trotzdem gepostet. Jedenfalls finde ich das Verhalten sehr merkwürdig. + Multi-Zitat Zitieren
#5 29. August 2010 AW: WKW Birthday AutoPoster Sooo, bin wieder aus dem Urlaub da und hatte den Fehler gefunden. Hatte ihn lokal schon lange gefixxt, aber hier nicht geupdatet, sorry. In der Funktion leaveMessage() musst du die Zeile so ändern: PHP: if content . find ( 'Dein Gästebucheintrag wurde gespeichert.' ) != - 1 : Habs gerade getestet und es funktioniert 1A. Für dein Problem mit dem splitten bei Unix Systemen solltest du diese Zeile in der Funktion readMessages() PHP: messages = content . split ( ';;\n' ) in PHP: messages = content . split ( ';;\r\n' ) ändern. greez + Multi-Zitat Zitieren