/modules/phpbb/module.py
Python | 196 lines | 171 code | 8 blank | 17 comment | 1 complexity | 46dfd797a2d236daea0743d06fd16638 MD5 | raw file
- # -*- coding: utf-8 -*-
- # Copyright(C) 2010-2011 Romain Bignon
- #
- # 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 <http://www.gnu.org/licenses/>.
- from weboob.tools.backend import Module, BackendConfig
- from weboob.tools.newsfeed import Newsfeed
- from weboob.tools.value import Value, ValueInt, ValueBackendPassword
- from weboob.tools.misc import limit
- from weboob.capabilities.messages import CapMessages, CapMessagesPost, Message, Thread, CantSendMessage
- from .browser import PhpBB
- from .tools import rssid, url2id, id2url, id2topic
- __all__ = ['PhpBBModule']
- class PhpBBModule(Module, CapMessages, CapMessagesPost):
- NAME = 'phpbb'
- MAINTAINER = u'Romain Bignon'
- EMAIL = 'romain@weboob.org'
- VERSION = '1.3'
- LICENSE = 'AGPLv3+'
- DESCRIPTION = "phpBB forum"
- CONFIG = BackendConfig(Value('url', label='URL of forum', regexp='https?://.*'),
- Value('username', label='Username', default=''),
- ValueBackendPassword('password', label='Password', default=''),
- ValueInt('thread_unread_messages', label='Limit number of unread messages to retrieve for a thread', default=500)
- )
- STORAGE = {'seen': {}}
- BROWSER = PhpBB
- def create_default_browser(self):
- username = self.config['username'].get()
- if len(username) > 0:
- password = self.config['password'].get()
- else:
- password = None
- return self.create_browser(self.config['url'].get(),
- username, password)
- #### CapMessages ##############################################
- def _iter_threads(self, root_link=None):
- with self.browser:
- links = list(self.browser.iter_links(root_link.url if root_link else None))
- for link in links:
- if link.type == link.FORUM:
- link.title = '%s[%s]' % (root_link.title if root_link else '', link.title)
- for thread in self._iter_threads(link):
- yield thread
- if link.type == link.TOPIC:
- thread = Thread(url2id(link.url))
- thread.title = ('%s ' % root_link.title if root_link else '') + link.title
- thread.date = link.date
- thread.flags = thread.IS_DISCUSSION
- yield thread
- def iter_threads(self):
- return self._iter_threads()
- def get_thread(self, id):
- thread = None
- parent = None
- if isinstance(id, Thread):
- thread = id
- id = thread.id
- thread_id = url2id(id, nopost=True) or id
- try:
- last_seen_id = self.storage.get('seen', default={})[id2topic(thread_id)]
- except KeyError:
- last_seen_id = 0
- with self.browser:
- for post in self.browser.iter_posts(id):
- if not thread:
- thread = Thread(thread_id)
- thread.title = post.title
- m = self._post2message(thread, post)
- m.parent = parent
- if last_seen_id < post.id:
- m.flags |= Message.IS_UNREAD
- if parent:
- parent.children = [m]
- else:
- thread.root = m
- parent = m
- return thread
- def _post2message(self, thread, post):
- signature = post.signature
- if signature:
- signature += '<br />'
- signature += 'URL: %s' % self.browser.absurl(id2url('%s.%s' % (thread.id, post.id)))
- return Message(thread=thread,
- id=post.id,
- title=post.title,
- sender=post.author,
- receivers=None,
- date=post.date,
- parent=None,
- content=post.content,
- signature=signature,
- children=[],
- flags=Message.IS_HTML)
- def iter_unread_messages(self):
- with self.browser:
- url = self.browser.get_root_feed_url()
- for article in Newsfeed(url, rssid).iter_entries():
- id = url2id(article.link)
- thread = None
- try:
- last_seen_id = self.storage.get('seen', default={})[id2topic(id)]
- except KeyError:
- last_seen_id = 0
- child = None
- iterator = self.browser.riter_posts(id, last_seen_id)
- if self.config['thread_unread_messages'].get() > 0:
- iterator = limit(iterator, self.config['thread_unread_messages'].get())
- for post in iterator:
- if not thread:
- thread = Thread('%s.%s' % (post.forum_id, post.topic_id))
- message = self._post2message(thread, post)
- if child:
- message.children.append(child)
- child.parent = message
- if post.parent:
- message.parent = Message(thread=thread,
- id=post.parent)
- else:
- thread.root = message
- yield message
- def set_message_read(self, message):
- try:
- last_seen_id = self.storage.get('seen', default={})[id2topic(message.thread.id)]
- except KeyError:
- last_seen_id = 0
- if message.id > last_seen_id:
- self.storage.set('seen', id2topic(message.thread.id), message.id)
- self.storage.save()
- def fill_thread(self, thread, fields):
- return self.get_thread(thread)
- #### CapMessagesReply #########################################
- def post_message(self, message):
- assert message.thread
- forum = 0
- topic = 0
- if message.thread:
- try:
- if '.' in message.thread.id:
- forum, topic = [int(i) for i in message.thread.id.split('.', 1)]
- else:
- forum = int(message.thread.id)
- except ValueError:
- raise CantSendMessage('Thread ID must be in form "FORUM_ID[.TOPIC_ID]".')
- with self.browser:
- return self.browser.post_answer(forum,
- topic,
- message.title,
- message.content)
- OBJECTS = {Thread: fill_thread}