[code] orari dopo le 24

che mufhd0 ce la manni bona
se si rompono cose, QUESTO è il commit da revertare

madonna la monnezza che ho fatto
This commit is contained in:
boyska 2018-07-06 17:00:32 +02:00
parent f3f33bae33
commit eb3754ce0b
2 changed files with 132 additions and 81 deletions

View file

@ -100,6 +100,25 @@ def get_global_data():
return data return data
def _get_time_shift(timestring):
''' Il problema che abbiamo è che vogliamo dire che le 2 di notte del sabato sono in realtà "parte" del
venerdì. Per farlo accettiamo orari che superano le 24, ad esempio 25.30 vuol dire 1.30.
Questa funzione ritorna una timedelta in base alla stringa passata
'''
timeparts = re.findall(r'\d+', timestring)
if not timeparts or len(timeparts) > 2:
raise ValueError("Malformed time %s" % timestring)
timeparts += [0,0] # "padding" per essere sicuro ci siano anche [1] e [2]
duration = datetime.timedelta(hours=int(timeparts[0]),
minutes=int(timeparts[1]),
seconds=int(timeparts[2]))
if duration.total_seconds() > 3600 * 31 or duration.total_seconds() < 0:
raise ValueError("Sforamento eccessivo: %d" % duration.hours)
return duration
@memoize @memoize
def get_talk_data(talkname): def get_talk_data(talkname):
fname = os.path.join(pelican.settings['TALKS_PATH'], talkname, 'meta.yaml') fname = os.path.join(pelican.settings['TALKS_PATH'], talkname, 'meta.yaml')
@ -155,15 +174,18 @@ def get_talk_data(talkname):
else: else:
data['day'] = get_global_data()['startdate'] + \ data['day'] = get_global_data()['startdate'] + \
datetime.timedelta(days=data['day']) datetime.timedelta(days=data['day'])
timeparts = re.findall(r'\d+', str(data['time'])) try:
if 4 > len(timeparts) > 0: shift = _get_time_shift(str(data['time']))
timeparts = [int(p) for p in timeparts] except ValueError:
data['time'] = datetime.datetime.combine(
data['day'], datetime.time(*timeparts))
data['time'] = data['time'].replace(
tzinfo=dateutil.tz.gettz('Europe/Rome'))
else:
logging.error("Talk <%s> has malformed `time`", talkname) logging.error("Talk <%s> has malformed `time`", talkname)
data['delta'] = shift
data['time'] = datetime.datetime.combine(
data['day'], datetime.time(0,0,0))
data['time'] += shift
data['time'] = data['time'].replace(tzinfo=dateutil.tz.gettz('Europe/Rome'))
data['id'] = talkname data['id'] = talkname
resdir = os.path.join(pelican.settings['TALKS_PATH'], talkname, resdir = os.path.join(pelican.settings['TALKS_PATH'], talkname,
pelican.settings['TALKS_ATTACHMENT_PATH']) pelican.settings['TALKS_ATTACHMENT_PATH'])
@ -282,6 +304,27 @@ class TalkDirective(Directive):
] ]
def _delta_to_position(delta):
gridstep = pelican.settings['TALKS_GRID_STEP']
sec = delta.total_seconds() // gridstep * gridstep
return int('%2d%02d' % (sec // 3600, (sec % 3600) // 60))
def _delta_inc_position(delta, i):
gridstep = pelican.settings['TALKS_GRID_STEP']
delta = delta + datetime.timedelta(minutes=i*gridstep)
sec = delta.total_seconds() // gridstep * gridstep
return int('%2d%02d' % (sec // 3600, (sec % 3600) // 60))
def _approx_timestr(timestr):
gridstep = pelican.settings['TALKS_GRID_STEP']
t = str(timestr)
minutes = int(t[-2:])
hours = t[:-2]
minutes = minutes // gridstep * gridstep
return int('%s%02d' % (hours, minutes))
class TalkGridDirective(Directive): class TalkGridDirective(Directive):
'''A complete grid''' '''A complete grid'''
final_argument_whitespace = True final_argument_whitespace = True
@ -291,79 +334,87 @@ class TalkGridDirective(Directive):
} }
def run(self): def run(self):
lang = self.options.get('lang', 'C') try:
tmpl = jinja_env().get_template('grid.html') lang = self.options.get('lang', 'C')
output = [] tmpl = jinja_env().get_template('grid.html')
days = unique_attr(all_talks(), 'day') output = []
gridstep = pelican.settings['TALKS_GRID_STEP'] days = unique_attr(all_talks(), 'day')
for day in sorted(days): gridstep = pelican.settings['TALKS_GRID_STEP']
talks = {talk['id'] for talk in all_talks() for day in sorted(days):
if talk.get('day', None) == day talks = {talk['id'] for talk in all_talks()
and 'time' in talk if talk.get('day', None) == day
and 'room' in talk} and 'time' in talk
if not talks: and 'room' in talk}
continue if not talks:
talks = [get_talk_data(t) for t in talks] continue
rooms = set() talks = [get_talk_data(t) for t in talks]
for t in talks: rooms = set()
if type(t['room']) is list: for t in talks:
for r in t['room']: if type(t['room']) is list:
rooms.add(r) for r in t['room']:
else: rooms.add(r)
rooms.add(t['room']) else:
# TODO: ordina in base a qualcosa nel meta.yaml globale rooms.add(t['room'])
rooms = list(sorted(rooms)) # TODO: ordina in base a qualcosa nel meta.yaml globale
rooms = list(sorted(rooms))
# room=* is not a real room. # room=* is not a real room.
# Remove it unless that day only has special rooms # Remove it unless that day only has special rooms
if '*' in rooms and len(rooms) > 1: if '*' in rooms and len(rooms) > 1:
del rooms[rooms.index('*')] del rooms[rooms.index('*')]
mintime = min({talk['time'].hour * 60 + mintimedelta = min({talk['delta'] for talk in talks})
talk['time'].minute maxtimedelta = max({talk['delta'] + datetime.timedelta(minutes=talk['duration']) for talk in talks})
for talk in talks}) // gridstep * gridstep mintime = _delta_to_position(mintimedelta)
maxtime = max({talk['time'].hour * 60 + maxtime = _delta_to_position(maxtimedelta)
talk['time'].minute + times = {}
talk['duration']
for talk in talks})
times = {}
for t in range(mintime, maxtime, gridstep): t = mintimedelta
times[t] = [None] * len(rooms) while t <= maxtimedelta:
for talk in sorted(talks, key=lambda x: x['time']): times[_delta_to_position(t)] = [None] * len(rooms)
talktime = talk['time'].hour * 60 + talk['time'].minute t += datetime.timedelta(minutes=gridstep)
position = talktime // gridstep * gridstep # round print(list(times.keys()))
assert position in times for talk in sorted(talks, key=lambda x: x['delta']):
if talk['room'] == '*': talktime = _delta_to_position(talk['delta'])
roomnums = range(len(rooms)) position = _approx_timestr(talktime)
elif type(talk['room']) is list: assert position in times, 'pos=%d,time=%d' % (position, talktime)
roomnums = [rooms.index(r) for r in talk['room']] if talk['room'] == '*':
else: roomnums = range(len(rooms))
roomnums = [rooms.index(talk['room'])] elif type(talk['room']) is list:
for roomnum in roomnums: roomnums = [rooms.index(r) for r in talk['room']]
if times[position][roomnum] is not None: else:
logging.error("Talk %s and %s overlap! (room %s)", roomnums = [rooms.index(talk['room'])]
times[position][roomnum]['id'], for roomnum in roomnums:
talk['id'], if times[position][roomnum] is not None:
rooms[roomnum] logging.error("Talk %s and %s overlap! (room %s)",
) times[position][roomnum]['id'],
continue talk['id'],
times[position][roomnum] = copy(talk) rooms[roomnum]
times[position][roomnum]['skip'] = False )
for i in range(1, talk['duration'] // gridstep): continue
times[position + i*gridstep][roomnum] = copy(talk) times[position][roomnum] = copy(talk)
times[position + i*gridstep][roomnum]['skip'] = True times[position][roomnum]['skip'] = False
for i in range(1, talk['duration'] // gridstep):
p = _approx_timestr(_delta_inc_position(talk['delta'], i))
times[p][roomnum] = copy(talk)
times[p][roomnum]['skip'] = True
render = tmpl.render(times=times,
rooms=rooms, render = tmpl.render(times=times,
mintime=mintime, maxtime=maxtime, rooms=rooms,
timestep=gridstep, mintime=mintime, maxtime=maxtime,
lang=lang, timestep=gridstep,
) lang=lang,
output.append(nodes.raw( )
'', u'<h4>%s</h4>' % format_date(day, format='full', output.append(nodes.raw(
locale=lang), '', u'<h4>%s</h4>' % format_date(day, format='full',
format='html')) locale=lang),
output.append(nodes.raw('', render, format='html')) format='html'))
output.append(nodes.raw('', render, format='html'))
except:
logging.exception("Error on talk grid")
import traceback
traceback.print_exc()
return []
return output return output

View file

@ -8,10 +8,10 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for time in range (mintime, maxtime, timestep) %} {% for time in times %}
<tr> <tr>
<td>{{time//60}}:{{ "%02d" % (time % 60)}}</td> <td>{{time}}</td>
{% for talk in times[time / timestep * timestep] %} {% for talk in times[time] %}
{% if not loop.first and talk.room == '*' %} {% if not loop.first and talk.room == '*' %}
{# skip: covered by colspan #} {# skip: covered by colspan #}
{% elif talk == None %} {% elif talk == None %}