The new woob repository is here: https://gitlab.com/woob/woob. This gitlab will be removed soon.

The new woob repository is here: https://gitlab.com/woob/woob. This gitlab will be removed soon.

Commit fcd43011 authored by Simon Lipp's avatar Simon Lipp Committed by Vincent A

tapatalk: python3 support

parent 59b9c2c3
Pipeline #2615 passed with stages
in 13 minutes and 11 seconds
......@@ -21,7 +21,9 @@
import datetime
import requests
import re
import xmlrpclib
from six import text_type
from six.moves import urllib, xmlrpc_client
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import Value, ValueBackendPassword
......@@ -41,29 +43,41 @@ def __init__(self, uri):
def request(self, host, handler, request, verbose):
response = self._session.post(self._uri, data = request,
headers={"Content-Type": "text/xml; charset=UTF-8"})
p, u = xmlrpclib.getparser()
p, u = xmlrpc_client.getparser()
p.feed(response.content)
p.close()
response.close()
return u.close()
class TapatalkServerProxy(xmlrpclib.ServerProxy):
class TapatalkServerProxy(xmlrpc_client.ServerProxy):
def __init__(self, uri):
transport = RequestsTransport(uri)
xmlrpclib.ServerProxy.__init__(self, uri, transport)
xmlrpc_client.ServerProxy.__init__(self, uri, transport)
def __getattr__(self, name):
method = xmlrpclib.ServerProxy.__getattr__(self, name)
method = xmlrpc_client.ServerProxy.__getattr__(self, name)
return self._wrap(method)
def _wrap(self, method):
def call(*args, **kwargs):
res = method(*args, **kwargs)
if 'result' in res and not res['result']:
raise TapatalkError(str(res.get('result_text')))
raise TapatalkError(xmlrpc_str(res['result_text']))
return res
return call
def xmlrpc_str(data):
"""
Depending on how the XML-RPC server on the other end has been
implemented, strings can either be str (or unicode in python2)
or xmlrpc_client.Binary. Convert the later case in the former, and
ensure that the result is always a str (even if the input is a number)
"""
if isinstance(data, xmlrpc_client.Binary):
return text_type(data.data, 'utf-8')
else:
return text_type(data)
class TapatalkModule(Module, CapMessages):
NAME = 'tapatalk'
DESCRIPTION = u'Tapatalk-compatible sites'
......@@ -72,9 +86,10 @@ class TapatalkModule(Module, CapMessages):
LICENSE = 'AGPLv3+'
VERSION = '1.6'
CONFIG = BackendConfig(Value('username', label='Username', default=''),
ValueBackendPassword('password', label='Password', default=''),
Value('url', label='Site URL', default="https://support.tapatalk.com/mobiquo/mobiquo.php"))
CONFIG = BackendConfig(Value('username', label='Username', default=''),
ValueBackendPassword('password', label='Password', default=''),
Value('url', label='Site URL', default="https://support.tapatalk.com/mobiquo/mobiquo.php"),
Value('message_url_format', label='Message URL format', default='/index.php?/topic/{thread_id}-{thread_title}#entry{message_id}'))
def __init__(self, *args, **kwargs):
super(TapatalkModule, self).__init__(*args, **kwargs)
......@@ -88,45 +103,47 @@ def _conn(self):
password = self.config['password'].get()
self._xmlrpc_client = TapatalkServerProxy(url)
try:
self._xmlrpc_client.login(xmlrpclib.Binary(username), xmlrpclib.Binary(password))
self._xmlrpc_client.login(username, password)
except TapatalkError as e:
raise BrowserIncorrectPassword(e.message)
return self._xmlrpc_client
def _get_time(self, post):
if 'post_time' in post:
return dateutil.parser.parse(str(post['post_time']))
return dateutil.parser.parse(xmlrpc_str(post['post_time']))
else:
return datetime.datetime.now()
def _format_content(self, post):
msg = unicode(str(post['post_content']), 'utf-8')
msg = xmlrpc_str(post['post_content'])
msg = re.sub(r'\[url=(.+?)\](.*?)\[/url\]', r'<a href="\1">\2</a>', msg)
msg = re.sub(r'\[quote\s?.*\](.*?)\[/quote\]', r'<blockquote><p>\1</p></blockquote>', msg)
msg = re.sub(r'\[img\](.*?)\[/img\]', r'<img src="\1">', msg)
if post.get('icon_url'):
return u'<img style="float:right;position:relative" src="%s"> %s' % (post['icon_url'], msg)
return u'<img style="float:right;position:relative" src="%s"> %s' % (xmlrpc_str(post['icon_url']), msg)
else:
return msg
def _process_post(self, thread, post, is_root):
message_id = is_root and u'0' or xmlrpc_str(post['post_id'])
message_title = is_root and thread.title or u'Re: %s' % thread.title
# Tapatalk app seems to have hardcoded this construction... I don't think we can do better :(
url = u'%s/index.php?/topic/%s-%s#entry%s' % (
self.config["url"].get().rstrip('/'),
thread.id,
re.sub(r'[^a-zA-Z0-9-]', '', re.sub(r'\s+', '-', thread.title)),
post['post_id']
)
rel_url = self.config['message_url_format'].get().format(
thread_id = urllib.parse.quote(thread.id.encode('utf-8')),
thread_title = urllib.parse.quote(thread.title.encode('utf-8')),
message_id = urllib.parse.quote(message_id.encode('utf-8')),
message_title = urllib.parse.quote(message_title.encode('utf-8')))
message = Message(
id = is_root and "0" or str(post['post_id']),
id = message_id,
thread = thread,
sender = unicode(str(post.get('post_author_name', 'Anonymous')), 'utf-8'),
title = is_root and thread.title or u"Re: %s"%thread.title,
url = url,
sender = xmlrpc_str(post.get('post_author_name', u'Anonymous')),
title = message_title,
url = urllib.parse.urljoin(self.config['url'].get(), rel_url),
receivers = None,
date = self._get_time(post),
content = self._format_content(post),#bbcode(),
content = self._format_content(post),
signature = None,
parent = thread.root or None,
children = [],
......@@ -140,7 +157,7 @@ def _process_post(self, thread, post, is_root):
# First message in the thread is not the root message,
# because we asked only for unread messages. Create a non-loaded root
# message to allow monboob to fill correctly the References: header
thread.root = Message(id="0", parent=None, children=[message], thread=thread)
thread.root = Message(id=u'0', parent=None, children=[message], thread=thread)
message.parent = thread.root
return message
......@@ -161,7 +178,7 @@ def fill_root(thread, start, count, first_unread):
count = 50
topic = self._conn.get_thread_by_unread(thread.id, count)
if 'title' in fields:
thread.title = unicode(str(topic['topic_title']), 'utf-8')
thread.title = xmlrpc_str(topic['topic_title'])
if 'date' in fields:
thread.date = self._get_time(topic)
if 'root' in fields:
......@@ -188,14 +205,14 @@ def browse_forum_mode(forum, prefix, mode):
count = 50
while True:
if mode:
topics = self._conn.get_topic(forum['forum_id'], start, start+count-1, mode)
topics = self._conn.get_topic(xmlrpc_str(forum['forum_id']), start, start+count-1, mode)
else:
topics = self._conn.get_topic(forum['forum_id'], start, start+count-1)
topics = self._conn.get_topic(xmlrpc_str(forum['forum_id']), start, start+count-1)
all_ignored = True
for topic in topics['topics']:
t = Thread(topic['topic_id'])
t.title = unicode(str(topic['topic_title']), 'utf-8')
t = Thread(xmlrpc_str(topic['topic_id']))
t.title = xmlrpc_str(topic['topic_title'])
t.date = self._get_time(topic)
if not unread or topic.get('new_post'):
all_ignored = False
......@@ -211,11 +228,11 @@ def process_forum(forum, prefix):
yield thread
for child in forum.get('child', []):
for thread in process_forum(child, "%s.%s" % (prefix, child['forum_name'])):
for thread in process_forum(child, u"%s.%s" % (prefix, xmlrpc_str(child['forum_name']))):
yield thread
for forum in self._conn.get_forum():
for thread in process_forum(forum, "%s" % forum['forum_name']):
for thread in process_forum(forum, xmlrpc_str(forum['forum_name'])):
yield thread
def iter_unread_messages(self):
......
......@@ -146,6 +146,7 @@ sprunge
sueurdemetal
supertoinette
suravenir
tapatalk
themisbanque
tumblr
tvsubtitles
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment