[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>&nbsp;</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