diff --git a/.travis.yml b/.travis.yml index b165373..260959d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,13 @@ language: python +python: + - "2.6" + - "2.7" + - "3.2" + - "3.3" + - "3.4" + - "3.5" + cache: directories: - $HOME/.cache/pip diff --git a/hooks/flat_schedule.py b/hooks/flat_schedule.py index b89ff08..26e678c 100755 --- a/hooks/flat_schedule.py +++ b/hooks/flat_schedule.py @@ -3,7 +3,6 @@ import datetime import errno import io -import itertools import os import re @@ -14,6 +13,10 @@ import vobject #import yaml +try: + from itertools import chain, repeat, izip_longest as zip_longest +except ImportError: # python 3 + from itertools import chain, repeat, zip_longest def parse_date(s): """Returns a datetime.date, from a date in the tabular schedule @@ -66,11 +69,11 @@ def collapse_whitespace(s): def repeat_none(value, times): - for i in xrange(times): + for i in range(times): yield None -def colspan_cells(cells, fillfunc=itertools.repeat): +def colspan_cells(cells, fillfunc=repeat): """Yields td or th elements, repeating them as necessary for colspan=n """ for cell in cells: @@ -80,7 +83,7 @@ def colspan_cells(cells, fillfunc=itertools.repeat): yield item -def rowspan_cells(cells, rowspans, fillfunc=itertools.repeat): +def rowspan_cells(cells, rowspans, fillfunc=repeat): """Yields td or th elements, repeating them as necessary for colspan=n & rowspan=n. """ @@ -109,7 +112,7 @@ def parse_rooms(table): """ row1 = colspan_cells(table.xpath('./thead/tr[1]/th')[1:]) row2 = colspan_cells(table.xpath('./thead/tr[2]/th')[1:]) - for th1, th2 in itertools.izip_longest(row1, row2): + for th1, th2 in zip_longest(row1, row2): text1 = collapse_whitespace(th1.text) text2 = collapse_whitespace(th2.text) if th2 is not None else '' if text2: @@ -198,14 +201,21 @@ def parse_event(td, default_room=None): def stringify_children(node): + def make_sure_is_string(obj): + """antidote for lxml returning sometimes strings, sometimes byte strings """ + try: + return obj.decode('utf-8') + except AttributeError: + return obj + # http://stackoverflow.com/a/28173933/293340 parts = ([node.text] - + list(itertools.chain(*([lxml.html.tostring(c, with_tail=False), + + list(chain(*([lxml.html.tostring(c, with_tail=False, encoding='utf-8'), c.tail] for c in node.getchildren()) )) + [node.tail]) # filter removes possible Nones in texts and tails - return ''.join(part for part in parts if part is not None) + return ''.join(make_sure_is_string(part) for part in parts if part is not None) def events(table): @@ -414,7 +424,7 @@ def add_tz(dt): ics_path = os.path.join(config['output_dir'], 'schedule.ics') with io.open(ics_path, 'w', encoding='utf-8') as f: - f.write(cal.serialize().decode('utf-8')) + f.write(cal.serialize()) def create_flat_schedule(config): diff --git a/hooks/guidebook.py b/hooks/guidebook.py index 1f8af5f..2179058 100644 --- a/hooks/guidebook.py +++ b/hooks/guidebook.py @@ -4,10 +4,14 @@ import codecs import csv -import cStringIO import io import os +try: + from cStringIO import StringIO +except ImportError: # python 3 + from io import StringIO + from flat_schedule import (mkdirs, read_html_tabular_schedule) @@ -23,7 +27,7 @@ class UnicodeWriter(object): # https://docs.python.org/2.7/library/csv.html#writer-objects def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds): - self.queue = cStringIO.StringIO() + self.queue = StringIO() self.writer = csv.writer(self.queue, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() @@ -31,7 +35,6 @@ def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds): def writerow(self, row): self.writer.writerow([s.encode('utf-8') for s in row]) data = self.queue.getvalue() - data = data.decode('utf-8') data = self.encoder.encode(data) self.stream.write(data) self.queue.truncate(0) @@ -78,7 +81,7 @@ def extract_description(talk, config): if talk['type'] in EVENT_TYPES: path = os.path.join(config['content_dir'], talk['href'].strip('/') + '.md') with open(path) as f: - text = f.read().decode('utf-8') + text = f.read() # Remove metadata if present. idx = text.find('###') if idx != -1: diff --git a/hooks/schedule_summary.py b/hooks/schedule_summary.py index ce800fc..7de4eb8 100644 --- a/hooks/schedule_summary.py +++ b/hooks/schedule_summary.py @@ -8,10 +8,15 @@ import codecs import csv -import cStringIO import io import os +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO + + from flat_schedule import mkdirs, read_html_tabular_schedule @@ -23,7 +28,7 @@ class UnicodeWriter(object): # https://docs.python.org/2.7/library/csv.html#writer-objects def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds): - self.queue = cStringIO.StringIO() + self.queue = StringIO() self.writer = csv.writer(self.queue, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() @@ -31,7 +36,6 @@ def __init__(self, f, dialect=csv.excel, encoding='utf-8', **kwds): def writerow(self, row): self.writer.writerow([s.encode('utf-8') for s in row]) data = self.queue.getvalue() - data = data.decode('utf-8') data = self.encoder.encode(data) self.stream.write(data) self.queue.truncate(0) @@ -71,7 +75,6 @@ def extract_speaker(talk, config): path = os.path.join(config['content_dir'], talk['href'].strip('/') + '.md') with open(path) as f: for line in f: - line = line.decode('utf-8') if line[:4] == '### ': return line[4:].strip() return '' diff --git a/requirements.txt b/requirements.txt index d3e3321..482424e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,11 @@ -awesome-slugify==1.4 -docutils==0.8.1 -Jinja2==2.7.3 -LinkChecker==9.3 +#LinkChecker==9.3 # waiting for py3 version lxml==3.4.4 -Markdown==2.1.1 MarkupSafe==0.23 -py==1.4.27 -Pygments==1.4 -pytest==2.5.2 python-dateutil==2.4.2 pytz==2015.4 -PyYAML==3.10 regex==2015.5.10 requests==2.7.0 six==1.9.0 Unidecode==0.4.17 -vobject==0.6.6 -wok==1.1.1 +-e git+https://github.com/tBaxter/vobject.git@5bdf21751a6f443045e05db862e00be5bbd006f3#egg=vobject +-e git+https://github.com/jneves/wok.git@21ce6ea44483218b2380104b6ada8865122ddf2c#egg=wok