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.value import Value, ValueBool, ValuesDict
from weboob.capabilities.messages import ICapMessages, ICapMessagesPost, Message, Thread, CantSendMessage
from weboob.capabilities.content import ICapContent, Content
from .browser import DLFP
from .tools import rssid, id2url
@ -30,7 +31,7 @@ from .tools import rssid, id2url
__all__ = ['DLFPBackend']
class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost):
class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapContent):
NAME = 'dlfp'
MAINTAINER = 'Romain Bignon'
EMAIL = 'romain@weboob.org'
@ -58,6 +59,8 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost):
with self.browser:
self.browser.close_session()
#### ICapMessages ##############################################
def iter_threads(self):
whats = set()
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.save()
def fill_thread(self, thread, fields):
return self.get_thread(thread)
#### ICapMessagesReply #########################################
def post_message(self, message):
if not message.parent:
raise CantSendMessage('Posting news and diaries on DLFP is not supported yet')
@ -164,7 +171,29 @@ class DLFPBackend(BaseBackend, ICapMessages, ICapMessagesPost):
message.title,
message.content)
def fill_thread(self, thread, fields):
return self.get_thread(thread)
#### ICapContent ###############################################
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}

View file

@ -19,12 +19,13 @@
import urllib
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 .pages.index import IndexPage, LoginPage
from .pages.news import ContentPage, NewCommentPage, NodePage, CommentPage, NewTagPage
from .pages.board import BoardIndexPage
from .pages.wiki import WikiEditPage
from .tools import id2url, url2id
# Browser
@ -34,12 +35,15 @@ class DLFP(BaseBrowser):
PAGES = {'https://linuxfr.org/?': IndexPage,
'https://linuxfr.org/login.html': LoginPage,
'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/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$': NodePage,
'https://linuxfr.org/nodes/(\d+)/comments': NodePage,
'https://linuxfr.org/nodes/(\d+)/tags/nouveau': NewTagPage,
'https://linuxfr.org/board/index.xml': BoardIndexPage,
}
@ -63,6 +67,66 @@ class DLFP(BaseBrowser):
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):
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
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_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/([^\.]+)')
def rssid(entry):