From eb3754ce0bed511f30ed0328a73d6c0e972679d5 Mon Sep 17 00:00:00 2001 From: boyska Date: Fri, 6 Jul 2018 17:00:32 +0200 Subject: [PATCH] [code] orari dopo le 24 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit che mufhd0 ce la manni bona se si rompono cose, QUESTO è il commit da revertare madonna la monnezza che ho fatto --- plugins/talks.py | 207 +++++++++++++++++++++++-------------- talks/_templates/grid.html | 6 +- 2 files changed, 132 insertions(+), 81 deletions(-) diff --git a/plugins/talks.py b/plugins/talks.py index c1217cc..fc5aa5d 100644 --- a/plugins/talks.py +++ b/plugins/talks.py @@ -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'

%s

' % 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'

%s

' % 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 diff --git a/talks/_templates/grid.html b/talks/_templates/grid.html index 457d994..fa2e204 100644 --- a/talks/_templates/grid.html +++ b/talks/_templates/grid.html @@ -8,10 +8,10 @@ - {% for time in range (mintime, maxtime, timestep) %} + {% for time in times %} - {{time//60}}:{{ "%02d" % (time % 60)}} - {% for talk in times[time / timestep * timestep] %} + {{time}} + {% for talk in times[time] %} {% if not loop.first and talk.room == '*' %} {# skip: covered by colspan #} {% elif talk == None %}