ICS: url and description; refactoring
This commit is contained in:
parent
4cfff94e56
commit
632db0c37f
3 changed files with 43 additions and 30 deletions
|
@ -24,6 +24,14 @@ from docutils.parsers.rst import directives, Directive
|
||||||
from pelican import signals, generators
|
from pelican import signals, generators
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
|
try:
|
||||||
|
import ics
|
||||||
|
except ImportError:
|
||||||
|
ICS_ENABLED = False
|
||||||
|
else:
|
||||||
|
ICS_ENABLED = True
|
||||||
|
import unidecode
|
||||||
|
|
||||||
pelican = None # This will be set during register()
|
pelican = None # This will be set during register()
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,6 +118,8 @@ def get_talk_data(talkname):
|
||||||
if 'text' not in data:
|
if 'text' not in data:
|
||||||
logging.warn("Talk <{}> has no `text` field".format(talkname))
|
logging.warn("Talk <{}> has no `text` field".format(talkname))
|
||||||
data['text'] = ''
|
data['text'] = ''
|
||||||
|
else:
|
||||||
|
data['text'] = unicode(data['text'])
|
||||||
if 'duration' not in data:
|
if 'duration' not in data:
|
||||||
logging.info("Talk <{}> has no `duration` field (50min used)"
|
logging.info("Talk <{}> has no `duration` field (50min used)"
|
||||||
.format(talkname))
|
.format(talkname))
|
||||||
|
@ -303,37 +313,33 @@ class TalkGridDirective(Directive):
|
||||||
|
|
||||||
|
|
||||||
def talks_to_ics():
|
def talks_to_ics():
|
||||||
content = u'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:pelican\n'
|
c = ics.Calendar()
|
||||||
|
c.creator = u'pelican'
|
||||||
for t in all_talks():
|
for t in all_talks():
|
||||||
try:
|
e = talk_to_ics(t)
|
||||||
content += talk_to_ics(t)
|
if e is not None:
|
||||||
except:
|
c.events.add(e)
|
||||||
logging.exception("Error producing calendar for talk %s", t['id'])
|
return unicode(c)
|
||||||
content += 'END:VCALENDAR\n'
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def talk_to_ics(talk):
|
def talk_to_ics(talk):
|
||||||
if 'time' not in talk or 'duration' not in talk:
|
if 'time' not in talk or 'duration' not in talk:
|
||||||
return ''
|
return None
|
||||||
start = talk['time']
|
e = ics.Event(
|
||||||
end = start + datetime.timedelta(minutes=talk['duration'])
|
uid="%s@%d.hackmeeting.org\n" % (talk['id'], talk['day'].year),
|
||||||
content = 'BEGIN:VEVENT\n'
|
name=talk['id'],
|
||||||
content += "UID:%s@%d.hackmeeting.org\n" % (talk['id'], talk['day'].year)
|
begin=talk['time'],
|
||||||
content += "SUMMARY:%s\n" % talk['title']
|
duration=datetime.timedelta(minutes=talk['duration']),
|
||||||
content += "DTSTAMP:%s\n" % time.strftime('%Y%m%dT%H%M%SZ',
|
transparent=True,
|
||||||
time.gmtime(float(
|
)
|
||||||
start.strftime('%s'))))
|
# ics.py has some problems with unicode
|
||||||
content += "DTSTART:%s\n" % time.strftime('%Y%m%dT%H%M%SZ',
|
# unidecode replaces letters with their most similar ASCII counterparts
|
||||||
time.gmtime(float(
|
# (ie: accents get stripped)
|
||||||
start.strftime('%s'))))
|
e.description = unidecode.unidecode(talk['text'])
|
||||||
content += "DTEND:%s\n" % time.strftime('%Y%m%dT%H%M%SZ',
|
|
||||||
time.gmtime(float(
|
|
||||||
end.strftime('%s'))))
|
|
||||||
|
|
||||||
content += "LOCATION:%s\n" % (talk['room'] if 'room' in talk else 'todo')
|
e.url = pelican.settings['SCHEDULEURL'] + '#talk-' + talk['id']
|
||||||
content += 'END:VEVENT\n'
|
|
||||||
return content
|
return e
|
||||||
|
|
||||||
|
|
||||||
class TalksGenerator(generators.Generator):
|
class TalksGenerator(generators.Generator):
|
||||||
|
@ -354,10 +360,13 @@ class TalksGenerator(generators.Generator):
|
||||||
if os.path.isdir(outdir):
|
if os.path.isdir(outdir):
|
||||||
shutil.rmtree(outdir)
|
shutil.rmtree(outdir)
|
||||||
shutil.copytree(self.talks[talkname]['resources'], outdir)
|
shutil.copytree(self.talks[talkname]['resources'], outdir)
|
||||||
|
if ICS_ENABLED:
|
||||||
with io.open(os.path.join(self.output_path, pelican.settings.get('TALKS_ICS')),
|
with io.open(os.path.join(self.output_path, pelican.settings.get('TALKS_ICS')),
|
||||||
'w',
|
'w',
|
||||||
encoding='utf8') as buf:
|
encoding='utf8') as buf:
|
||||||
buf.write(talks_to_ics())
|
buf.write(talks_to_ics())
|
||||||
|
else:
|
||||||
|
logging.warning('module `ics` not found. ICS calendar will not be generated')
|
||||||
|
|
||||||
|
|
||||||
def add_talks_option_defaults(pelican):
|
def add_talks_option_defaults(pelican):
|
||||||
|
|
|
@ -14,6 +14,9 @@ SITEURL = '/hackit18'
|
||||||
RELATIVE_URLS = True
|
RELATIVE_URLS = True
|
||||||
TALKS_GRID_STEP = 30
|
TALKS_GRID_STEP = 30
|
||||||
|
|
||||||
|
# plugin/talks.py
|
||||||
|
SCHEDULEURL = 'https://hackmeeting.org' + SITEURL + '/schedule.html'
|
||||||
|
|
||||||
# DELETE_OUTPUT_DIRECTORY = True
|
# DELETE_OUTPUT_DIRECTORY = True
|
||||||
|
|
||||||
# Following items are often useful when publishing
|
# Following items are often useful when publishing
|
||||||
|
|
|
@ -3,6 +3,7 @@ beautifulsoup4==4.6.0
|
||||||
blinker==1.3
|
blinker==1.3
|
||||||
docutils==0.12
|
docutils==0.12
|
||||||
feedgenerator==1.7
|
feedgenerator==1.7
|
||||||
|
ics==0.4
|
||||||
Jinja2==2.7.3
|
Jinja2==2.7.3
|
||||||
Markdown==2.6.1
|
Markdown==2.6.1
|
||||||
MarkupSafe==0.23
|
MarkupSafe==0.23
|
||||||
|
|
Loading…
Reference in a new issue