[Python-checkins] r41992 - sandbox/trunk/pycon sandbox/trunk/pycon/get.sh sandbox/trunk/pycon/parse-sched.py sandbox/trunk/pycon/talks.py
andrew.kuchling
python-checkins at python.org
Tue Jan 10 00:14:56 CET 2006
Author: andrew.kuchling
Date: Tue Jan 10 00:14:54 2006
New Revision: 41992
Added:
sandbox/trunk/pycon/
sandbox/trunk/pycon/get.sh
sandbox/trunk/pycon/parse-sched.py (contents, props changed)
sandbox/trunk/pycon/talks.py
Log:
Add PyCon scheduling script
Added: sandbox/trunk/pycon/get.sh
==============================================================================
--- (empty file)
+++ sandbox/trunk/pycon/get.sh Tue Jan 10 00:14:54 2006
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+wget -U "Mozilla/1.0 (GNU w-get)" -O - \
+ http://wiki.python.org/moin/PyCon2006/FinalSchedule?action=raw \
+ >FinalSchedule
+
Added: sandbox/trunk/pycon/parse-sched.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/pycon/parse-sched.py Tue Jan 10 00:14:54 2006
@@ -0,0 +1,230 @@
+#!/usr/bin/python
+
+# Reads a page with a wiki-format table
+
+# Basic data structure of dictionary:
+# {(year, month, day) -> [(time, duration, title)]
+
+import sys, optparse
+import re, string
+import pprint, cgi
+import datetime
+
+import talks
+
+date_pat = re.compile('^=\s+(\d{4})-(\d{2})-(\d{1,2})\s+.*\s+=')
+line_pat = re.compile('[|]{2}.*[|]{2}\s*$')
+talk_pat = re.compile('#(\d+)')
+
+def parse ():
+ lines = sys.stdin.readlines()
+ lines = map(string.strip, lines)
+ d = {}
+ date = None
+
+ for line in lines:
+ m = date_pat.match(line)
+ if m:
+ date = [int(value) for value in m.group(1,2,3)]
+ date = tuple(date)
+
+ m = line_pat.match(line)
+ if m:
+ if date is None:
+ print >>sys.stderr, "Table line before date header: %r" % line
+ else:
+ L = line.split('||')
+ L = map(string.strip, L)
+ assert L[0] == ''
+ assert L[-1] == ''
+ L = L[1:-1]
+ if len(L) != 4:
+ print >>sys.stderr, "Wrong number of fields in line: %r" % line
+ # Skip headers
+ elif L[0].lower() == 'room':
+ pass
+ else:
+ event_list = d.setdefault(date, [])
+ t = canonicalize_presentation(L)
+ event_list.append(t)
+
+ return d
+
+
+time_pat = re.compile('(\d+):(\d+)')
+
+def parse_time (S):
+ """(str): (int, int)
+ Parse a time into an (hour, minute) tuple.
+ """
+ m = time_pat.match(S)
+ assert m is not None
+ hour, min = int(m.group(1)), int(m.group(2))
+ return hour, min
+
+
+def canonicalize_presentation (L):
+ """Take a 4-item list for a talk and perform various
+ corrections to it.
+ """
+ hour, min = parse_time(L[1])
+ L[1] = '%02i:%02i' % (hour, min)
+ L[2] = int(L[2])
+ return tuple(L)
+
+
+
+#
+# HTML generation functions
+#
+
+def add_time (start_time, duration):
+ hour, min = parse_time(start_time)
+ while duration > 60:
+ hour += 1
+ duration -= 60
+ min += duration
+ while min >= 60:
+ hour += 1
+ min -= 60
+ return '%02i:%02i' % (hour, min)
+
+def find_next_time (time_list, end_time):
+ if len(time_list) == 0:
+ return 1
+ span = 0
+ while (time_list[span][0] < end_time and span < len(time_list)):
+ span += 1
+ return span+1
+
+
+def format_day (day, output):
+ # Figure out unique rooms
+ rooms = []
+ for room, time, duration, title in day:
+ # XXX change to use regex pattern
+ if room.startswith('-'):
+ continue
+ if room not in rooms:
+ rooms.append(room)
+ rooms.sort()
+
+ # Move Bent Tree to be last
+ if 'Bent Tree' in rooms:
+ rooms.remove('Bent Tree')
+ rooms.append('Bent Tree')
+
+ # Print room header
+ print >>output, '''<table width="80%%" border=3>
+<col width="75"><col span=%i width="*">
+''' % len(rooms)
+
+ print >>output, "<thead>"
+ print >>output, '<tr><td></td>',
+ for room in rooms:
+ print >>output, '<th>%s</th>' % room,
+ print >>output, '</tr>'
+ print >>output, "</thead>"
+
+ # Sort list
+ time_dict = {}
+ for room, time, duration, title in day:
+ d = time_dict.setdefault(time, {})
+ d[room] = (duration, title)
+ time_list = time_dict.items()
+ time_list.sort()
+
+ active = {}
+ print '<tbody>'
+ while len(time_list) > 0:
+ time, room_dict = time_list.pop(0)
+ print >>output, '<tr>',
+ for act_room, end_time in active.items():
+ if end_time <= time:
+ del active[act_room]
+ print >>output, '<th>%s</th>' % time,
+ plenary = (len(room_dict) == 1)
+ if plenary:
+ # Plenary session of some sort
+ duration, title = room_dict.values()[0]
+ colspan = len(rooms)
+ print >>output, '<td align="center" colspan=%i>%s</td>' % (colspan, title),
+ print >>output, '</tr>'
+ continue
+
+ for room in rooms:
+ # Room still occupied, so skip it
+ if room in active:
+ continue
+
+ # New room
+ t = room_dict.get(room)
+ if t is None:
+ print >>output, '<td rowspan=1> </td>',
+ else:
+ duration, title = t
+ end_time = add_time(time, duration)
+ active[room] = end_time
+ rowspan = find_next_time(time_list, end_time)
+
+ # Turn talk numbers into a link with a title
+ m = talk_pat.match(title)
+ if m is not None:
+ talk_num = int(m.group(1))
+ title = talks.get_title(talk_num)
+ else:
+ title = cgi.escape(title)
+
+ print >>output, '<td rowspan="%i">' % rowspan,
+ print >>output, title,
+ print >>output, '</td>',
+
+ print >>output, '</tr>'
+
+ print '</tbody>'
+ print >>output, '</table>'
+
+
+def output_html (d, output):
+ L = d.items() ; L.sort()
+
+ for (y, m, day), day_data in L:
+ date = datetime.date(y, m, day)
+ print >>output, date.strftime('<h3>%A, %B %d %Y</h3>')
+ format_day(day_data, output)
+
+
+def main ():
+ parser = optparse.OptionParser(usage="usage: %prog [options] < final-schedule")
+ parser.add_option('--format',
+ type='choice',
+ choices=['pickle', 'python', 'print', 'html'],
+ default='print',
+ action="store", dest="format",
+ help = "Select output format")
+ options, args = parser.parse_args()
+
+ d = parse()
+ fmt = options.format
+ if fmt == 'print':
+ pprint.pprint(d)
+ elif fmt == 'python':
+ print 'schedule =',
+ pprint.pprint(d)
+ elif fmt == 'pickle':
+ import cPickle
+ cPickle.dump(d, sys.stdout)
+ elif fmt == 'html':
+ output_html(d, sys.stdout)
+ else:
+ print >>sys.stderr, "Unknown format %r" % fmt
+ sys.exit(1)
+
+if __name__ == '__main__':
+ main()
+
+
+
+
+
+
Added: sandbox/trunk/pycon/talks.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/pycon/talks.py Tue Jan 10 00:14:54 2006
@@ -0,0 +1,70 @@
+
+talk_dict = {
+ 1: 'Introduction to Pyparsing: An Object-oriented Easy-to-Use Toolkit for Building Recursive Descent Parsers',
+ 2: 'Agile Documentation: using tests as documentation',
+ 4: 'An Interactive Adventure Game Engine Built Using Pyparsing',
+ 5: 'Desktop Application Programming With PyGTK and Glade',
+ 6: 'Vertebral Fracture Analysis',
+ 8: 'Scripting .NET with IronPython',
+ 11: 'Effective AJAX with TurboGears',
+ 12: 'Stackless Python in EVE Online',
+ 13: "Cuaima MetaInstaller. New tool for managing System's Installations.",
+ 14: 'Osh: An Open-Source Python-Based Object-Oriented Shell',
+ 16: 'Decimal for beginners',
+ 17: 'Large-scale, cross-platform synchronization using embedded python',
+ 18: 'Internet Access via Anti-Virus Policy Enforcement Software and Messaging Service',
+ 19: 'State-of-the-art Python IDEs',
+ 21: 'Developing an Internationalized Application in Python: Chandler a case study',
+ 23: 'Processing XML with ElementTree',
+ 24: 'What is Nabu?',
+ 25: 'TurboGears Tutorial',
+ 26: 'Packaging Programs with py2exe',
+ 29: 'Python in Business : Thyme, a business-oriented Python development framework.',
+ 30: 'Python at Home : In Control',
+ 31: 'Extending the life of CVS with Python',
+ 34: 'The State of Dabo',
+ 35: 'PyPy architecture session',
+ 36: 'Python Can Survive In The Enterprise',
+ 37: 'Beyond Scripting: Using Python to create a medical information system with graphical template and database schema design',
+ 38: 'PyPy -- where we are now',
+ 39: 'The Rest Of The Web Stack',
+ 40: 'SAM: Transforming a commandline tool to Web 3000 (c)',
+ 41: 'Teaching Python - Anecdotes from the Field',
+ 45: 'Implementation of the Python Bytecode Compiler',
+ 46: 'Making Apples from Applesauce: The Evolution of cvs2svn',
+ 47: 'Agile open-source methods, Businesses and EU Funding',
+ 48: 'Extensible Desktop Applications: Abusing the Zope 3 Project',
+ 50: 'Using Django to supercharge Web development',
+ 52: 'New Tools for Testing Web Applications with Python',
+ 53: 'vobject - An iCalendar Library',
+ 54: 'Zanshin: Zen and the Art of Network Client Programming',
+ 55: 'IronPython Implementation',
+ 56: 'Python tools for regional hydrologic modeling in South Florida',
+ 57: 'pysense: Humanoid Robots, a Wearable System, and Python',
+ 58: 'Introduction to Zope Application Development',
+ 59: 'Introduction to CMF Application Development',
+ 60: 'Mission-Critical Python and the Brave New Web',
+ 62: 'Docutils Developers Tutorial: Architecture, Extending, and Embedding',
+ 63: 'Django tutorial',
+ 64: 'Creating Presentations With Docutils and S5',
+ 65: 'Understanding Unicode',
+ 66: 'Building Pluggable Software with Eggs',
+ 67: 'Gamma: An Atom Publishing Protocol implementation for Zope 3',
+ 69: 'Python in Your Pocket: Python for Series 60',
+ 70: 'Simplifying Red-Black Trees',
+ 71: 'entransit, a content deployment system',
+ 72: 'bazaar-ng distributed version control',
+ 73: 'State of Zope',
+ }
+
+import cgi
+
+def get_title (num):
+ title = talk_dict.get(num)
+ if title is None:
+ return '#' + str(num)
+
+ url = 'http://wiki.python.org/moin/PyCon2006/Talks#' + str(num)
+ title = cgi.escape(title)
+ return '<a href="%s">%s</a>' % (url, title)
+
More information about the Python-checkins
mailing list