the DLFP backend implements ICapContent

This commit is contained in:
Romain Bignon 2011-03-19 11:24:36 +01:00
commit 55a8154f39
4 changed files with 156 additions and 9 deletions

View file

@ -22,6 +22,7 @@ from weboob.tools.backend import BaseBackend
from weboob.tools.newsfeed import Newsfeed from weboob.tools.newsfeed import Newsfeed
from weboob.tools.value import Value, ValueBool, ValuesDict from weboob.tools.value import Value, ValueBool, ValuesDict
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread, CantSendMessage from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread, CantSendMessage
from weboob.capabilities.content import ICapContent, Content
from .browser import DLFP from .browser import DLFP
from .tools import rssid, id2url from .tools import rssid, id2url
@ -30,7 +31,7 @@ from .tools import rssid, id2url
__all__ = ['DLFPBackend'] __all__ = ['DLFPBackend']
class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost): class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapContent):
NAME = 'dlfp' NAME = 'dlfp'
MAINTAINER = 'Romain Bignon' MAINTAINER = 'Romain Bignon'
EMAIL = 'romain@weboob.org' EMAIL = 'romain@weboob.org'
@ -58,6 +59,8 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost):
with self.browser: with self.browser:
self.browser.close_session() self.browser.close_session()
#### ICapMessages ##############################################
def iter_threads(self): def iter_threads(self):
whats = set() whats = set()
if self.config['get_news']: if self.config['get_news']:
@ -152,6 +155,10 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost):
self.storage.get('seen', message.thread.id, 'comments', default=[]) + [message.id]) self.storage.get('seen', message.thread.id, 'comments', default=[]) + [message.id])
self.storage.save() self.storage.save()
def fill_thread(self, thread, fields):
return self.get_thread(thread)
#### ICapMessagesReply #########################################
def post_message(self, message): def post_message(self, message):
if not message.parent: if not message.parent:
raise CantSendMessage('Posting news and diaries on DLFP is not supported yet') raise CantSendMessage('Posting news and diaries on DLFP is not supported yet')
@ -164,7 +171,29 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost):
message.title, message.title,
message.content) message.content)
def fill_thread(self, thread, fields): #### ICapContent ###############################################
return self.get_thread(thread) def get_content(self, id):
if isinstance(id, basestring):
content = Content(id)
else:
content = id
id = content.id
with self.browser:
data = self.browser.get_wiki_content(id)
if data is None:
return None
content.content = data
return content
def push_content(self, content, message=None, minor=False):
with self.browser:
return self.browser.set_wiki_content(content.id, content.content, message)
def get_content_preview(self, content):
with self.browser:
return self.browser.get_wiki_preview(content.id, content.content)
OBJECTS = {Thread: fill_thread} OBJECTS = {Thread: fill_thread}

View file

