pax_global_header 0000666 0000000 0000000 00000000064 13434601454 0014516 g ustar 00root root 0000000 0000000 52 comment=d0a72914b1b13c7766ca764ce93a9d23b473bfe7
woob-d0a72914b1b13c7766ca764ce93a9d23b473bfe7-modules-dlfp/ 0000775 0000000 0000000 00000000000 13434601454 0022060 5 ustar 00root root 0000000 0000000 woob-d0a72914b1b13c7766ca764ce93a9d23b473bfe7-modules-dlfp/modules/ 0000775 0000000 0000000 00000000000 13434601454 0023530 5 ustar 00root root 0000000 0000000 woob-d0a72914b1b13c7766ca764ce93a9d23b473bfe7-modules-dlfp/modules/dlfp/ 0000775 0000000 0000000 00000000000 13434601454 0024455 5 ustar 00root root 0000000 0000000 woob-d0a72914b1b13c7766ca764ce93a9d23b473bfe7-modules-dlfp/modules/dlfp/__init__.py 0000664 0000000 0000000 00000001550 13434601454 0026567 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2010-2011 Romain Bignon
#
# This file is part of a weboob module.
#
# This weboob module 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.
#
# This weboob module 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 this weboob module. If not, see .
from .browser import DLFP
from .module import DLFPModule
__all__ = ['DLFP', 'DLFPModule']
woob-d0a72914b1b13c7766ca764ce93a9d23b473bfe7-modules-dlfp/modules/dlfp/browser.py 0000664 0000000 0000000 00000020573 13434601454 0026521 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2010-2011 Romain Bignon
#
# This file is part of a weboob module.
#
# This weboob module 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.
#
# This weboob module 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 this weboob module. If not, see .
import re
import hashlib
import lxml
from requests.exceptions import HTTPError
from weboob.browser import LoginBrowser, need_login, URL
from weboob.browser.exceptions import HTTPNotFound
from weboob.exceptions import BrowserIncorrectPassword, ParseError
from weboob.capabilities.messages import CantSendMessage
from .pages.index import IndexPage, LoginPage
from .pages.news import ContentPage, NewCommentPage, NodePage, CommentPage, NewTagPage, RSSComment
from .pages.board import BoardIndexPage
from .pages.wiki import WikiEditPage
from .tools import id2url, url2id
# Browser
class DLFP(LoginBrowser):
BASEURL = 'https://linuxfr.org/'
index = URL(r'/?$', IndexPage)
login = URL(r'/compte/connexion', LoginPage)
content = URL(r'/news/.+',
r'/wiki/(?!nouveau)[^/]+',
r'/suivi/[^\.]+',
r'/sondages/[^\.]+',
r'/users/[^\./]+/journaux/[^\.]+',
r'/forums/[^\./]+/posts/[^\.]+',
ContentPage)
wiki_edit = URL(r'/wiki$',
r'/wiki/nouveau',
r'/wiki/[^\.]+/modifier',
WikiEditPage)
comment = URL(r'/nodes/(\d+)/comments/(\d+)', CommentPage)
new_comment = URL(r'/nodes/(\d+)/comments/nouveau', NewCommentPage)
node = URL(r'/nodes/(\d+)/comments', NodePage)
new_tag = URL(r'/nodes/(\d+)/tags/nouveau', NewTagPage)
board_index = URL(r'/board/index.xml', BoardIndexPage)
rss_comment = URL(r'/nodes/(\d+)/comments.atom', RSSComment)
last_board_msg_id = None
_token = None
def parse_id(self, _id):
if re.match('^https?://.*linuxfr.org/nodes/\d+/comments/\d+$', _id):
return _id, None
url = id2url(_id)
if url is None:
if url2id(_id) is not None:
url = _id
_id = url2id(url)
else:
return None, None
return url, _id
@need_login
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 HTTPNotFound:
return ''
assert self.wiki_edit.is_here()
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 HTTPNotFound:
self.location('/wiki/nouveau')
new = True
else:
new = False
assert self.wiki_edit.is_here()
return new
@need_login
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)
@need_login
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.wiki_edit.is_here():
return self.page.get_preview_html()
elif self.content.is_here():
return self.page.get_article().body
def get_hash(self, url):
self.location(url)
if self.page.doc.xpath('//entry'):
myhash = hashlib.md5(lxml.etree.tostring(self.page.doc)).hexdigest()
return myhash
else:
return None
def get_content(self, _id):
url, _id = self.parse_id(_id)
if url is None:
return None
self.location(url)
if self.comment.is_here():
content = self.page.get_comment()
elif self.content.is_here():
m = re.match('.*#comment-(\d+)$', url)
if m:
content = self.page.get_comment(int(m.group(1)))
else:
content = self.page.get_article()
else:
raise ParseError('Not on a content or comment page (%r)' % self.page)
if _id is not None:
content.id = _id
return content
@need_login
def post_comment(self, thread, reply_id, title, message):
url = id2url(thread)
if url is None:
raise CantSendMessage('%s is not a right ID' % thread)
self.location(url)
assert self.content.is_here()
self.location(self.page.get_post_comment_url())
assert self.new_comment.is_here()
form = self.page.get_form(xpath='//form[contains(@action,"comment_new")]')
if title is not None:
form['comment[title]'] = title.encode('utf-8')
form['comment[wiki_body]'] = message.encode('utf-8')
if int(reply_id) > 0:
form['comment[parent_id]'] = str(reply_id)
form['commit'] = 'Poster le commentaire'
try:
form.submit()
except HTTPError as e:
raise CantSendMessage('Unable to send message to %s.%s: %s' % (thread, reply_id, e))
if self.node.is_here():
errors = self.page.get_errors()
if len(errors) > 0:
raise CantSendMessage('Unable to send message: %s' % ', '.join(errors))
return None
def do_login(self):
if self.username is None:
return
# not usefull for the moment
#self.location('/', no_login=True)
data = {'account[login]': self.username,
'account[password]': self.password,
'account[remember_me]': 1,
#'authenticity_token': self.page.get_login_token(),
}
self.location('/compte/connexion', data=data)
if not self.is_logged():
raise BrowserIncorrectPassword()
self._token = self.page.doc.xpath('//input[@name="authenticity_token"]')
def is_logged(self):
return (self.username is None or (self.page and self.page.logged))
def close_session(self):
if self._token:
self.open('/compte/deconnexion', data={'authenticity_token': self._token[0].attrib['value']})
def plusse(self, url):
return self.relevance(url, 'for')
def moinse(self, url):
return self.relevance(url, 'against')
@need_login
def relevance(self, url, what):
comment = self.get_content(url)
if comment is None:
raise ValueError('The given URL isn\'t a comment.')
if comment.relevance_token is None:
return False
res = self.open('%s%s' % (comment.relevance_url, what),
data={'authenticity_token': comment.relevance_token}).content
return res
def iter_new_board_messages(self):
self.location('/board/index.xml')
assert self.board_index.is_here()
msgs = self.page.get_messages(self.last_board_msg_id)
for msg in reversed(msgs):
self.last_board_msg_id = msg.id
yield msg
@need_login
def board_post(self, msg):
self.open(self.absurl('/board/'), data={'board[message]': msg},
headers={'Referer': self.absurl('/')})
@need_login
def add_tag(self, _id, tag):
url, _id = self.parse_id(_id)
if url is None:
return None
self.location(url)
assert self.content.is_here()
self.location(self.page.get_tag_url())
assert self.new_tag.is_here()
self.page.tag(tag)
woob-d0a72914b1b13c7766ca764ce93a9d23b473bfe7-modules-dlfp/modules/dlfp/favicon.png 0000664 0000000 0000000 00000011764 13434601454 0026621 0 ustar 00root root 0000000 0000000 PNG
IHDR @ @ % sRGB pHYs tIME
,0a IDAThi]W}{fެ{I;5-EiPJ*TʇVHtIP@D Nxyom~{8&F)]{wYq~2*;]wޡC)%tloeiW@D@HBCoF)%5=ED!yK(Ap+gOT6}F w
qJ9e
c
ʖJ-!76ŕ_^9VN|]@W2@3B2
eK[ֵ*S
i(lF! ,4
!7˷"w# @G2 MP9Pz H )>BnN$NW !$-$
CC[l^Xs0erJޒrS9pcw$UCۄit
8{h806K6@AW CX>tcwt}ox?lL}r@|GukI 0
ݾ_,J$RB2:]pSFi3ɣ?]/LKUJǦ+p7T-Eoh6![`3h1*o߆O5ie]RY^[%y)H[BeS
jso#2B[Qa93+Mhf&cUvNl&V]ؽ'|/).峾~rd?C>|[ķO7!K߁/~`B6>ޣ
WNRcc{ta~85}^saZ}q\"#f#%|G٧JS^pG+Ώ{=cgcjw]P#\mw>nJ/u07 o=T\.#K;eB%NjG۱Fup{4{EDLkwUOKO&W3}e|vCyaOCeeV'aJkH
Ʀqhvx#2H8?jL;6/_TulGlni/$L.W*iإr>kj*