diff --git a/modules/mailinator/__init__.py b/modules/mailinator/__init__.py
new file mode 100644
index 00000000..1c40f994
--- /dev/null
+++ b/modules/mailinator/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Vincent A
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from .backend import MailinatorBackend
+
+
+__all__ = ['MailinatorBackend']
diff --git a/modules/mailinator/backend.py b/modules/mailinator/backend.py
new file mode 100644
index 00000000..09f93970
--- /dev/null
+++ b/modules/mailinator/backend.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Vincent A
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.tools.backend import BaseBackend, BackendConfig
+from weboob.capabilities.messages import ICapMessages, Thread, Message
+from weboob.tools.value import Value
+
+from .browser import MailinatorBrowser
+
+
+__all__ = ['MailinatorBackend']
+
+
+# There is only one thread per inbox, and the thread id is the inbox name
+# TODO but this can lead to bans if there are too many messages...
+class MailinatorBackend(BaseBackend, ICapMessages):
+ NAME = 'mailinator'
+ DESCRIPTION = u'mailinator temp mailbox'
+ MAINTAINER = u'Vincent A'
+ EMAIL = 'dev@indigo.re'
+ LICENSE = 'AGPLv3+'
+ VERSION = '0.i'
+
+ BROWSER = MailinatorBrowser
+
+ CONFIG = BackendConfig(Value('inbox', label='Inbox', default=''))
+
+ def iter_threads(self):
+ inbox = self.config['inbox'].get()
+ if not inbox:
+ raise NotImplementedError()
+ else:
+ return [self.get_thread(inbox)]
+
+ def get_thread(self, _id):
+ t = Thread(_id)
+ t.title = 'Mail for %s' % _id
+ t.flags = t.IS_DISCUSSION
+
+ first = True
+ for d in self.browser.get_mails(_id):
+ m = self.make_message(d, t)
+ if not m.content:
+ m.content = self.browser.get_mail_content(m.id)
+
+ if first:
+ first = False
+ t.root = m
+ else:
+ m.parent = t.root
+ m.parent.children.append(m)
+
+ return t
+
+ def make_message(self, d, thread):
+ m = Message(thread, d['id'])
+ m.children = []
+ m.sender = d['from']
+ m.flags = 0
+ if not d.get('read', True):
+ m.flags = m.IS_UNREAD
+ m.title = d['subject']
+ m.date = d['datetime']
+ m.receivers = [d['to']]
+ return m
diff --git a/modules/mailinator/browser.py b/modules/mailinator/browser.py
new file mode 100644
index 00000000..97429f36
--- /dev/null
+++ b/modules/mailinator/browser.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Vincent A
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.tools.browser import BaseBrowser, BrowserBanned
+from weboob.tools.date import datetime
+from weboob.tools.parsers.jsonparser import json
+import lxml.html
+import time
+
+
+__all__ = ['MailinatorBrowser']
+
+
+class MailinatorBrowser(BaseBrowser):
+ PROTOCOL = 'http'
+ DOMAIN = 'mailinator.com'
+ ENCODING = 'utf-8'
+
+ def __init__(self, *args, **kw):
+ kw['parser'] = 'raw'
+ BaseBrowser.__init__(self, *args, **kw)
+
+ def _get_unicode(self, url):
+ return self.get_document(self.openurl(url)).decode(self.ENCODING, 'replace')
+
+ def _get_json(self, url):
+ j = json.loads(self._get_unicode(url))
+ if 'rate' in j:
+ # shit, we've been banned...
+ raise BrowserBanned('Flood - Banned for today')
+ return j
+
+ def get_mails(self, boxid, after=None):
+ box = self._get_json('http://mailinator.com/useit?box=%s&time=%s' % (boxid, millis()))
+ address = box['address']
+
+ mails = self._get_json('http://mailinator.com/grab?inbox=%s&address=%s' % (boxid, address))
+ for mail in mails['maildir']:
+ d = {'id': mail['id'], 'from': mail['fromfull'], 'to': mail['to'], 'from_name': mail['from'], 'datetime': frommillis(mail['time']), 'subject': mail['subject'], 'read': mail['been_read'], 'box': (boxid, address)}
+ yield d
+
+ def get_mail_content(self, mailid):
+ frame = self._get_unicode('http://mailinator.com/rendermail.jsp?msgid=%s&time=%s' % (mailid, millis())).strip()
+ if not len(frame):
+ # likely we're banned
+ return ''
+ doc = lxml.html.fromstring(frame)
+ divs = doc.cssselect('.mailview')
+ return divs[0].text_content().strip()
+
+def millis():
+ return int(time.time() * 1000)
+
+def frommillis(millis):
+ return datetime.fromtimestamp(millis / 1000)
diff --git a/modules/mailinator/favicon.png b/modules/mailinator/favicon.png
new file mode 100644
index 00000000..f143c391
Binary files /dev/null and b/modules/mailinator/favicon.png differ
diff --git a/modules/mailinator/test.py b/modules/mailinator/test.py
new file mode 100644
index 00000000..a8c2079a
--- /dev/null
+++ b/modules/mailinator/test.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Vincent A
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.tools.test import BackendTest
+
+
+class MailinatorTest(BackendTest):
+ BACKEND = 'mailinator'
+
+ def test_mailinator(self):
+ t = self.backend.get_thread('qwerty')
+ assert t
+ assert t.root
+ assert t.root.title
+ assert t.root.date
+ assert t.root.sender
+ assert t.root.receivers
+