pax_global_header 0000666 0000000 0000000 00000000064 14042356110 0014506 g ustar 00root root 0000000 0000000 52 comment=18d41565f955028f9fcd2f6cc437f5f1cb717401
woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/ 0000775 0000000 0000000 00000000000 14042356110 0023001 5 ustar 00root root 0000000 0000000 woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/ 0000775 0000000 0000000 00000000000 14042356110 0024451 5 ustar 00root root 0000000 0000000 woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/pariskiwi/ 0000775 0000000 0000000 00000000000 14042356110 0026453 5 ustar 00root root 0000000 0000000 woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/pariskiwi/__init__.py 0000664 0000000 0000000 00000001505 14042356110 0030565 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2013 Vincent A
#
# This file is part of a woob module.
#
# This woob 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 woob 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 woob module. If not, see .
from .module import ParisKiwiModule
__all__ = ['ParisKiwiModule']
woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/pariskiwi/browser.py 0000664 0000000 0000000 00000010717 14042356110 0030516 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2013 Vincent A
#
# This file is part of a woob module.
#
# This woob 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 woob 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 woob module. If not, see .
from __future__ import unicode_literals
from datetime import datetime, time
import re
from woob.browser.browsers import APIBrowser
__all__ = ['ParisKiwiBrowser']
CAL = 'Agenda/Detruire_Ennui_Paris'
class ParisKiwiBrowser(APIBrowser):
PROTOCOL = 'https'
DOMAIN = 'pariskiwi.org'
BASEURL = 'https://pariskiwi.org'
ENCODING = 'utf-8'
def list_events_all(self):
ids = []
cont = ''
# titles are in m-d-y format, so we're forced to fetch everything
while True:
data = self.request('/api.php?action=query&list=allpages&apprefix=%s&aplimit=500&format=json&apcontinue=%s' % (CAL, cont))
ids.extend(id_from_title(p['title']) for p in data['query']['allpages'])
if 'continue' in data:
cont = data['continue']['apcontinue']
else:
break
ids = [_id for _id in ids if _id and _id != 'style']
ids.sort(key=date_from_id)
for _id in ids:
yield {
'id': _id,
'date': date_from_id(_id),
}
def get_event(self, _id):
_id = id_from_title(_id)
j = self.request('/api.php?action=query&format=json&prop=revisions&rvprop=content&rvlimit=1&titles=%s/%s' % (CAL, _id))
pages = j['query']['pages']
page = pages[list(pages.keys())[0]]
text = page['revisions'][0]['*']
res = {
'id': _id,
'date': date_from_id(_id),
'datetime': date_from_id(_id),
'url': 'https://pariskiwi.org/index.php/%s/%s' % (CAL, _id),
'description': text,
'summary': find_title(text),
}
match = re.search(r'\b(\d\d?)h(\d\d)?\b', text)
if match:
res['hour'] = time(int(match.group(1)), int(match.group(2) or '0'))
res['datetime'] = combine(res['date'], res['hour'])
text = text[:match.start(0)] + text[match.end(0):]
match = re.search(u'\\b(\\d+([,.]\\d+)?)\s*(euros\\b|euro\\b|€)', text)
if match:
res['price'] = float(match.group(1).replace(',', '.'))
text = text[:match.start(0)] + text[match.end(0):]
res['address'] = find_address(text)
if not res['address']:
res.pop('address')
return res
def id_from_title(title):
return title.rsplit('/', 1)[-1].replace(' ', '_')
def date_from_id(_id):
_id = id_from_title(_id).split('_', 1)[0]
return datetime.strptime(_id, '%m-%d-%Y')
def id_from_path(title):
return title.replace(' ', '_').split('/')[-1]
def combine(dt, t):
return datetime(dt.year, dt.month, dt.day, t.hour, t.minute)
def find_title(text):
for line in text.split('\n'):
line = line.strip()
line = re.sub(r'^=+(.*)=+$', '', line)
if line:
return line
def find_address(text):
address = []
parts = text.split('\n')
for n, p in enumerate(parts):
match = re.search(r'\d+[\s,]+(rue|boulevard|avenue)\s+.+', p, re.I)
if match:
address.append(match.group(0))
p = parts[n] = p[:match.start(0)] + p[match.end(0):]
match = re.search(r'\b(75|92|93|94|78|77|95|91)\d\d\d\b.*', p)
if match:
address.append(match.group(0))
p = parts[n] = p[:match.start(0)] + p[match.end(0):]
match = re.search(r'\b(m.tro|rer)\b.*', p, re.I)
if match:
address.append(match.group(0))
p = parts[n] = p[:match.start(0)] + p[match.end(0):]
match = re.search(r'@\s+\w+(\s+[^.]+.*)?', p) # refuse '@foo' or '@ foo . plop'
if match:
address.append(match.group(0))
p = parts[n] = p[:match.start(0)] + p[match.end(0):]
return ' '.join(address)
woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/pariskiwi/favicon.png 0000664 0000000 0000000 00000001634 14042356110 0030612 0 ustar 00root root 0000000 0000000 PNG
IHDR @ @ iq bKGD c = Xw pHYs tIME
6' tEXtComment Created with GIMPW IDATxZKNA@"eaqPv[#rYs@bkl&iVzơKiޫWjJӢE-Z|ڀ
G~~2H{'Lo3wz&{P~,U2? ]Pa
s._H*0w}ȐnT)Wo!M~,0) /XOյD$LH$X),z6_^bm=Pd/ 5IE :D n$!{IxEDߏF8 oSLbG~͑c_^Q0-g?vm*X`j64T)?@5CX)kf9Cp,&(ZÌ_NaAHciR2$u?:[a=b㎓An}!Jן0: / 5Ԯ@" @+M-R
+n=`}n6gmhm7ԶHm%-KD;s d̛]^q%#$k!R$r z@ wmg܆)qwXwbW7AN9pdOn0Qjuf;TY>(V GC?<^d Fr05!lL/tC0"uT 5/ꪌ2Ǜۧ( y)_,% f,Ir@/MM*q2-Zhq
rZN IENDB` woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/pariskiwi/module.py 0000664 0000000 0000000 00000005575 14042356110 0030326 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2013 Vincent A
#
# This file is part of a woob module.
#
# This woob 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 woob 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 woob module. If not, see .
from woob.tools.backend import Module
from woob.capabilities.calendar import CapCalendarEvent, BaseCalendarEvent, CATEGORIES, TRANSP, STATUS
from datetime import datetime, time
from .browser import ParisKiwiBrowser
__all__ = ['ParisKiwiModule']
class ParisKiwiModule(Module, CapCalendarEvent):
NAME = 'pariskiwi'
DESCRIPTION = u'ParisKiwi website'
MAINTAINER = u'Vincent A'
EMAIL = 'dev@indigo.re'
LICENSE = 'AGPLv3+'
VERSION = '3.1'
BROWSER = ParisKiwiBrowser
ASSOCIATED_CATEGORIES = [CATEGORIES.CONCERT]
def search_events(self, query):
if self.has_matching_categories(query):
for event in self.list_events(query.start_date, query.end_date or None):
yield event
def list_events(self, date_from, date_to=None):
for d in self.browser.list_events_all():
if date_from and d['date'] < date_from:
continue
if date_to and d['date'] > date_to:
break
event = self.get_event(d['id'])
if event:
yield event
def get_event(self, _id):
d = self.browser.get_event(_id)
if not d:
return None
return self._make_event(d)
def _make_event(self, d):
event = BaseCalendarEvent(d['id'])
event.city = u'Paris'
event.url = d['url']
event.start_date = d['datetime']
event.end_date = datetime.combine(d['datetime'].date(), time.max)
event.summary = d['summary']
event.category = CATEGORIES.CONCERT
event.description = d['description']
event.status = STATUS.CONFIRMED
event.transp = TRANSP.OPAQUE
if 'price' in d:
event.price = d['price']
if 'address' in d:
event.location = d['address']
return event
def _make_false_event(self):
event = BaseCalendarEvent('0')
event.start_date = event.end_date = datetime.utcfromtimestamp(0)
event.summary = u'NON EXISTING EVENT'
event.status = STATUS.CANCELLED
event.category = CATEGORIES.CONCERT
event.transp = TRANSP.OPAQUE
return event
woob-18d41565f955028f9fcd2f6cc437f5f1cb717401-modules-pariskiwi/modules/pariskiwi/test.py 0000664 0000000 0000000 00000003037 14042356110 0030007 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
# Copyright(C) 2013 Vincent A
#
# This file is part of a woob module.
#
# This woob 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 woob 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 woob module. If not, see .
from woob.tools.test import BackendTest
from datetime import datetime, date
class ParisKiwiTest(BackendTest):
MODULE = 'pariskiwi'
def test_pariskiwi_event(self):
event = self.backend.get_event('11-9-2013_-Event_2')
self.assertTrue(event)
self.assertIn('Belleville', event.location)
self.assertEqual(event.price, 5)
self.assertTrue(event.summary)
self.assertEqual(event.start_date, datetime(2013, 11, 9, 20, 30))
self.assertEqual(event.url, 'https://pariskiwi.org/index.php/Agenda/Detruire_Ennui_Paris/11-9-2013_-Event_2')
def test_pariskiwi_list(self):
it = self.backend.list_events(datetime.now())
ev = next(it)
self.assertTrue(ev)
self.assertGreaterEqual(ev.start_date.date(), date.today())