20120726¶
Cannot re-execute Tx25-Anfrage #9 with non-empty ticket¶
Alicia hatte auf einer bereits ausgeführten Tx25 (die mit disable_editing komplett schreibgeschützt ist) auf “Speichern” geklickt. Sie bekam dann “AJAX communication failed” als Antwort, und der Server machte einen Traceback “Cannot re-execute Tx25-Anfrage #9 with non-empty ticket.”.
Der Fehler war, dass der Speichern-Button
trotz disable_editing aktiv war. Das lag an einem Bug in
lino.core.actors.Actor.disabled_actions()
: die rief
a.get_action_permission(ar.get_user(),obj,state) statt
obj.get_row_permission(u,state,a). Behoben.
Aber dann fiel mir auf: dadurch wurden nicht nur die Buttons “Speichern” und “Löschen” disabled, sondern auch “Neu”. Das war logisch aber falsch: logisch, weil InsertRow.readonly False war und Tx25.get_row_permission folglich Veto erhebt, falsch weil man hier ja doch auf “Neu” klicken können soll. Die Bedeutung von Action.readonly muss sein: ob diese Aktion im gegebenen Objekt etwas ändert. So gesehen ist InsertRow keine verändernde Aktion.
Also: InsertRow hat ab jetzt readonly=True, und damit readonly-Benutzer jetzt nicht plötzlich einfügen können, überschreiben wir ihre get_action_permission:
def get_action_permission(self,user,obj,state):
if user.profile.readonly:
return False
return super(InsertRow,self).get_action_permission(oser,obj,state)
Forced update did not affect any rows¶
Ein anderer Traceback auf dem Server gestern war “Forced update did not affect any rows”. Der kommt, wenn man auf einem JobProvider “Speichern” klickt, obwohl man gar nichts verändert hat. Kommt nur mit MySQL (nicht mit SQLite). Kommt nur auf einer MTI-Tabelle.
Um das zu verhindern, mache ich in form2obj_and_save
jetzt einen Test ähnlich wie
lino.utils.dblogger.DiffingMixin
,
und wenn sich nichts verändert hat,
kommt jetzt “%s : nothing to save.”,
und before_ui_save und full_clean werden dann auch gar
nicht erst aufgerufen.
Das gilt bei allen Records, nicht nur in MTI-Tabellen.
Konvention #270 : Aufgabenbereich wird nicht gedruckt¶
Hier der Text, der in Contract.responsibilities steht:
<p><span style="font-family: Verdana;">Arbeitszeiten:</span></p>
<p><span style="font-family: Verdana;">Montag-Dienstag von 11:00-18:30 (1Stunde Mittagspause)</span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;">Mittwoch: frei</span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;">Donnerstag: 12:00-19:30 (1 Stunde Mittagspause)</span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;">Freitag: 13:00-20:30 (1 Stunde Mittagspause)</span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;">Samstag: 8:00-14:30 (1/2 Stunde Mittagspause)</span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;">Sonntag: frei </span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;"><!--[if !supportEmptyParas]--> <!--[endif]--></span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black;">Aufgabenbereiche: </span></p>
<p><span style="font-family: Verdana; font-size: 7.5pt;">* Truck wash (lavage des camions)</span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black; mso-ansi-language: FR;"><span style="font-size: 7.5pt; font-family: Verdana; color: black; mso-ansi-language: FR;" lang="FR">* Aide au niveau du garage (réparation de planchers de camions, éclairage de remorques, remplacement de pièces de carrosserie,...)</span></span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black; mso-ansi-language: FR;"><span style="font-size: 7.5pt; font-family: Verdana; color: black; mso-ansi-language: FR;" lang="FR">* Entretien des abords (plantations, tonde des herbes et des hailles,...)</span></span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; color: black; mso-ansi-language: FR;"><span style="font-size: 7.5pt; font-family: Verdana; color: black; mso-ansi-language: FR;" lang="FR">* Service bâtiments (Petits travaux électriques, maintenance,...)</span></span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"; color: black; mso-ansi-language: FR; mso-fareast-language: DE; mso-bidi-language: AR-SA;" lang="FR"><span style="font-size: 7.5pt; font-family: Verdana; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"; color: black; mso-ansi-language: FR; mso-fareast-language: DE; mso-bidi-language: AR-SA;">* Nettoyage et rangement dans l'entrepôt.</span></span></p>
<p><span style="font-size: 7.5pt; font-family: Verdana; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"; color: black; mso-ansi-language: FR; mso-fareast-language: DE; mso-bidi-language: AR-SA;" lang="FR"><span style="font-size: 7.5pt; font-family: Verdana; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"; color: black; mso-ansi-language: FR; mso-fareast-language: DE; mso-bidi-language: AR-SA;"><br /></span></span></p>
Hier die Fehlermeldung im Dokument (nur sichtbar, nachdem ich Druckmethode von AppyPdf nach AppyOdt umgeschaltet habe):
Error while evaluating the expression "html(self.responsibilities)" defined in the "from" part of a statement.
File "<string>", line 1, in <module>
File "/var/snapshots/lino/lino/utils/appy_pod.py", line 189, in html_func
return self.renderXhtml(html,**kw)
File "/var/snapshots/appy-current/appy/pod/renderer.py", line 242, in renderXhtml
stylesMapping, ns).run()
File "/var/snapshots/appy-current/appy/pod/xhtml2odt.py", line 497, in run
self.xhtmlParser.parse(self.xhtmlString)
File "/var/snapshots/appy-current/appy/shared/xml_parser.py", line 193, in parse
self.parser.parse(inputSource)
File "/usr/lib/python2.6/xml/sax/expatreader.py", line 107, in parse
xmlreader.IncrementalParser.parse(self, source)
File "/usr/lib/python2.6/xml/sax/xmlreader.py", line 123, in parse
self.feed(buffer)
File "/usr/lib/python2.6/xml/sax/expatreader.py", line 211, in feed
self._err_handler.fatalError(exc)
File "/usr/lib/python2.6/xml/sax/handler.py", line 38, in fatalError
raise exception
<class 'xml.sax._exceptions.SAXParseException'>: <unknown>:14:82: not well-formed (invalid token)
12 Uhr : Ich vermute, dass es an den Gänsefüßchen in family: "Times New Roman"
liegt:
----------------------------------------------------------------------------------
<p><span style="font-size: 7.5pt; font-family: Verdana; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family
: "Times New Roman"; color: black; mso-ansi-language: FR; mso-fareast-language: DE; mso-bidi-language: AR-SA;" lang="FR"
><span style="font-size: 7.5pt; font-family: Verdana; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family:
"Times New Roman"; color: black; mso-ansi-language: FR; mso-fareast-language: DE; mso-bidi-language: AR-SA;">* Nettoyage
et rangement dans l'entrepôt.</span></span></p>
13.10 Uhr : Da! Ich habs!
Mein Modul lino.utils.html2xhtml
produzierte ungültigen XHTML,
wenn im HTML Attribute mit Gänsefüßen waren:
def attrs2xml(attrs):
return ' '.join(['%s="%s"' % a for a in attrs])
So ist es besser:
from xml.sax.saxutils import quoteattr
def attrs2xml(attrs):
return ' '.join(['%s=%s' % (k,quoteattr(v)) for k,v in attrs])
Im Docstring des Moduls mach ich jetzt auch einen test case dafür:
>>> html = '''\
... <p style="font-family: "Verdana";">Verdana</p>'''
>>> print repr(html2xhtml(html))
u'<p style=\'font-family: "Verdana";\'>Verdana</p>'