From bfe5e3549ff691a14e59ccbfdd3e3b0f281bb1f2 Mon Sep 17 00:00:00 2001 From: lars Date: Sun, 15 Jun 2008 23:47:44 +0000 Subject: [PATCH] change some settings for the demo environment add error checks improve mail generation (date, to, from, ...) --- fotokiste/fotokiste/controllers.py | 98 +++++++++++------- .../static/images/fotokiste-default.jpg | Bin 0 -> 4744 bytes 2 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 fotokiste/fotokiste/static/images/fotokiste-default.jpg diff --git a/fotokiste/fotokiste/controllers.py b/fotokiste/fotokiste/controllers.py index 56cb7fc..aa9de02 100644 --- a/fotokiste/fotokiste/controllers.py +++ b/fotokiste/fotokiste/controllers.py @@ -19,22 +19,34 @@ import re import datetime IMAGE_STORE = os.path.join(tempfile.gettempdir(), "fotokiste.jpg") -VIDEO_URL = "http://localhost:8081/?action=stream" -SNAPSHOT_URL = "http://localhost:8081/?action=snapshot" +VIDEO_URL = "http://krake:8081/?action=stream" +# Netzwerk-Problem beim xen-Switch ... - erstmal nur ein Standardbild +#SNAPSHOT_URL = "http://krake:8081/?action=snapshot" +SNAPSHOT_URL = "http://localhost:8080/static/images/fotokiste-default.jpg" ALLOWED_MAILADDRESS_CHARACTERS = "\w._%@-" ALLOWED_MAILTEXT_CHARACTERS = "\w@_\-\.\s\n\#\(\)\[\]\{\}\|\>\<\,\+/\'\"\?\!\:=%\$^&\*" +MAIL_ADDRESS_REGEX = r"^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+\.[a-zA-Z]{2,6}$" +# TODO: this path is relative - to be fixed! MAIL_SIGNATURE_FILE = "mail_signature.txt" -MAIL_FROM_ADDRESS = "fotokiste@glasmensch.org" +MAIL_FROM_ADDRESS = '"Fusion-Fotokiste" ' MAIL_SUBJECT = "Ein Foto von der Fusion!" -SMTP_HOST = "localhost" +MAIL_ATTACHMENT_FILENAME = "fusion.jpeg" +SMTP_HOST = "192.168.1.31" SMTP_PORT = "25" MAIL_MAX_LENGTH = 5000 +ERRORS_MAX_LENGTH = 25 +errors = [] DEFAULT_DICT = { "video_url": VIDEO_URL } def debug(message): - print "%s: %s" % (datetime.datetime.now().isoformat(), message) + log_msg = "%s: %s" % (datetime.datetime.now().isoformat(), message) + errors.append(log_msg) + # remove old messages, if necessary + while len(errors) > ERRORS_MAX_LENGTH: + del errors[0] + print log_msg def merged_dicts(dict_a, dict_b): return dict(dict_a.items() + dict_b.items()) @@ -50,51 +62,62 @@ def filter_mailtext(text): return filtered def check_mailaddress(address): - if re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+\.[a-zA-Z]{2,6}$", address): + if re.match(MAIL_ADDRESS_REGEX, address): return True else: return False def send_mail(address, text): import smtplib - import MimeWriter import StringIO - import base64 + import email.Generator + import email.MIMEMultipart + import email.MIMEText + import email.MIMEImage + import rfc822 # read the additional mail parts (signature and picture) try: signature = file(MAIL_SIGNATURE_FILE).read() except IOError, msg: debug("failed to open the signature file (%s): %s" % \ (MAIL_SIGNATURE_FILE, msg)) + return False try: - picture = StringIO.StringIO(file(IMAGE_STORE).read()) + picture = file(IMAGE_STORE).read() except IOError, msg: debug("failed to open the image file (%s): %s" % \ (IMAGE_STORE, msg)) + return False # prepare the message - message = StringIO.StringIO() - writer = MimeWriter.MimeWriter(message) - writer.addheader("Subject", MAIL_SUBJECT) - # the picture should be shown inline by the mail clients - writer.addheader("Content-Disposition", "inline") - writer.startmultipartbody('mixed') - # start off with a text/plain part - part = writer.nextpart() - body = part.startbody('text/plain') - body.write(text + signature) - # now add an attachment - part = writer.nextpart() - # the 'Content-Disposition' is necessary for displaying the image inline - part.addheader('Content-Disposition', 'attachment; filename="fusion.jpeg"') - part.addheader('Content-Transfer-Encoding', 'base64') - body = part.startbody('image/jpeg') - base64.encode(picture, body) - # finish off - writer.lastpart() + #mail_flat = StringIO.StringIO() + #mail_gen = email.Generator.Generator(mail_flat) + #mail_gen.flatten(body) + mail = email.MIMEMultipart.MIMEMultipart() + mail_text = email.MIMEText.MIMEText(text + signature) + mail_pict = email.MIMEImage.MIMEImage(picture, "jpeg") + mail_pict.add_header("Content-Disposition", + 'attachment; filename="%s"' % MAIL_ATTACHMENT_FILENAME) + mail.add_header("Subject", MAIL_SUBJECT) + mail.add_header("To", address) + mail.add_header("From", MAIL_FROM_ADDRESS) + mail.add_header("Date", rfc822.formatdate()) + mail.add_header("Content-Disposition", "inline") + mail.attach(mail_text) + mail.attach(mail_pict) + writer = StringIO.StringIO() + email.Generator.Generator(writer).flatten(mail) - con = smtplib.SMTP(SMTP_HOST, SMTP_PORT) - con.sendmail(address, MAIL_FROM_ADDRESS, message.getvalue()) + # send the mail + try: + con = smtplib.SMTP(SMTP_HOST, SMTP_PORT) + con.sendmail(address, MAIL_FROM_ADDRESS, writer.getvalue()) + con.quit() + except (smtplib.SMTPHeloError, smtplib.SMTPRecipientsRefused, + smtplib.SMTPSenderRefused, smtplib.SMTPDataError), msg: + debug("an error occoured while sending the mail: %s" % msg) + return False + return True class Root(controllers.RootController): @@ -102,8 +125,7 @@ class Root(controllers.RootController): @expose(template="fotokiste.templates.start") def index(self, **kargs): - # Bilder zufaellig aus der Datenbank auswaehlen - # eine andere Funktion muss die Bilder ausliefern + # TODO: this should generate a selection of random pictures gallery = [] for i in range(22): obj = DummyPicture() @@ -111,7 +133,7 @@ class Root(controllers.RootController): obj.url = "URL: %d" % i gallery.append(obj) - # alte Bild-Datei loeschen + # remove old picture if os.path.isfile(IMAGE_STORE): os.unlink(IMAGE_STORE) @@ -123,6 +145,7 @@ class Root(controllers.RootController): flash("Das Bild wird in 5 Sekunden aufgenommen!") return merged_dicts({}, DEFAULT_DICT) + @expose(template="fotokiste.templates.mailtext") def mailtext(self, mailaddress="", mailtext="", already_stored="no", **kargs): # store the picture if necessary @@ -141,6 +164,7 @@ class Root(controllers.RootController): "already_stored": already_stored, }, DEFAULT_DICT) + @expose(template="fotokiste.templates.senden") def senden(self, mailaddress="", mailtext="", senden=None): # filter input @@ -159,9 +183,11 @@ class Root(controllers.RootController): flash("Die Mailadresse scheint nicht ungueltig zu sein.") redirect("mailtext", return_dict) else: - # Mail versenden - send_mail(mailaddress, mailtext) - return return_dict + # send the mail + if send_mail(mailaddress, mailtext): + return return_dict + else: + redirect("error") @expose() def get_current_shot(self): diff --git a/fotokiste/fotokiste/static/images/fotokiste-default.jpg b/fotokiste/fotokiste/static/images/fotokiste-default.jpg new file mode 100644 index 0000000000000000000000000000000000000000..89dbd6d01094c85fe7cddc95a5eea7a79d2d75b5 GIT binary patch literal 4744 zcmbVPXIK+i+fG6PGAy{jATBJrDrG_zY!nrcvW!a41PD?DQB=BsKorH5tg#Fhqzi&! zAVEq15keDOVr4~_-VqUD5fK}pVBtIX?zh+X{`=l{u1u~Zb8?<`KllBdg`S14Bu##R z1^ErB>=NnUFDVj9Ne-i8R1#^SpLCK${`ZUW?JI>sAycF%Qc~Y;DJoS;3cRGKG%A%! z0~h!tO`}OKe*XLK;C~bvShD!^Kf8dhG~nXG?De@{3MUgC}NM5)@CP*am z-zNSy4B!~BF0(`yk|UF({_*}_kN?lZ?@1Ig@Sh4?qJm(_vEUhrsz_5>wcb)%8S|A{ z9S(1ZyOgtJjn(x=6;|sT&5e5^xU$eP)#X2^X=&>qbX@~OBjZh*xBOy_Zri@Y#@5-z zmF>3E-D9uczWoRM0|F04Mn!WDABp+xB=6MeGiUL{q~w&;wDijvL~foyn18LHu>3|v zrMRlPrdD$M&fRq!dZ!qy>`sJfb8XMoFI~IBiNq!O7$O5Ix7o z(T|IJ^A46_76IUv;Ig$IWkg)B0nBP0cX-9ew!O3*9I_xXrcQSt#2+7ILeeoOi&{%m z=MU}n^F5gT$&uVL%$4xikmMG=10kmSLhP93ygsW1(rJOlp{}cSep4p1O86t6Yp(|o zzAvhIarv+fKlyJF7yeAkGBAW{pC&};OW-sb}&id+;dBHd)Hc&VH@rDp| z(t6(y?~!Rp7jF<-qNFqn;zX~w2eX)tSx2NLh(R&Z12le_$6Wf8yqeSXymL@a;>aRc9F>d?gRzGO#9Lx8Z7T$3}fRuCH*{D-pmSz zAcRD4cU2uYsLc~BCEb3u+|)HdySQ(GG#m2z0nyEx4Wf_(`qauO*FWjOu{{`(bAiai-`6tld^G z!5zQIvKl6l+`^XVwq{VdF3F&K86nCWY}7x4p}?8=!1~um<0_sGf)CQ1s>He5Pe+j!#%#D#p!ncqm9p0s_?(+ zFFu2vje9?%!VT+!+*m^|*QA9)CF>L%50|QyUVZRpjt705+q+)3LdUf>sCdmol?Pum z^S-E=ex`=6OI_7nD7?~t@x$JIQ@6JNdJ`$-o77~q@?e#yqcpfZU{IM88x7GZsc|T| z830$&bbb2t`P9)5PW;+o6fzqG`+S_}XZ{i!Xw={GFmzv6!236JWKOZEW`(xsZv`Z)U z*{oh^fSy`@fV(c}L6D?r<9AgnP5mN1R@b`jlO6AFNcKF=aR};oSKjQcs`|673#H6$2zuIvelhM7qRt#(ZUT;6th9U6zqdRoSc z6Ij_ok%_@&cBtbs%%-A$pQqibZAW8TB21=7@D-BING1HzrWs#!Q=Q5A(nusvUL?V( zCBGeYRhA{wLb%CG*lCFzPXNP*((X;P|WRLxo_^!)lX@V#5AXgZEU*y+q zw&bzt=NF8IEH}Hk%b2sRqoC@={2WiECGZ1;&~gV5L6;??p+9|MiW*$-c+cxdL3HSN8=>kAF5OED#)9`cYN*G5)D^&YL0E zj3H)cWLOO?ApbkVeOfHjg&TxWRl1+QJB)bEGgiq=xu;yro@^_L{ij9i&6^tvLRVE3Ix z_v-=r+634nHM1JC^hI5Qv!2@>^n+be#$l$O6)rsuA??@9Dz;wynE7evvG9*~-|T&Q z|9A5<**`le9^3qpWVob3b>~1pf?n5e^26sI28XIxCs~^cdP*D{e;>i;Bn_UtYU7`t z{&Bd^)ZDK3zN)uyHBlGPS=e5n6`Pz zQMck$Er5a$X4>8gBTgLag6O^S!jb*(%}<}&%8(F)`NKon0@FtA_yhMc2V%%qq~X3@)pjG4thkGjBg9Gi~CpQ9U{}M#Wvtu z7ijm5L5Sx-sLdU(tG~aW$-NL0IbApw_~>HnNrJC@D*?(H}aB-TR2ZT%*C3?`{SAx3_1psUr zspp{=COZ+)njgeOoCs(c77@Ms)$$3reyM3&Y&_l`jufoi;KU?OM2mA!qp8GYmu{wG zJ2VnGK+6JXFbU`g7bhWn17DQdzkNT<)Bt)}X$d%G7D85lv?%+cTE~fqhDOx2ug69- z1v^({WvFplX>h6N_BJ?w^H_W^Gnpl~*#2rXcxelg8-CmuB`^N5t$s0PKY{0*SutjQu7xX zQOyXfd;Y2rqL;3Ztb^!59d-^}97OQt6$OVA#XKEh4ytaFI65^zchWKM$`)xVIC$CW z+5$x|0~-g!%q0l_AR0!*`PlK`?-0IQSK}_#laY1@l|B~T_SU%BSv)Q0aMZh^bt>x7 zcJl+RBNg$Kb*r-F+g}^a z)utCnipRFJeO>jUVci>p8u89jYPvXTpnun~`rn_Qa@+RWht@szRq^nt&(2SO)=~RY z%2ZvXdp)x77#3OhIO$dquRF=KIBnyFgDI?L*ZR>`ap{d40VY08G?jVxm&PFH`dttr zT?&9L4baY*(WtlqAr0Jk2-#!%YLKQ8Ac#&2yLe|3#vY2&UxkNfC$DH|ND0|SUq7y; zlFk6q0!An;AXp0XJXo30H;M2$vEO5keO@sGK!I{lYEw@}P<%Z1e7I?Qh5zbp8SFjy z7NqIvQrlC>dzUjTHE&idOK4+Q5ZSq7fKZrvfYISsz=_W5#$eckJ}5`@Ai@tdx@<5+ zbufP(I{xL+fkmJGI^@i{T#wy(Z_>3ORtGL zkUR*)DCgr2Ah?~6SsbA)7RrG!faHimwX+*h{ha-x-Nebno}!>IBJ0wYUVj)96!Ypq z(EEZ^x`t7G*P}_t&mj4cj?HwZzg$L_xn`AU!4)3V(*4M$T%FCY*`w6Qnmqtxg28eT>F1}H4Ws0C3nC6QvL_FwmGUvGI^_x2*`|sg3bVRqcd*^6 zvF(ft=L|TIZjGNTJs^xo^t?V@DM|Zb6Fk}HAn!40tGgIMW;wv$RS*DQC8-vomkjHu z2f~=|i!yA7+m632YE@J~i0TH%W+cCCuCxrZau`|_ZX8`!Z@_qgw2J;}w}Z?BCe%_S#qflS{1Sx^1`h;UM*E^pAUgg0{l;e)|~ zS|8g2Xax|{vcKmfz!w?8i*q)`7RWy^s9cTx(%R!V3(?IQ4R;gi+1G)u^RjxOu(MOH zMp_?4uN3vGVWYLGFRwmMe&@JZID`LU6PT!u?*GOP%F%#pUV_$|g5N&~1#sC|U=V)-S zjwZ}BH-ee^fcysZuYf=}o(Yw8d#;3^`_#rx4DZtt!Y=M&x^WOh)+AfL?0%b58fA0d z`-2jm2sY1!kXy`XP$2dVATdUD5V8`GyJV4L*Md$A<>F+2n8~OD7W*b)rkxj{#n+;H zLqG4twtet3D*@sZtU}ayUqghI9RHOJNH>?^m0!tC%{+L?I~RZ5^3;JT6QF6aV=&V#0kd3tAdJWyNF4;yX75qN zQ?W57C5!?HMiDP`=}I@_;AKS)vWI_k*(wNTWenB~Y#%K}P`?)f@n< zfkuEBKqG5P7LtQ()81B#;&xaDqBv^JExZF92<=#)B2QA$nD~ z7SJA+Oc`d+KB^6~Zdq=M2J^cJtQV;B!HF_r0%j@zx<)H%GUCDErm%}9^OmL(V?ZoR z0pa=tN@hd5t1*`j7d^c{o~L9~V>>fKLH9_vfuOuv!5haCB}Zm)amqNtS1-f1r*}1? zl-hbw(`GSP*O?;0MIM;^+G>oYgFI;j1AC<}y0w-Y9gO5Uat~Rep5f&-%0E~mL=&SY zJe*^PV3~>SqFyxJbgv^#IVS?I7TQesDCa0vRm= zbSt+AT0=0=9|Z+e6T{AqeZM&fVV0JMK4?3TVjni_ylN