1
0
Fork 0

Merge branch 'talk-plugins'

This commit is contained in:
dbz 2017-05-17 13:22:21 +02:00
commit 21da9e949a
10 changed files with 322 additions and 11 deletions

View file

@ -19,3 +19,15 @@ firefox output/index.html
Also, `make help` is your friend.
**Morte ai nemici dell'UTF-8**
Aggiungere un talk
--------------------
```sh
cp -r talks/_talk_example/ talks/MIOTALK/
vim talks/MIOTALK/meta.yaml
```
Quindi rifai `make publish` come spiegato prima: l'output ti informa di eventuali errori nei campi o
sovrapposizioni con altri talk, leggilo!

View file

@ -17,6 +17,8 @@ appreciated!
Hackmeeting (still) hasn't a proper translation system, but you can
find a bunch of people to ask to do translations when you need it.
.. talkgrid::
.. talklist::

View file

@ -12,5 +12,7 @@ Leggi l'`invito a presentare dei contenuti
<http://lists.autistici.org/message/20170502.165954.0e930b75.en.html>`_, fatti coraggio e proponi il tuo contenuto in `mailing
list <{filename}contatti.rst>`_
.. talkgrid::
.. talklist::

View file

@ -10,7 +10,10 @@ import logging
import re
import datetime
import shutil
import time
from copy import copy
import markdown
from docutils import nodes
from docutils.parsers.rst import directives, Directive
@ -19,6 +22,9 @@ import jinja2
TALKS_PATH = 'talks'
TALK_ATTACHMENT_PATH = 'res'
TALK_ICS = 'schedule.ics'
GRID_STEP = 15
def memoize(function):
@ -44,6 +50,34 @@ def get_talk_names():
]
def all_talks():
return [get_talk_data(tn) for tn in get_talk_names()]
def unique_attr(iterable, attr):
return {x[attr] for x in iterable
if attr in x}
@memoize
def get_global_data():
fname = os.path.join(TALKS_PATH, 'meta.yaml')
if not os.path.isfile(fname):
return None
with io.open(fname, encoding='utf8') as buf:
try:
data = yaml.load(buf)
except Exception:
logging.exception("Syntax error reading %s; skipping", fname)
return None
if data is None:
return None
if 'startdate' not in data:
logging.error("Missing startdate in global data")
data['startdate'] = datetime.datetime.now()
return data
@memoize
def get_talk_data(talkname):
fname = os.path.join(TALKS_PATH, talkname, 'meta.yaml')
@ -68,19 +102,32 @@ def get_talk_data(talkname):
.format(talkname))
data['duration'] = 50
data['duration'] = int(data['duration'])
if data['duration'] < GRID_STEP:
logging.info("Talk <{}> lasts only {} minutes; changing to {}"
.format(talkname, data['duration'], GRID_STEP))
data['duration'] = GRID_STEP
if 'links' not in data or not data['links']:
data['links'] = []
if 'contacts' not in data or not data['contacts']:
data['contacts'] = []
if 'needs' not in data or not data['needs']:
data['needs'] = []
if 'room' not in data:
logging.warn("Talk <{}> has no `room` field".format(talkname))
if 'time' not in data or 'day' not in data:
logging.warn("Talk <{}> has no `time` or `day`".format(talkname))
if 'time' in data:
if 'day' in data:
data['day'] = get_global_data()['startdate'] + datetime.timedelta(days=data['day'])
if 'time' in data and 'day' in data:
timeparts = re.findall(r'\d+', str(data['time']))
if 4 > len(timeparts) > 0:
timeparts = [int(p) for p in timeparts]
data['time'] = datetime.time(*timeparts)
data['time'] = datetime.datetime.combine(data['day'],
datetime.time(*timeparts))
else:
logging.error("Talk <{}> has malformed `time`".format(talkname))
data['id'] = talkname
resdir = os.path.join(TALKS_PATH, talkname, 'res')
resdir = os.path.join(TALKS_PATH, talkname, TALK_ATTACHMENT_PATH)
if os.path.isdir(resdir) and os.listdir(resdir):
data['resources'] = resdir
return data
@ -90,6 +137,9 @@ jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.join(TALKS_PATH, '_templates')),
autoescape=True,
)
jinja_env.filters['markdown'] = lambda text: \
jinja2.Markup(markdown.Markdown(extensions=['meta']).
convert(text))
class TalkListDirective(Directive):
@ -123,7 +173,94 @@ class TalkDirective(Directive):
format='html')
]
# TODO: TalkGridDirective (griglia completa)
class TalkGridDirective(Directive):
'''A complete grid'''
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = True
has_content = True
def run(self):
tmpl = jinja_env.get_template('grid.html')
output = []
days = unique_attr(all_talks(), 'day')
for day in sorted(days):
talks = {talk['id'] for talk in all_talks()
if talk.get('day', None) == day
and 'time' in talk
and 'room' in talk}
if not talks:
continue
talks = [get_talk_data(t) for t in talks]
rooms = tuple(sorted(unique_attr(talks, 'room')))
mintime = min({talk['time'].hour * 60 +
talk['time'].minute
for talk in talks}) // GRID_STEP * GRID_STEP
maxtime = max({talk['time'].hour * 60 +
talk['time'].minute +
talk['duration']
for talk in talks})
times = {}
for t in range(mintime, maxtime, GRID_STEP):
times[t] = [None] * len(rooms)
for talk in sorted(talks, key=lambda x: x['time']):
talktime = talk['time'].hour * 60 + talk['time'].minute
position = talktime // GRID_STEP * GRID_STEP # round
assert position in times
roomnum = rooms.index(talk['room'])
if times[position][roomnum] is not None:
logging.error("Talk {} and {} overlap! "
.format(times[position][roomnum]['id'],
talk['id']))
continue
times[position][roomnum] = copy(talk)
times[position][roomnum]['skip'] = False
for i in range(1, talk['duration'] // GRID_STEP):
times[position + i*GRID_STEP][roomnum] = copy(talk)
times[position + i*GRID_STEP][roomnum]['skip'] = True
render = tmpl.render(times=times,
rooms=rooms,
mintime=mintime, maxtime=maxtime,
timestep=GRID_STEP,
)
output.append(nodes.raw('', u'<h4>%s</h4>' %
day.strftime('%A %d').decode('utf8').title(),
format='html'))
output.append(nodes.raw('', render, format='html'))
return output
def talks_to_ics():
content = 'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:pelican\n'
for t in all_talks():
content += talk_to_ics(t)
content += 'END:VCALENDAR\n'
return content
def talk_to_ics(talk):
if 'time' not in talk:
return ''
start = talk['time']
end = start + datetime.timedelta(minutes=talk['duration'])
content = 'BEGIN:VEVENT\n'
content += "UID:%s@%d.hackmeeting.org\n" % (talk['id'], talk['day'].year)
content += "SUMMARY:%s\n" % talk['title']
content += "DTSTAMP:%s\n" % time.strftime('%Y%m%dT%H%M%SZ',
time.gmtime(float(start.strftime('%s'))))
content += "DTSTART:%s\n" % time.strftime('%Y%m%dT%H%M%SZ',
time.gmtime(float(
start.strftime('%s'))))
content += "DTEND:%s\n" % time.strftime('%Y%m%dT%H%M%SZ',
time.gmtime(float(
end.strftime('%s'))))
content += "LOCATION:%s\n" % talk['room']
content += 'END:VEVENT\n'
return content
class TalksGenerator(generators.Generator):
@ -138,11 +275,13 @@ class TalksGenerator(generators.Generator):
def generate_output(self, writer=None):
for talkname in self.talks:
if 'resources' in self.talks[talkname]:
outdir = os.path.join(self.output_path, 'talks', talkname,
'res')
outdir = os.path.join(self.output_path, TALKS_PATH, talkname,
TALK_ATTACHMENT_PATH)
if os.path.isdir(outdir):
shutil.rmtree(outdir)
shutil.copytree(self.talks[talkname]['resources'], outdir)
with open(os.path.join(self.output_path, TALK_ICS), 'w') as buf:
buf.write(talks_to_ics())
def add_talks_option_defaults(pelican):
@ -167,3 +306,4 @@ else:
signals.initialized.connect(add_talks_option_defaults)
directives.register_directive('talklist', TalkListDirective)
directives.register_directive('talk', TalkDirective)
directives.register_directive('talkgrid', TalkGridDirective)

View file

@ -1,16 +1,25 @@
# File di esempio; copialo e cambialo
title: Il titolo del talk
title: "Il titolo del talk"
text: |
Descrizione del talk divisa in molte righe
Puoi scrivere quanto vuoi
ma devi rimanere indentato
Puoi anche mettere delle spaziature.
# Se ancora non è stata assegnata una stanza al talk, lasciala vuota. Non usare un valore tipo "qualunque" o
# Se ancora non è stata assegnata una stanza al talk, commentala. Non usare un valore tipo "qualunque" o
# cose del genere, che ci si incasina tutto
room: antani
# duration è la durata in minuti del talk
# duration: 50
# Ci vanno le virgolette intorno! altrimenti 17.30 viene interpretato come un numero decimale
time: "17.30"
# day è il giorno in cui avverrà il talk. Finché non decommenti il talk non sarà schedulato
# 0=giovedì, 1=venerdì, 2=sabato, 3=domenica
# day: 0
tags:
- tante
- cose
@ -20,7 +29,7 @@ links:
- https://git.lattuga.net/asd/foo
# mail dovrebbe contenere un link alla mail con cui il talk è stato proposto
# così si può sapere chi contattare e se c'è stata una discussione
mail: blabla
mail: "blabla"
# Devi usare UTF-8, non t'inventare scuse, sappiamo ndo abiti
# vim: set fileencoding=utf-8:

View file

@ -0,0 +1,39 @@
<style>
.talk-grid {
table-layout: fixed;
width: 100%;
}
.talk-grid > thead th:first-child {
max-width: 5em;
}
td.talk {
border: 1px solid;
}
</style>
<table class="talk-grid">
<thead>
<tr>
<th></th>
{% for room in rooms %}
<th>{{room}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for time in range (mintime, maxtime, timestep) %}
<tr>
<td>{{time//60}}:{{ "%02d" % (time % 60)}}</td>
{% for talk in times[time / timestep * timestep] %}
{% if talk == None %}
<td></td>
{% elif talk != 'skip' %}
<td class="talk" rowspan="{{talk.duration // timestep}}">
<a href="#talk-{{talk.id}}"> {{talk.title}}</a>
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{# vim: set ft=jinja: #}

View file

@ -10,15 +10,25 @@
{% if room is defined %}
<p>Stanza {{ room }}</p>
{% endif %}
{% if needs: %}
<div class="talk-needs">
<strong>Materiale necessario:</strong>
{{needs|join(", ")}}
</div>
{% endif %}
</div>
<div class="talk-description">{{text}}</div>
<div class="talk-description">{{text | markdown}}
{% if contacts: %}
<p class="contacts">A cura di {{contacts|join(', ')}}</p>
{% endif %}
</div>
{% if links is defined or resources is defined or mail is defined %}
<div class="talk-resources">
<h4>Link utili:</h4>
<ul>
{% if links is defined: %}
{% for link in links %}
<li>{{link}}</li>
<li>{{link|urlize}}</li>
{% endfor %}
{% endif %}
{% if resources is defined: %}

48
talks/cable/meta.yaml Normal file
View file

@ -0,0 +1,48 @@
# File di esempio; copialo e cambialo
title: "Cable: una rete federata di server Signal"
text: |
Signal è riconosciuto come uno degli strumenti più validi per quanto
riguarda la messaggistica privata, avendo tutte le caratteristiche
desiderabili a livello di protocollo e algoritmi e un'usabilità pari ai
più diffusi prodotti commerciali. Si tratta purtroppo di un servizio
centralizzato, i cui server sono interamente gestiti da una specifica
entità.
I software che implementano il servizio (server e client) supportano
però la federazione, è quindi possibile costruire una rete
decentralizzata e indipendente. Il talk vuole esporre il lavoro che
abbiamo fatto in questo senso in HacklabBo.
Programma di massima:
0. Il senso di questo lavoro
1. Infrastruttura del servizio Signal
2. Liberazione di client e server da servizi commerciali
3. Federazione di due server
4. Call for federation
5. Discussione
# Se ancora non è stata assegnata una stanza al talk, commentala. Non usare un valore tipo "qualunque" o
# cose del genere, che ci si incasina tutto
# room: ""
# Ci vanno le virgolette intorno! altrimenti 17.30 viene interpretato come un numero decimale
duration: 90
# time: "17.30"
# day: 1
tags:
- comunicazione
- servizi autogestiti
# Devono essere dei link validi!
links:
- https://github.com/WhisperSystems/Signal-Server/wiki/API-Protocol
# mail dovrebbe contenere un link alla mail con cui il talk è stato proposto
# così si può sapere chi contattare e se c'è stata una discussione
mail: http://lists.autistici.org/message/20170515.205020.ba238125.en.html
needs:
- proiettore
contacts:
- torn
- gine
# Devi usare UTF-8, non t'inventare scuse, sappiamo ndo abiti
# vim: set fileencoding=utf-8:

View file

@ -0,0 +1,48 @@
# File di esempio; copialo e cambialo
title: "Copia forense, un'esperienza da tecnico di parte e il problema del pranzo"
text: |
Ripercorriamo la prima esperienza sul campo di hacklabbo/ams da
consulenti tecnici di parte per una copia forense.
Analizzeremo assieme il sequestro, la nomina e le operazioni compiute.
Parleremo di:
* imballi, sigilli e come devo essere maneggiati i dispositivi dal CTU
* quale materiale il CTP deve portarsi il giorno della copia
* il problema del pranzo
* una piccola panoramica su Deft Zero
* i formati di acquisizione
* Ufed Cellbrite Touch, per l'estrapolazione dei dati dal telefono
* la parti del verbale e cosa far scrivere
* curiose anomalie
* la figura del CTP, serve? Non serve? Cosa possiamo fare come hacklab
per i/le compagni/e inguiati/e?
needs:
- proiettore
# Se ancora non è stata assegnata una stanza al talk, commentala. Non usare un valore tipo "qualunque" o
# cose del genere, che ci si incasina tutto
# room: antani
# duration è la durata in minuti del talk
duration: 60
# Ci vanno le virgolette intorno! altrimenti 17.30 viene interpretato come un numero decimale
# time: "17.30"
# day è il giorno in cui avverrà il talk. Finché non decommenti il talk non sarà schedulato
# 0=giovedì, 1=venerdì, 2=sabato, 3=domenica
# day: 0
tags:
- legale
# Devono essere dei link validi!
links:
# mail dovrebbe contenere un link alla mail con cui il talk è stato proposto
# così si può sapere chi contattare e se c'è stata una discussione
mail: "http://lists.autistici.org/message/20170516.235536.3e0103ea.en.html"
contacts:
- jops
- gine
# Devi usare UTF-8, non t'inventare scuse, sappiamo ndo abiti
# vim: set fileencoding=utf-8:

1
talks/meta.yaml Normal file
View file

@ -0,0 +1 @@
startdate: 2017-06-15