the DLFP backend implements ICapContent
This commit is contained in:
parent
4a864a97af
commit
55a8154f39
4 changed files with 156 additions and 9 deletions
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
54
weboob/backends/dlfp/pages/wiki.py
Normal file
54
weboob/backends/dlfp/pages/wiki.py
Normal 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)
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue