1 from Plugins.Plugin import PluginDescriptor
2 from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigText, ConfigSelection, ConfigYesNo,ConfigText
3 from Components.ConfigList import ConfigListScreen
4 from Components.ActionMap import ActionMap
5 from Components.Label import Label
6 from Components.Pixmap import Pixmap
7 from Screens.Screen import Screen
8 from Screens.VirtualKeyBoard import VirtualKeyBoard
9 from Screens.ChoiceBox import ChoiceBox
10 from Screens.MessageBox import MessageBox
11 from enigma import ePoint
14 from twisted.mail import smtp, relaymanager
15 import MimeWriter, mimetools, StringIO
17 config.plugins.crashlogautosubmit = ConfigSubsection()
18 config.plugins.crashlogautosubmit.sendmail = ConfigSelection(default = "send", choices = [
19 ("send", _("Always ask before sending")), ("send_always", _("Don't ask, just send")), ("send_never", _("Disable crashlog reporting"))])
20 config.plugins.crashlogautosubmit.sendlog = ConfigSelection(default = "rename", choices = [
21 ("delete", _("Delete crashlogs")), ("rename", _("Rename crashlogs"))])
22 config.plugins.crashlogautosubmit.attachemail = ConfigYesNo(default = False)
23 config.plugins.crashlogautosubmit.email = ConfigText(default = "myemail@home.com", fixed_size = False)
24 config.plugins.crashlogautosubmit.name = ConfigText(default = "Dreambox User", fixed_size = False)
27 class CrashlogAutoSubmitConfiguration(Screen, ConfigListScreen):
29 oldMailEntryValue = config.plugins.crashlogautosubmit.sendmail.value
32 <screen name="CrashlogAutoSubmitConfiguration" position="80,80" size="560,400" title="CrashlogAutoSubmit settings..." >
33 <widget name="config" zPosition="2" position="5,5" size="550,360" scrollbarMode="showOnDemand" transparent="1" />
34 <ePixmap pixmap="skin_default/div-h.png" position="0,300" zPosition="10" size="560,2" transparent="1" alphatest="on" />
35 <widget name="status" position="10,300" zPosition="10" size="540,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
36 <ePixmap pixmap="skin_default/buttons/red.png" position="0,360" zPosition="2" size="140,40" transparent="1" alphatest="on" />
37 <widget name="closetext" position="0,360" zPosition="10" size="140,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
38 <ePixmap pixmap="skin_default/buttons/green.png" position="140,360" zPosition="2" size="140,40" transparent="1" alphatest="on" />
39 <widget name="installtext" position="140,360" zPosition="10" size="140,40" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
40 <widget name="VKeyButton" pixmap="skin_default/buttons/button_yellow.png" position="285,370" zPosition="2" size="15,16" transparent="1" alphatest="on" />
41 <widget name="VKeyIcon" pixmap="skin_default/vkey_icon.png" position="300,355" zPosition="10" size="60,48" transparent="1" alphatest="on" />
42 <widget name="HelpWindow" position="175,250" zPosition="1" size="1,1" transparent="1" />
45 def __init__(self, session):
46 Screen.__init__(self, session)
47 self.session = session
50 self.addEmailEntry = None
51 self.EmailEntry = None
53 self.msgCrashlogMailer = False
55 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions" ],
58 "cancel": self.keyCancel,
59 "red": self.keyCancel,
60 "green": self.keySave,
63 self["VirtualKB"] = ActionMap(["ColorActions" ],
65 "yellow": self.KeyYellow,
69 ConfigListScreen.__init__(self, self.list,session = self.session)
72 self["VKeyButton"] = Pixmap()
73 self["VKeyIcon"] = Pixmap()
74 self["closetext"] = Label(_("Close"))
75 self["installtext"] = Label(_("Save"))
76 self["HelpWindow"] = Label()
77 self["status"] = Label()
79 self["VKeyButton"].hide()
80 self["VKeyIcon"].hide()
81 self["VirtualKB"].setEnabled(False)
82 self.onShown.append(self.setWindowTitle)
83 self.onClose.append(self.msgCrashlogNotifier)
86 def setWindowTitle(self):
87 self.setTitle(_("CrashlogAutoSubmit settings..."))
90 ConfigListScreen.keyLeft(self)
94 ConfigListScreen.keyRight(self)
98 if self["config"].getCurrent() == self.EmailEntry:
99 self.session.openWithCallback(self.EmailCallback, VirtualKeyBoard, title = (_("Please enter your email address here:")), text = config.plugins.crashlogautosubmit.email.value)
100 if self["config"].getCurrent() == self.NameEntry:
101 self.session.openWithCallback(self.NameCallback, VirtualKeyBoard, title = (_("Please enter your name here (optional):")), text = config.plugins.crashlogautosubmit.name.value)
103 def EmailCallback(self, callback = None):
104 if callback is not None and len(callback):
105 config.plugins.crashlogautosubmit.email.setValue(callback)
106 self["config"].invalidate(self.EmailEntry)
108 def NameCallback(self, callback = None):
109 if callback is not None and len(callback):
110 config.plugins.crashlogautosubmit.name.setValue(callback)
111 self["config"].invalidate(self.NameEntry)
113 def createSetup(self):
115 self.MailEntry = getConfigListEntry(_("How to handle found crashlogs?"), config.plugins.crashlogautosubmit.sendmail)
116 self.LogEntry = getConfigListEntry(_("What to do with submitted crashlogs?"), config.plugins.crashlogautosubmit.sendlog)
117 self.addEmailEntry = getConfigListEntry(_("Include your email and name (optional) in the mail?"), config.plugins.crashlogautosubmit.attachemail)
118 self.EmailEntry = getConfigListEntry(_("Your email address:"), config.plugins.crashlogautosubmit.email)
119 self.NameEntry = getConfigListEntry(_("Your name (optional):"), config.plugins.crashlogautosubmit.name)
120 self.list.append( self.MailEntry )
121 if config.plugins.crashlogautosubmit.sendmail.value is not "send_never":
122 self.list.append( self.LogEntry )
123 self.list.append( self.addEmailEntry )
124 if config.plugins.crashlogautosubmit.attachemail.value is True:
125 self.list.append( self.EmailEntry )
126 self.list.append( self.NameEntry )
128 self["config"].list = self.list
129 self["config"].l.setList(self.list)
130 if not self.selectionChanged in self["config"].onSelectionChanged:
131 self["config"].onSelectionChanged.append(self.selectionChanged)
133 if not self.sendmailChanged in config.plugins.crashlogautosubmit.sendmail.notifiers:
134 config.plugins.crashlogautosubmit.sendmail.notifiers.append(self.sendmailChanged)
136 def sendmailChanged(self, configElement):
137 if configElement.value != CrashlogAutoSubmitConfiguration.oldMailEntryValue:
138 self.msgCrashlogMailer = True
140 self.msgCrashlogMailer = False
143 if self["config"].getCurrent() == self.MailEntry:
145 if self["config"].getCurrent() == self.addEmailEntry:
148 def selectionChanged(self):
149 current = self["config"].getCurrent()
150 if current == self.MailEntry:
151 self["status"].setText(_("Decide what should be done when crashlogs are found."))
152 self.disableVKeyIcon()
153 elif current == self.LogEntry:
154 self["status"].setText(_("Decide what should happen to the crashlogs after submission."))
155 self.disableVKeyIcon()
156 elif current == self.addEmailEntry:
157 self["status"].setText(_("Do you want to submit your email address and name so that we can contact you if needed?"))
158 self.disableVKeyIcon()
159 elif current == self.EmailEntry:
160 self["status"].setText(_("Enter your email address so that we can contact you if needed."))
161 self.enableVKeyIcon()
163 elif current == self.NameEntry:
164 self["status"].setText(_("Optionally enter your name if you want to."))
165 self.enableVKeyIcon()
168 def enableVKeyIcon(self):
169 self["VKeyButton"].show()
170 self["VKeyIcon"].show()
171 self["VirtualKB"].setEnabled(True)
173 def showKeypad(self):
174 current = self["config"].getCurrent()
175 helpwindowpos = self["HelpWindow"].getPosition()
176 if hasattr(current[1], 'help_window'):
177 if current[1].help_window.instance is not None:
178 current[1].help_window.instance.show()
179 current[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1]))
181 def disableVKeyIcon(self):
182 self["VKeyButton"].hide()
183 self["VKeyIcon"].hide()
184 self["VirtualKB"].setEnabled(False)
186 def hideKeypad(self):
187 current = self["config"].getCurrent()
188 if hasattr(current[1], 'help_window'):
189 if current[1].help_window.instance is not None:
190 current[1].help_window.instance.hide()
192 def cancelConfirm(self, result):
196 for x in self["config"].list:
202 if self["config"].isChanged():
204 self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
210 CrashlogAutoSubmitConfiguration.oldMailEntryValue = config.plugins.crashlogautosubmit.sendmail.value
211 ConfigListScreen.keySave(self)
213 def msgCrashlogNotifier(self):
214 if self.msgCrashlogMailer is True:
216 callCrashMailer(True, self.session)
217 except AttributeError:
218 print "error, not restarting crashlogmailer"
221 def mxServerFound(mxServer,session):
222 print "[CrashlogAutoSubmit] - mxServerFound -->", mxServer
223 crashLogFilelist = []
224 message = StringIO.StringIO()
225 writer = MimeWriter.MimeWriter(message)
226 mailFrom = "enigma2@crashlog.dream-multimedia-tv.de"
227 mailTo = "enigma2@crashlog.dream-multimedia-tv.de"
228 subject = "Automatically generated crashlogmail"
229 # Define the main body headers.
230 writer.addheader('To', "dream-multimedia-crashlogs <enigma2@crashlog.dream-multimedia-tv.de>")
231 writer.addheader('From', "CrashlogAutoSubmitter <enigma2@crashlog.dream-multimedia-tv.de>")
232 writer.addheader('Subject', str(subject))
233 writer.addheader('Date', smtp.rfc822date())
234 if config.plugins.crashlogautosubmit.attachemail.value is True:
235 if str(config.plugins.crashlogautosubmit.email.value) != "myemail@home.com":
236 writer.addheader('Reply-To', str(str(config.plugins.crashlogautosubmit.email.value)))
237 writer.addheader('MIME-Version', '1.0')
238 writer.startmultipartbody('mixed')
239 # start with a text/plain part
240 part = writer.nextpart()
241 body = part.startbody('text/plain')
243 # Define the message body
244 body_text1 = "\nHello\n\nHere are some crashlogs i found for you.\n"
245 if str(config.plugins.crashlogautosubmit.email.value) == "myemail@home.com":
248 user_email = "\nUser supplied email address: " + str(config.plugins.crashlogautosubmit.email.value)
249 if str(config.plugins.crashlogautosubmit.name.value) == "Dreambox User":
252 user_name = "\n\nOptional supplied name: " + str(config.plugins.crashlogautosubmit.name.value)
253 body_text2 = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n"
254 body_text = body_text1 + user_email + user_name + body_text2
255 body.write(body_text)
259 (_("Yes, and don't ask again"), "send_always"),
260 (_("No, not now"), "send_not"),
261 (_("No, send them never"), "send_never")
264 def handleError(error):
265 print "[CrashlogAutoSubmit] - Message send Error -->", error.getErrorMessage()
267 def handleSuccess(result):
268 print "[CrashlogAutoSubmit] - Message sent successfully -->",result
269 if len(crashLogFilelist):
270 for crashlog in crashLogFilelist:
271 if config.plugins.crashlogautosubmit.sendlog.value == "delete":
273 elif config.plugins.crashlogautosubmit.sendlog.value == "rename":
274 currfilename = str(os.path.basename(crashlog))
275 newfilename = "/media/hdd/" + currfilename + ".sent"
276 os.rename(crashlog,newfilename)
279 print "[CrashlogAutoSubmit] - send_mail"
280 if len(crashLogFilelist):
281 for crashlog in crashLogFilelist:
282 filename = str(os.path.basename(crashlog))
283 subpart = writer.nextpart()
284 subpart.addheader("Content-Transfer-Encoding", 'base64')
285 subpart.addheader("Content-Disposition",'attachment; filename="%s"' % filename)
286 subpart.addheader('Content-Description', 'Enigma2 crashlog')
287 body = subpart.startbody("%s; name=%s" % ('application/octet-stream', filename))
288 mimetools.encode(open(crashlog, 'rb'), body, 'base64')
290 sending = smtp.sendmail(str(mxServer), mailFrom, mailTo, message.getvalue())
291 sending.addCallback(handleSuccess).addErrback(handleError)
293 def handleAnswer(answer):
294 answer = answer and answer[1]
295 print "[CrashlogAutoSubmit] - handleAnswer --> ",answer
298 elif answer == "send_always":
299 config.plugins.crashlogautosubmit.sendmail.value = "send_always"
300 config.plugins.crashlogautosubmit.sendmail.save()
301 config.plugins.crashlogautosubmit.save()
302 config.plugins.save()
305 elif answer in ( None, "send_never"):
306 config.plugins.crashlogautosubmit.sendmail.value = "send_never"
307 config.plugins.crashlogautosubmit.sendmail.save()
308 config.plugins.crashlogautosubmit.save()
309 config.plugins.save()
311 elif answer == "send_not":
312 print "[CrashlogAutoSubmit] - not sending crashlogs for this time."
314 for crashlog in os.listdir('/media/hdd'):
315 if crashlog.startswith("enigma2_crash_") and crashlog.endswith(".log"):
316 print "[CrashlogAutoSubmit] - found crashlog: ",os.path.basename(crashlog)
317 crashLogFilelist.append('/media/hdd/' + crashlog)
319 if len(crashLogFilelist):
320 if config.plugins.crashlogautosubmit.sendmail.value == "send":
321 session.openWithCallback(handleAnswer, ChoiceBox, title=_("Crashlogs found!\nSend them to Dream Multimedia ?"), list = list)
322 elif config.plugins.crashlogautosubmit.sendmail.value == "send_always":
325 print "[CrashlogAutoSubmit] - no crashlogs found."
328 def getMailExchange(host):
329 print "[CrashlogAutoSubmit] - getMailExchange"
330 return relaymanager.MXCalculator().getMX(host).addCallback(_gotMXRecord)
332 def _gotMXRecord(mxRecord):
333 return str(mxRecord.name)
336 def startMailer(session):
337 if config.plugins.crashlogautosubmit.sendmail.value == "send_never":
338 print "[CrashlogAutoSubmit] - not starting CrashlogAutoSubmit"
341 def gotMXServer(mxServer):
342 print "[CrashlogAutoSubmit] gotMXServer: ",mxServer
343 mxServerFound(mxServer,session)
345 def handleMXError(error):
346 print "[CrashlogAutoSubmit] - MX resolve ERROR:", error.getErrorMessage()
348 if not config.misc.firstrun.value:
349 getMailExchange('crashlog.dream-multimedia-tv.de').addCallback(gotMXServer).addErrback(handleMXError)
352 def callCrashMailer(result,session):
354 print "[CrashlogAutoSubmit] - config changed"
357 print "[CrashlogAutoSubmit] - config not changed"
360 def autostart(reason, **kwargs):
361 print "[CrashlogAutoSubmit] - autostart"
362 if "session" in kwargs:
364 startMailer(kwargs["session"])
365 except ImportError, e:
366 print "[CrashlogAutoSubmit] Twisted-mail not available, not starting CrashlogAutoSubmitter", e
369 def openconfig(session, **kwargs):
370 session.open(CrashlogAutoSubmitConfiguration)
373 def selSetup(menuid, **kwargs):
374 if menuid != "system":
377 return [(_("Crashlog settings") + "...", openconfig, "crashlog_config", 70)]
380 def Plugins(**kwargs):
381 return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart),
382 PluginDescriptor(name=_("CrashlogAutoSubmit"), description=_("CrashlogAutoSubmit settings"),where=PluginDescriptor.WHERE_MENU, fnc=selSetup)]