[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
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
def get_talk_data(talkname):
fname = os.path.join(pelican.settings['TALKS_PATH'], talkname, 'meta.yaml')
@ -155,15 +174,18 @@ def get_talk_data(talkname):
else:
data['day'] = get_global_data()['startdate'] + \
datetime.timedelta(days=data['day'])
timeparts = re.findall(r'\d+', str(data['time']))
if 4 > len(timeparts) > 0:
timeparts = [int(p) for p in timeparts]
data['time'] = datetime.datetime.combine(
data['day'], datetime.time(*timeparts))
data['time'] = data['time'].replace(
tzinfo=dateutil.tz.gettz('Europe/Rome'))
else:
try:
shift = _get_time_shift(str(data['time']))
except ValueError:
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
resdir = os.path.join(pelican.settings['TALKS_PATH'], talkname,
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):
'''A complete grid'''
final_argument_whitespace = True
@ -291,79 +334,87 @@ class TalkGridDirective(Directive):
}
def run(self):
lang = self.options.get('lang', 'C')
tmpl = jinja_env().get_template('grid.html')
output = []
days = unique_attr(all_talks(), 'day')
gridstep = pelican.settings['TALKS_GRID_STEP']
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 = set()
for t in talks:
if type(t['room']) is list:
for r in t['room']:
rooms.add(r)
else:
rooms.add(t['room'])
# TODO: ordina in base a qualcosa nel meta.yaml globale
rooms = list(sorted(rooms))
try:
lang = self.options.get('lang', 'C')
tmpl = jinja_env().get_template('grid.html')
output = []
days = unique_attr(all_talks(), 'day')
gridstep = pelican.settings['TALKS_GRID_STEP']
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 = set()
for t in talks:
if type(t['room']) is list:
for r in t['room']:
rooms.add(r)
else:
rooms.add(t['room'])
# TODO: ordina in base a qualcosa nel meta.yaml globale
rooms = list(sorted(rooms))
# room=* is not a real room.
# Remove it unless that day only has special rooms
if '*' in rooms and len(rooms) > 1:
del rooms[rooms.index('*')]
mintime = min({talk['time'].hour * 60 +
talk['time'].minute
for talk in talks}) // gridstep * gridstep
maxtime = max({talk['time'].hour * 60 +
talk['time'].minute +
talk['duration']
for talk in talks})
times = {}
# room=* is not a real room.
# Remove it unless that day only has special rooms
if '*' in rooms and len(rooms) > 1:
del rooms[rooms.index('*')]
mintimedelta = min({talk['delta'] for talk in talks})
maxtimedelta = max({talk['delta'] + datetime.timedelta(minutes=talk['duration']) for talk in talks})
mintime = _delta_to_position(mintimedelta)
maxtime = _delta_to_position(maxtimedelta)
times = {}
for t in range(mintime, maxtime, gridstep):
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 // gridstep * gridstep # round
assert position in times
if talk['room'] == '*':
roomnums = range(len(rooms))
elif type(talk['room']) is list:
roomnums = [rooms.index(r) for r in talk['room']]
else:
roomnums = [rooms.index(talk['room'])]
for roomnum in roomnums:
if times[position][roomnum] is not None:
logging.error("Talk %s and %s overlap! (room %s)",
times[position][roomnum]['id'],
talk['id'],
rooms[roomnum]
)
continue
times[position][roomnum] = copy(talk)
times[position][roomnum]['skip'] = False
for i in range(1, talk['duration'] // gridstep):
times[position + i*gridstep][roomnum] = copy(talk)
times[position + i*gridstep][roomnum]['skip'] = True
t = mintimedelta
while t <= maxtimedelta:
times[_delta_to_position(t)] = [None] * len(rooms)
t += datetime.timedelta(minutes=gridstep)
print(list(times.keys()))
for talk in sorted(talks, key=lambda x: x['delta']):
talktime = _delta_to_position(talk['delta'])
position = _approx_timestr(talktime)
assert position in times, 'pos=%d,time=%d' % (position, talktime)
if talk['room'] == '*':
roomnums = range(len(rooms))
elif type(talk['room']) is list:
roomnums = [rooms.index(r) for r in talk['room']]
else:
roomnums = [rooms.index(talk['room'])]
for roomnum in roomnums:
if times[position][roomnum] is not None:
logging.error("Talk %s and %s overlap! (room %s)",
times[position][roomnum]['id'],
talk['id'],
rooms[roomnum]
)
continue
times[position][roomnum] = copy(talk)
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,
mintime=mintime, maxtime=maxtime,
timestep=gridstep,
lang=lang,
)
output.append(nodes.raw(
'', u'<h4>%s</h4>' % format_date(day, format='full',
locale=lang),
format='html'))
output.append(nodes.raw('', render, format='html'))
render = tmpl.render(times=times,
rooms=rooms,
mintime=mintime, maxtime=maxtime,
timestep=gridstep,
lang=lang,
)
output.append(nodes.raw(
'', u'<h4>%s</h4>' % format_date(day, format='full',
locale=lang),
format='html'))
output.append(nodes.raw('', render, format='html'))
except:
logging.exception("Error on talk grid")
import traceback
traceback.print_exc()
return []
return output

View file

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