@ -19,12 +19,13 @@
import urllib import urllib
import re import re
from weboob.tools.browser import BaseBrowser, BrowserHTTPError, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserHTTPNotFound, BrowserHTTPError, BrowserIncorrectPassword
from weboob.capabilities.messages import CantSendMessage from weboob.capabilities.messages import CantSendMessage
from .pages.index import IndexPage, LoginPage from .pages.index import IndexPage, LoginPage
from .pages.news import ContentPage, NewCommentPage, NodePage, CommentPage, NewTagPage from .pages.news import ContentPage, NewCommentPage, NodePage, CommentPage, NewTagPage
from .pages.board import BoardIndexPage from .pages.board import BoardIndexPage
from .pages.wiki import WikiEditPage
from .tools import id2url, url2id from .tools import id2url, url2id
# Browser # Browser
@ -34,12 +35,15 @@ class DLFP(BaseBrowser):
PAGES = {'https://linuxfr.org/?': IndexPage, PAGES = {'https://linuxfr.org/?': IndexPage,
'https://linuxfr.org/login.html': LoginPage, 'https://linuxfr.org/login.html': LoginPage,
'https://linuxfr.org/news/[^\.]+': ContentPage, 'https://linuxfr.org/news/[^\.]+': ContentPage,
'https://linuxfr.org/wiki/[^\.]+': ContentPage, 'https://linuxfr.org/wiki/(?!nouveau)[^/]+': ContentPage,
'https://linuxfr.org/wiki': WikiEditPage,
'https://linuxfr.org/wiki/nouveau': WikiEditPage,
'https://linuxfr.org/wiki/[^\.]+/modifier': WikiEditPage,
'https://linuxfr.org/users/[\w\-_]+/journaux/[^\.]+': ContentPage, 'https://linuxfr.org/users/[\w\-_]+/journaux/[^\.]+': ContentPage,
'https://linuxfr.org/forums/[\w\-_]+/posts/[^\.]+': ContentPage, 'https://linuxfr.org/forums/[\w\-_]+/posts/[^\.]+': ContentPage,
'https://linuxfr.org/nodes/(\d+)/comments/(\d+)$': CommentPage, 'https://linuxfr.org/nodes/(\d+)/comments/(\d+)': CommentPage,
'https://linuxfr.org/nodes/(\d+)/comments/nouveau': NewCommentPage, 'https://linuxfr.org/nodes/(\d+)/comments/nouveau': NewCommentPage,
'https://linuxfr.org/nodes/(\d+)/comments$': NodePage, 'https://linuxfr.org/nodes/(\d+)/comments': NodePage,
'https://linuxfr.org/nodes/(\d+)/tags/nouveau': NewTagPage, 'https://linuxfr.org/nodes/(\d+)/tags/nouveau': NewTagPage,
'https://linuxfr.org/board/index.xml': BoardIndexPage, 'https://linuxfr.org/board/index.xml': BoardIndexPage,
} }
@ -63,6 +67,66 @@ class DLFP(BaseBrowser):
return url, _id return url, _id
def get_wiki_content(self, _id):
url, _id = self.parse_id('W.%s' % _id)
if url is None:
return None
try:
self.location('%s/modifier' % url)
except BrowserHTTPNotFound:
return ''
assert self.is_on_page(WikiEditPage)
return self.page.get_body()
def _go_on_wiki_edit_page(self, name):
"""
Go on the wiki page named 'name'.
Return True if this is a new page, or False if
the page already exist.
Return None if it isn't a right wiki page name.
"""
url, _id = self.parse_id('W.%s' % name)
if url is None:
return None
try:
self.location('%s/modifier' % url)
except BrowserHTTPNotFound:
self.location('/wiki/nouveau')
new = True
else:
new = False
assert self.is_on_page(WikiEditPage)
return new
def set_wiki_content(self, name, content, message):
new = self._go_on_wiki_edit_page(name)
if new is None:
return None
if new:
title = name.replace('-', ' ')
else:
title = None
self.page.post_content(title, content, message)
def get_wiki_preview(self, name, content):
if self._go_on_wiki_edit_page(name) is None:
return None
self.page.post_preview(content)
if self.is_on_page(WikiEditPage):
return self.page.get_preview_html()
elif self.is_on_page(ContentPage):
return self.page.get_article().body
def get_content(self, _id): def get_content(self, _id):
url, _id = self.parse_id(_id) url, _id = self.parse_id(_id)

View file

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2010-2011 Romain Bignon
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from weboob.tools.parsers.lxmlparser import select, SelectElementException
from .index import DLFPPage
class WikiEditPage(DLFPPage):
def get_body(self):
try:
return select(self.document.getroot(), 'textarea#wiki_page_wiki_body', 1).text
except SelectElementException:
return ''
def _is_wiki_form(self, form):
return form.attrs.get('class', '') in ('new_wiki_page', 'edit_wiki_page')
def post_content(self, title, body, message):
self.browser.select_form(predicate=self._is_wiki_form)
self.browser.set_all_readonly(False)
if title is not None:
self.browser['wiki_page[title]'] = title
self.browser['commit'] = 'Créer'
else:
self.browser['commit'] = 'Mettre à jour'
self.browser['wiki_page[wiki_body]'] = body
if message is not None:
self.browser['wiki_page[message]'] = message
self.browser.submit()
def post_preview(self, body):
self.browser.select_form(predicate=self._is_wiki_form)
self.browser['wiki_page[wiki_body]'] = body
self.browser.submit()
def get_preview_html(self):
body = select(self.document.getroot(), 'article.wikipage div.content', 1)
return self.browser.parser.tostring(body)

View file

@ -19,10 +19,10 @@
import re import re
RSSID_RE = re.compile('tag:.*:(\w)\w+/(\d+)') RSSID_RE = re.compile('tag:.*:(\w)\w+/(\d+)')
ID2URL_RE = re.compile('^(\w)([\w\-_]*)\.([^\.]+)$') ID2URL_RE = re.compile('^(\w)([\w\-_]*)\.([^ \.]+)$')
URL2ID_DIARY_RE = re.compile('.*/users/([\w\-_]+)/journaux/([^\.]+)') URL2ID_DIARY_RE = re.compile('.*/users/([\w\-_]+)/journaux/([^\.]+)')
URL2ID_NEWSPAPER_RE = re.compile('.*/news/(.+)') URL2ID_NEWSPAPER_RE = re.compile('.*/news/(.+)')
URL2ID_WIKI_RE = re.compile('.*/wiki/(.+)') URL2ID_WIKI_RE = re.compile('.*/wiki/([^ /]+)')
URL2ID_FORUM_RE = re.compile('.*/forums/([\w\-_]+)/posts/([^\.]+)') URL2ID_FORUM_RE = re.compile('.*/forums/([\w\-_]+)/posts/([^\.]+)')
def rssid(entry): def rssid(entry):