include forum in messages ID, and ability to create new topic
This commit is contained in:
parent
e39cb220b9
commit
b8c3501ff5
4 changed files with 104 additions and 29 deletions
|
|
@ -24,10 +24,10 @@ from weboob.tools.backend import BaseBackend, 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 ICapMessages, ICapMessagesPost, Message, Thread
|
||||
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread, CantSendMessage
|
||||
|
||||
from .browser import PhpBB
|
||||
from .tools import rssid, url2id, id2url
|
||||
from .tools import rssid, url2id, id2url, id2topic
|
||||
|
||||
|
||||
__all__ = ['PhpBBBackend']
|
||||
|
|
@ -87,9 +87,9 @@ class PhpBBBackend(BaseBackend, ICapMessages, ICapMessagesPost):
|
|||
thread = id
|
||||
id = thread.id
|
||||
|
||||
thread_id = url2id(id) or id
|
||||
thread_id = url2id(id, nopost=True) or id
|
||||
try:
|
||||
last_seen_id = self.storage.get('seen', default={})[url2id(thread_id)]
|
||||
last_seen_id = self.storage.get('seen', default={})[id2topic(thread_id)]
|
||||
except KeyError:
|
||||
last_seen_id = 0
|
||||
|
||||
|
|
@ -135,11 +135,10 @@ class PhpBBBackend(BaseBackend, ICapMessages, ICapMessagesPost):
|
|||
url = self.browser.get_root_feed_url()
|
||||
for article in Newsfeed(url, rssid).iter_entries():
|
||||
id = url2id(article.link)
|
||||
thread_id, message_id = [int(v) for v in id.split('.')]
|
||||
thread = Thread(thread_id)
|
||||
thread = None
|
||||
|
||||
try:
|
||||
last_seen_id = self.storage.get('seen', default={})[thread.id]
|
||||
last_seen_id = self.storage.get('seen', default={})[id2topic(id)]
|
||||
except KeyError:
|
||||
last_seen_id = 0
|
||||
|
||||
|
|
@ -148,6 +147,8 @@ class PhpBBBackend(BaseBackend, ICapMessages, ICapMessagesPost):
|
|||
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:
|
||||
|
|
@ -163,12 +164,12 @@ class PhpBBBackend(BaseBackend, ICapMessages, ICapMessagesPost):
|
|||
|
||||
def set_message_read(self, message):
|
||||
try:
|
||||
last_seen_id = self.storage.get('seen', default={})[message.thread.id]
|
||||
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', int(message.thread.id), message.id)
|
||||
self.storage.set('seen', id2topic(message.thread.id), message.id)
|
||||
self.storage.save()
|
||||
|
||||
def fill_thread(self, thread, fields):
|
||||
|
|
@ -178,8 +179,20 @@ class PhpBBBackend(BaseBackend, ICapMessages, ICapMessagesPost):
|
|||
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(message.thread.id if message.thread else 0,
|
||||
return self.browser.post_answer(forum,
|
||||
topic,
|
||||
message.title,
|
||||
message.content)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import re
|
||||
import urllib
|
||||
from urlparse import urlsplit
|
||||
|
||||
|
|
@ -28,6 +29,10 @@ from .pages.index import LoginPage
|
|||
from .pages.forum import ForumPage, TopicPage, PostingPage
|
||||
from .tools import id2url, url2id
|
||||
|
||||
|
||||
__all__ = ['PhpBB']
|
||||
|
||||
|
||||
# Browser
|
||||
class PhpBB(BaseBrowser):
|
||||
PAGES = {'https?://.*/index.php': ForumPage,
|
||||
|
|
@ -93,7 +98,7 @@ class PhpBB(BaseBrowser):
|
|||
parent = 0
|
||||
while 1:
|
||||
for post in self.page.iter_posts():
|
||||
if post.id >= stop_id:
|
||||
if stop_id and post.id >= stop_id:
|
||||
return
|
||||
|
||||
post.parent = parent
|
||||
|
|
@ -145,11 +150,39 @@ class PhpBB(BaseBrowser):
|
|||
|
||||
return post
|
||||
|
||||
def post_answer(self, topic, title, content):
|
||||
if topic == 0:
|
||||
raise CantSendMessage('Unable to create new topic for now')
|
||||
def get_forums(self):
|
||||
self.home()
|
||||
return dict(self.page.iter_all_forums())
|
||||
|
||||
def post_answer(self, forum_id, topic_id, title, content):
|
||||
if topic_id == 0:
|
||||
if not forum_id:
|
||||
forums = self.get_forums()
|
||||
forums_prompt = 'Forums list:\n%s' % ('\n'.join(['\t- %s' % f for f in forums.itervalues()]))
|
||||
m = re.match('\[(.*)\] (.*)', title or '')
|
||||
if not m:
|
||||
raise CantSendMessage('Please enter a title formatted like that:\n\t"[FORUM] SUBJECT"\n\n%s' % forums_prompt)
|
||||
|
||||
forum_id = None
|
||||
for k,v in forums.iteritems():
|
||||
if v.lower() == m.group(1).lower():
|
||||
forum_id = k
|
||||
break
|
||||
|
||||
if not forum_id:
|
||||
raise CantSendMessage('Forum "%s" not found.\n\n%s' % (m.group(1), forums_prompt))
|
||||
|
||||
self.location('%s/posting.php?mode=post&f=%d' % (self.BASEPATH, forum_id))
|
||||
|
||||
assert self.is_on_page(PostingPage)
|
||||
self.page.post(title, content)
|
||||
|
||||
assert self.is_on_page(PostingPage)
|
||||
error = self.page.get_error_message()
|
||||
if error:
|
||||
raise CantSendMessage(u'Unable to send message: %s' % error)
|
||||
else:
|
||||
self.location('%s/%s' % (self.BASEPATH, id2url(topic)))
|
||||
self.location('%s/%s' % (self.BASEPATH, id2url(topic_id)))
|
||||
assert self.is_on_page(TopicPage)
|
||||
|
||||
self.page.go_reply()
|
||||
|
|
@ -158,7 +191,7 @@ class PhpBB(BaseBrowser):
|
|||
# Don't send title because it isn't needed in real use case
|
||||
# and with monboob title is something like:
|
||||
# Re: [Forum Name] Re: Topic Name
|
||||
if title is not None and title.startswith('Re: '):
|
||||
if title is not None and title.startswith('Re:'):
|
||||
title = None
|
||||
self.page.post(title, content)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,10 +67,19 @@ class ForumPage(PhpBBPage):
|
|||
link.nb_messages = int(li.cssselect('dd.posts')[0].text.strip()) + 1
|
||||
yield link
|
||||
|
||||
def iter_all_forums(self):
|
||||
for option in self.parser.select(self.document.getroot(), 'select#f', 1).findall('option'):
|
||||
value = int(option.attrib['value'])
|
||||
if value < 0 or not option.text:
|
||||
continue
|
||||
|
||||
yield value, option.text.strip(u'» \xa0\n\r')
|
||||
|
||||
class Post(object):
|
||||
def __init__(self, topic, id):
|
||||
def __init__(self, forum_id, topic_id, id):
|
||||
self.id = int(id)
|
||||
self.topic = topic
|
||||
self.forum_id = forum_id
|
||||
self.topic_id = topic_id
|
||||
self.title = u''
|
||||
self.author = u''
|
||||
self.date = None
|
||||
|
|
@ -85,9 +94,14 @@ class TopicPage(PhpBBPage):
|
|||
self.cur_page = int(strongs[0].text.strip())
|
||||
self.tot_pages = int(strongs[1].text.strip())
|
||||
|
||||
v = urlsplit(self.url)
|
||||
try:
|
||||
url = self.parser.select(self.document.getroot(), 'h2 a', 1).attrib['href']
|
||||
except BrokenPageError, e:
|
||||
url = self.url
|
||||
v = urlsplit(url)
|
||||
args = parse_qs(v.query)
|
||||
self.topic_id = int(args['t'][0])
|
||||
self.forum_id = int(args['f'][0]) if 'f' in args else 0
|
||||
|
||||
self.forum_title = u''
|
||||
nav = self.parser.select(self.document.getroot(), 'li.icon-home')
|
||||
|
|
@ -143,15 +157,15 @@ class TopicPage(PhpBBPage):
|
|||
profile = div.cssselect('dl.postprofile')[0]
|
||||
|
||||
id = div.attrib['id'][1:]
|
||||
post = Post(self.topic_id, id)
|
||||
post = Post(self.forum_id, self.topic_id, id)
|
||||
|
||||
title = u''
|
||||
title_tags = body.cssselect('h3 a')
|
||||
if len(title_tags) == 0:
|
||||
title_tags = self.document.getroot().cssselect('h2 a')
|
||||
if len(title_tags) == 0:
|
||||
title = u''
|
||||
self.logger.warning('Unable to parse title')
|
||||
elif title_tags[0].text:
|
||||
else:
|
||||
title = title_tags[0].text.strip()
|
||||
|
||||
post.title = self.forum_title + title
|
||||
|
|
|
|||
|
|
@ -24,13 +24,19 @@ from urlparse import urlsplit, parse_qs
|
|||
from weboob.tools.misc import local2utc
|
||||
|
||||
|
||||
def url2id(url):
|
||||
def url2id(url, nopost=False):
|
||||
v = urlsplit(url)
|
||||
pagename = v.path.split('/')[-1]
|
||||
args = parse_qs(v.query)
|
||||
if pagename == 'viewforum.php':
|
||||
return '%d' % int(args['f'][0])
|
||||
if pagename == 'viewtopic.php':
|
||||
s = '%d' % int(args['t'][0])
|
||||
if 'p' in args:
|
||||
if 'f' in args:
|
||||
s = '%d' % int(args['f'][0])
|
||||
else:
|
||||
s = '0'
|
||||
s += '.%d' % int(args['t'][0])
|
||||
if 'p' in args and not nopost:
|
||||
s += '.%d' % int(args['p'][0])
|
||||
return s
|
||||
|
||||
|
|
@ -39,11 +45,20 @@ def url2id(url):
|
|||
def id2url(id):
|
||||
v = id.split('.')
|
||||
if len(v) == 1:
|
||||
return 'viewtopic.php?t=%d' % int(v[0])
|
||||
return 'viewforum.php?f=%d' % int(v[0])
|
||||
if len(v) == 2:
|
||||
return 'viewtopic.php?t=%d&p=%d#p%d' % (int(v[0]),
|
||||
int(v[1]),
|
||||
int(v[1]))
|
||||
return 'viewtopic.php?f=%d&t=%d' % (int(v[0]), int(v[1]))
|
||||
if len(v) == 3:
|
||||
return 'viewtopic.php?f=%d&t=%d&p=%d#p%d' % (int(v[0]),
|
||||
int(v[1]),
|
||||
int(v[2]),
|
||||
int(v[2]))
|
||||
|
||||
def id2topic(id):
|
||||
try:
|
||||
return int(id.split('.')[1])
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def rssid(id):
|
||||
return id
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue