<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.friendsofbedlam.co.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Xander</id>
	<title>EUTC Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.friendsofbedlam.co.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Xander"/>
	<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php/Special:Contributions/Xander"/>
	<updated>2026-07-14T21:42:09Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=User:Xander&amp;diff=3879</id>
		<title>User:Xander</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=User:Xander&amp;diff=3879"/>
		<updated>2009-09-20T18:25:02Z</updated>

		<summary type="html">&lt;p&gt;Xander: Updates for 09/10&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Xander Macmillan ==&lt;br /&gt;
&lt;br /&gt;
I am a techie in the Bedlam Theatre.&lt;br /&gt;
&lt;br /&gt;
I am working on and have worked on various tech and IT systems in the Bedlam Theatre at one time or another. As such if you have a query with regards to any of the below you should get in touch with me. This is especially true if you are planning to perform maintenance that may be better informed with some background knowledge about a projects&#039; history.&lt;br /&gt;
&lt;br /&gt;
== Involvement ==&lt;br /&gt;
&lt;br /&gt;
=== Ex-projects and responsibilities ===&lt;br /&gt;
&lt;br /&gt;
* Purchasing the &#039;&#039;&#039;[[Sound Desk|Soundcraft GB4]]&#039;&#039;&#039;&lt;br /&gt;
* Fixing &#039;&#039;&#039;Zero88 Betapacks&#039;&#039;&#039; on the cheap&lt;br /&gt;
* The &#039;&#039;&#039;Bedlam Fringe website&#039;&#039;&#039; - Sam is maintaining interim content on the [http://www.bedlamfringe.co.uk Bedlam Fringe website] until Fringe 2010. The 2009 website is archived [http://bedlamfringe2009.portfolio.x13n.com here].&lt;br /&gt;
* The &#039;&#039;&#039;Bedlam and EUTC website content and domain names&#039;&#039;&#039; - Luke is in charge of these now&lt;br /&gt;
* &#039;&#039;&#039;Bedlam and EUTC email addresses&#039;&#039;&#039; - Luke can help you fix these&lt;br /&gt;
&lt;br /&gt;
=== Current projects and responsibilities ===&lt;br /&gt;
&lt;br /&gt;
* The Bedlam and Bedlam Fringe hosting and webspace&lt;br /&gt;
* The Bedlam Fringe email addresses&lt;br /&gt;
* The tickets, ticketing software, ticket printer and online ticketing (http://opentheatre.org.uk)&lt;br /&gt;
* The Box Office and Cafe computers&lt;br /&gt;
&lt;br /&gt;
== Contacting Me ==&lt;br /&gt;
&lt;br /&gt;
I keep up-to-date contact information at [http://x13n.com/alex x13n.com/alex]. Get in touch with me about anything any time.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3818</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3818"/>
		<updated>2009-02-27T12:03:28Z</updated>

		<summary type="html">&lt;p&gt;Xander: Migrating content to opentheatre.org.uk&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== XTS has a home! ==&lt;br /&gt;
&lt;br /&gt;
Because XTS might be useful to other theatres and is taking code contributions from multiple people, XTS now has it&#039;s own website at http://www.opentheatre.org.uk. The content on this page is being migrated to the new site, where it should be better updated and made more comprehensive.&lt;br /&gt;
&lt;br /&gt;
== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
== What I planned to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML you can write programs that interact with the API yourself. You can write your programs in Java, PHP, Python, Ruby -- whatever. So long as you can make an HTTP connection and deal with a little XML, you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
XTS also has a built-in secure proxy (security.py, part of [[#XWF]]), based on AES with a preshared key. It allows trusted remote hosts privileged access to the ticketing server over an encrypted connection.&lt;br /&gt;
&lt;br /&gt;
Applications that want to use the secure method of connecting to the server use a special URL (/v1/secure/v1/connect) and then &amp;quot;trade secrets&amp;quot; with the ticketing server in order to prove it&#039;s trustworthiness and verify the trustworthiness of the server. It&#039;s all very ingenious and you really shouldn&#039;t try doing it yourself until you&#039;ve taken Computer Security (a really good course) or are Bruce Schneier.&lt;br /&gt;
&lt;br /&gt;
To be honest, it&#039;s quite voodoo - but it&#039;s also crucial when doing anything regarding ticket sales over the internet. So, really, don&#039;t mess with it until you quite know what you&#039;re doing.&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== XWF ====&lt;br /&gt;
&lt;br /&gt;
XWF is a python module of useful bits of code for writing web applications. The thinking is that only XTS code should be in the XTS module. So if there&#039;s some code which does something more generic - like writing log files or providing security - this code should be written in a different module where it doesn&#039;t clutter up the code that actually matters.&lt;br /&gt;
&lt;br /&gt;
At time of writing, XWF includes xml.py, which is a lightweight set of functions for very quickly writing XML documents, and security.py, which provides a security layer for remote hosts that need trust and secrecy when talking to the Ticket Server (see [[#Security]]).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py and stats.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== reflection.py =====&lt;br /&gt;
&lt;br /&gt;
reflection.py is a silly bit of code with some functions for counting lines in code. It&#039;s used to provide some of the statistics you get when you look at the XTS &amp;quot;about&amp;quot; page, such as how many TODO comments are still left in the code.&lt;br /&gt;
&lt;br /&gt;
reflection.py should be refactored into the XWF module - none of the code is specific to XTS itself, so it shouldn&#039;t be cluttering up the snewts module.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== stats.py =====&lt;br /&gt;
&lt;br /&gt;
stats.py contains code for calculating various metrics and statistics with regards to the XTS database (such as &amp;quot;how many tickets have been sold?&amp;quot; and &amp;quot;of all of the seats that have been available for all of the shows ever, what percentage of them did we actually sell?&amp;quot;). stats.py accesses the database directly, because otherwise all of the code in stats.py would have to be in data.py, and that would make data.py even bigger than it already is.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3816</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3816"/>
		<updated>2009-02-21T14:51:50Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Security */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML you can write programs that interact with the API yourself. You can write your programs in Java, PHP, Python, Ruby -- whatever. So long as you can make an HTTP connection and deal with a little XML, you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
XTS also has a built-in secure proxy (security.py, part of [[#XWF]]), based on AES with a preshared key. It allows trusted remote hosts privileged access to the ticketing server over an encrypted connection.&lt;br /&gt;
&lt;br /&gt;
Applications that want to use the secure method of connecting to the server use a special URL (/v1/secure/v1/connect) and then &amp;quot;trade secrets&amp;quot; with the ticketing server in order to prove it&#039;s trustworthiness and verify the trustworthiness of the server. It&#039;s all very ingenious and you really shouldn&#039;t try doing it yourself until you&#039;ve taken Computer Security (a really good course) or are Bruce Schneier.&lt;br /&gt;
&lt;br /&gt;
To be honest, it&#039;s quite voodoo - but it&#039;s also crucial when doing anything regarding ticket sales over the internet. So, really, don&#039;t mess with it until you quite know what you&#039;re doing.&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== XWF ====&lt;br /&gt;
&lt;br /&gt;
XWF is a python module of useful bits of code for writing web applications. The thinking is that only XTS code should be in the XTS module. So if there&#039;s some code which does something more generic - like writing log files or providing security - this code should be written in a different module where it doesn&#039;t clutter up the code that actually matters.&lt;br /&gt;
&lt;br /&gt;
At time of writing, XWF includes xml.py, which is a lightweight set of functions for very quickly writing XML documents, and security.py, which provides a security layer for remote hosts that need trust and secrecy when talking to the Ticket Server (see [[#Security]]).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py and stats.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== reflection.py =====&lt;br /&gt;
&lt;br /&gt;
reflection.py is a silly bit of code with some functions for counting lines in code. It&#039;s used to provide some of the statistics you get when you look at the XTS &amp;quot;about&amp;quot; page, such as how many TODO comments are still left in the code.&lt;br /&gt;
&lt;br /&gt;
reflection.py should be refactored into the XWF module - none of the code is specific to XTS itself, so it shouldn&#039;t be cluttering up the snewts module.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== stats.py =====&lt;br /&gt;
&lt;br /&gt;
stats.py contains code for calculating various metrics and statistics with regards to the XTS database (such as &amp;quot;how many tickets have been sold?&amp;quot; and &amp;quot;of all of the seats that have been available for all of the shows ever, what percentage of them did we actually sell?&amp;quot;). stats.py accesses the database directly, because otherwise all of the code in stats.py would have to be in data.py, and that would make data.py even bigger than it already is.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter and the PyCrypto library later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ emacs ~/.bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, CTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;Python Crypto&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install pycrypto&lt;br /&gt;
Installing PyCrypto under Windows is not so trivial. You will need to install MinGW, then perform the install manually (or tweak the easy_install configuration). [http://jintoreedwine.wordpress.com/2008/07/20/python-25-and-encryption-pycrypto-under-windows/ This page summarises how to get the job done quickly].&lt;br /&gt;
&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hilariously, on Windows, this step is much easier. Just get the binary installer from Sourceforge: http://sourceforge.net/projects/mysql-python&lt;br /&gt;
&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3656</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3656"/>
		<updated>2008-10-24T11:38:41Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */ Too much sudo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML you can write programs that interact with the API yourself. You can write your programs in Java, PHP, Python, Ruby -- whatever. So long as you can make an HTTP connection and deal with a little XML, you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
XTS also has a built-in secure proxy (security.py, part of [[#XWF]]), based on AES with a preshared key. It allows trusted remote hosts privileged access to the ticketing server over an encrypted connection.&lt;br /&gt;
&lt;br /&gt;
Applications that want to use the secure method of connecting to the server use a special URL (/v1/secure/v1/connect) and then &amp;quot;trade secrets&amp;quot; with the ticketing server in order to prove it&#039;s trustworthiness and verify the trustworthiness of the server. It&#039;s all very ingenious and you really shouldn&#039;t try doing it yourself until you&#039;ve taken Computer Security (a really good course) or are Bruce Sterling.&lt;br /&gt;
&lt;br /&gt;
To be honest, it&#039;s quite voodoo - but it&#039;s also crucial when doing anything regarding ticket sales over the internet. So, really, don&#039;t mess with it until you quite know what you&#039;re doing.&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== XWF ====&lt;br /&gt;
&lt;br /&gt;
XWF is a python module of useful bits of code for writing web applications. The thinking is that only XTS code should be in the XTS module. So if there&#039;s some code which does something more generic - like writing log files or providing security - this code should be written in a different module where it doesn&#039;t clutter up the code that actually matters.&lt;br /&gt;
&lt;br /&gt;
At time of writing, XWF includes xml.py, which is a lightweight set of functions for very quickly writing XML documents, and security.py, which provides a security layer for remote hosts that need trust and secrecy when talking to the Ticket Server (see [[#Security]]).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py and stats.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== reflection.py =====&lt;br /&gt;
&lt;br /&gt;
reflection.py is a silly bit of code with some functions for counting lines in code. It&#039;s used to provide some of the statistics you get when you look at the XTS &amp;quot;about&amp;quot; page, such as how many TODO comments are still left in the code.&lt;br /&gt;
&lt;br /&gt;
reflection.py should be refactored into the XWF module - none of the code is specific to XTS itself, so it shouldn&#039;t be cluttering up the snewts module.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== stats.py =====&lt;br /&gt;
&lt;br /&gt;
stats.py contains code for calculating various metrics and statistics with regards to the XTS database (such as &amp;quot;how many tickets have been sold?&amp;quot; and &amp;quot;of all of the seats that have been available for all of the shows ever, what percentage of them did we actually sell?&amp;quot;). stats.py accesses the database directly, because otherwise all of the code in stats.py would have to be in data.py, and that would make data.py even bigger than it already is.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter and the PyCrypto library later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ emacs ~/.bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, CTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;Python Crypto&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install pycrypto&lt;br /&gt;
Installing PyCrypto under Windows is not so trivial. You will need to install MinGW, then perform the install manually (or tweak the easy_install configuration). [http://jintoreedwine.wordpress.com/2008/07/20/python-25-and-encryption-pycrypto-under-windows/ This page summarises how to get the job done quickly].&lt;br /&gt;
&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hilariously, on Windows, this step is much easier. Just get the binary installer from Sourceforge: http://sourceforge.net/projects/mysql-python&lt;br /&gt;
&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3628</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3628"/>
		<updated>2008-10-16T06:23:23Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML you can write programs that interact with the API yourself. You can write your programs in Java, PHP, Python, Ruby -- whatever. So long as you can make an HTTP connection and deal with a little XML, you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
XTS also has a built-in secure proxy (security.py, part of [[#XWF]]), based on AES with a preshared key. It allows trusted remote hosts privileged access to the ticketing server over an encrypted connection.&lt;br /&gt;
&lt;br /&gt;
Applications that want to use the secure method of connecting to the server use a special URL (/v1/secure/v1/connect) and then &amp;quot;trade secrets&amp;quot; with the ticketing server in order to prove it&#039;s trustworthiness and verify the trustworthiness of the server. It&#039;s all very ingenious and you really shouldn&#039;t try doing it yourself until you&#039;ve taken Computer Security (a really good course) or are Bruce Sterling.&lt;br /&gt;
&lt;br /&gt;
To be honest, it&#039;s quite voodoo - but it&#039;s also crucial when doing anything regarding ticket sales over the internet. So, really, don&#039;t mess with it until you quite know what you&#039;re doing.&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== XWF ====&lt;br /&gt;
&lt;br /&gt;
XWF is a python module of useful bits of code for writing web applications. The thinking is that only XTS code should be in the XTS module. So if there&#039;s some code which does something more generic - like writing log files or providing security - this code should be written in a different module where it doesn&#039;t clutter up the code that actually matters.&lt;br /&gt;
&lt;br /&gt;
At time of writing, XWF includes xml.py, which is a lightweight set of functions for very quickly writing XML documents, and security.py, which provides a security layer for remote hosts that need trust and secrecy when talking to the Ticket Server (see [[#Security]]).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py and stats.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== reflection.py =====&lt;br /&gt;
&lt;br /&gt;
reflection.py is a silly bit of code with some functions for counting lines in code. It&#039;s used to provide some of the statistics you get when you look at the XTS &amp;quot;about&amp;quot; page, such as how many TODO comments are still left in the code.&lt;br /&gt;
&lt;br /&gt;
reflection.py should be refactored into the XWF module - none of the code is specific to XTS itself, so it shouldn&#039;t be cluttering up the snewts module.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== stats.py =====&lt;br /&gt;
&lt;br /&gt;
stats.py contains code for calculating various metrics and statistics with regards to the XTS database (such as &amp;quot;how many tickets have been sold?&amp;quot; and &amp;quot;of all of the seats that have been available for all of the shows ever, what percentage of them did we actually sell?&amp;quot;). stats.py accesses the database directly, because otherwise all of the code in stats.py would have to be in data.py, and that would make data.py even bigger than it already is.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter and the PyCrypto library later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs ~/.bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, CTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;Python Crypto&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install pycrypto&lt;br /&gt;
Installing PyCrypto under Windows is not so trivial. You will need to install MinGW, then perform the install manually (or tweak the easy_install configuration). [http://jintoreedwine.wordpress.com/2008/07/20/python-25-and-encryption-pycrypto-under-windows/ This page summarises how to get the job done quickly].&lt;br /&gt;
&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hilariously, on Windows, this step is much easier. Just get the binary installer from Sourceforge: http://sourceforge.net/projects/mysql-python&lt;br /&gt;
&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3627</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3627"/>
		<updated>2008-10-16T06:22:49Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Ticket Server */ Various updates.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML you can write programs that interact with the API yourself. You can write your programs in Java, PHP, Python, Ruby -- whatever. So long as you can make an HTTP connection and deal with a little XML, you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
XTS also has a built-in secure proxy (security.py, part of [[#XWF]]), based on AES with a preshared key. It allows trusted remote hosts privileged access to the ticketing server over an encrypted connection.&lt;br /&gt;
&lt;br /&gt;
Applications that want to use the secure method of connecting to the server use a special URL (/v1/secure/v1/connect) and then &amp;quot;trade secrets&amp;quot; with the ticketing server in order to prove it&#039;s trustworthiness and verify the trustworthiness of the server. It&#039;s all very ingenious and you really shouldn&#039;t try doing it yourself until you&#039;ve taken Computer Security (a really good course) or are Bruce Sterling.&lt;br /&gt;
&lt;br /&gt;
To be honest, it&#039;s quite voodoo - but it&#039;s also crucial when doing anything regarding ticket sales over the internet. So, really, don&#039;t mess with it until you quite know what you&#039;re doing.&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== XWF ====&lt;br /&gt;
&lt;br /&gt;
XWF is a python module of useful bits of code for writing web applications. The thinking is that only XTS code should be in the XTS module. So if there&#039;s some code which does something more generic - like writing log files or providing security - this code should be written in a different module where it doesn&#039;t clutter up the code that actually matters.&lt;br /&gt;
&lt;br /&gt;
At time of writing, XWF includes xml.py, which is a lightweight set of functions for very quickly writing XML documents, and security.py, which provides a security layer for remote hosts that need trust and secrecy when talking to the Ticket Server (see [[#Security]]).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py and stats.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== reflection.py =====&lt;br /&gt;
&lt;br /&gt;
reflection.py is a silly bit of code with some functions for counting lines in code. It&#039;s used to provide some of the statistics you get when you look at the XTS &amp;quot;about&amp;quot; page, such as how many TODO comments are still left in the code.&lt;br /&gt;
&lt;br /&gt;
reflection.py should be refactored into the XWF module - none of the code is specific to XTS itself, so it shouldn&#039;t be cluttering up the snewts module.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== stats.py =====&lt;br /&gt;
&lt;br /&gt;
stats.py contains code for calculating various metrics and statistics with regards to the XTS database (such as &amp;quot;how many tickets have been sold?&amp;quot; and &amp;quot;of all of the seats that have been available for all of the shows ever, what percentage of them did we actually sell?&amp;quot;). stats.py accesses the database directly, because otherwise all of the code in stats.py would have to be in data.py, and that would make data.py even bigger than it already is.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter and the PyCrypto library later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs ~/.bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, CTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
&lt;br /&gt;
* Install &amp;quot;Python Crypto&amp;quot;&lt;br /&gt;
  $ sudo easy_install pycrypto&lt;br /&gt;
Installing PyCrypto under Windows is not so trivial. You will need to install MinGW, then perform the install manually (or tweak the easy_install configuration). [http://jintoreedwine.wordpress.com/2008/07/20/python-25-and-encryption-pycrypto-under-windows/ This page summarises how to get the job done quickly].&lt;br /&gt;
&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hilariously, on Windows, this step is much easier. Just get the binary installer from Sourceforge: http://sourceforge.net/projects/mysql-python&lt;br /&gt;
&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3626</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3626"/>
		<updated>2008-10-16T06:01:57Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */ Additions regarding new crypto library.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter and the PyCrypto library later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs ~/.bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, CTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
&lt;br /&gt;
* Install &amp;quot;Python Crypto&amp;quot;&lt;br /&gt;
  $ sudo easy_install pycrypto&lt;br /&gt;
Installing PyCrypto under Windows is not so trivial. You will need to install MinGW, then perform the install manually (or tweak the easy_install configuration). [http://jintoreedwine.wordpress.com/2008/07/20/python-25-and-encryption-pycrypto-under-windows/ This page summarises how to get the job done quickly].&lt;br /&gt;
&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hilariously, on Windows, this step is much easier. Just get the binary installer from Sourceforge: http://sourceforge.net/projects/mysql-python&lt;br /&gt;
&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3625</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3625"/>
		<updated>2008-10-15T14:06:01Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Getting Started */ Pycrypto&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* Install &amp;quot;Python Crypto&amp;quot;&lt;br /&gt;
  $ sudo easy_install pycrypto&lt;br /&gt;
This step relates to a part of XTS that is under development at time of writing. Pycrypto is the cryptographic package that I favour at the moment because it doesn&#039;t have any external dependencies, and thus *should* be easier to build on Windows. However, as I write, I&#039;m still at least needing to install MinGW in order to have the headers needed for compiling from C. So we&#039;ll see. --[[User:Xander|Xander]] 15:06, 15 October 2008 (BST)&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3624</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3624"/>
		<updated>2008-10-15T14:03:18Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */ XTS now has a crypto layer that needs documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
** Crypto - Rjindael (AES)&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=Branding&amp;diff=3621</id>
		<title>Branding</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=Branding&amp;diff=3621"/>
		<updated>2008-10-08T19:50:57Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Edinburgh University Students Association */ New EUSA logo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Current Branding ==&lt;br /&gt;
&lt;br /&gt;
=== Bedlam Theatre ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Bedlamtheatrelogo2007.jpg|150px|left]]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The Bedlam Theatre logo should be shown on all Bedlam Theatre and EUTC related publicity.&lt;br /&gt;
&lt;br /&gt;
The logo should be shown with its surrounding box though the border is optional if the box is shown in contrast to the poster background.&lt;br /&gt;
&lt;br /&gt;
The current branding was designed by Nick Kay for the 2007 Fringe and 07/08 academic year. We are continuing the use of this branding.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/b/b5/Bedlamtheatrelogo2007.jpg Download a high-resolution JPEG of the Bedlam Theatre logo]&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/1/11/BedlamLogoBW.eps Download a vector postscript of the Bedlam Theatre logo, black on white]&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/1/12/BedlamLogoWB.eps Download a vector postscript of the Bedlam Theatre logo, white on black]&lt;br /&gt;
&lt;br /&gt;
=== Edinburgh University Theatre Company ===&lt;br /&gt;
&lt;br /&gt;
Currently the Edinburgh University Theatre Company shares the Bedlam Theatre brand, so does not have a specific logo of it&#039;s own. To show the involvement of the EUTC in the production on posters you may write &amp;quot;Edinburgh University Theatre Company presents...&amp;quot; or similar.&lt;br /&gt;
&lt;br /&gt;
=== Edinburgh University Students Association ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Eusa-logo-2008.jpg|left|150px]]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
All society posters displayed in University buildings must display the EUSA logo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/5/5d/Eusa-logo-2008.jpg Download a high-resolution JPEG of the EUSA logo]&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/2/20/Eusa-logo-2008.eps Download a vector postscript of the EUSA logo]&lt;br /&gt;
&lt;br /&gt;
== Previous Brandings ==&lt;br /&gt;
&lt;br /&gt;
These images should not be used on publicity. Please attribute these images if you can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:Fringecat.gif|[[Fat Cat|No author]]&lt;br /&gt;
Image:Fatcat.gif|[[Fat Cat|No author]]&lt;br /&gt;
Image:Bedlameutc.gif&lt;br /&gt;
Image:Bedlam.gif&lt;br /&gt;
Image:100cat.gif&lt;br /&gt;
Image:Maintitle.gif&lt;br /&gt;
Image:Logo6.gif&lt;br /&gt;
Image:Logo.gif|Neil Hobbs&lt;br /&gt;
Image:Stamp k.jpg|Chris Mounsey&lt;br /&gt;
Image:Bedlam metal.jpg|Chris Mounsey&lt;br /&gt;
Image:Eutc bed metal.jpg|Chris Mounsey&lt;br /&gt;
Image:Eutc prod metal.jpg|Chris Mounsey&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=Branding&amp;diff=3620</id>
		<title>Branding</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=Branding&amp;diff=3620"/>
		<updated>2008-10-08T19:50:24Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Edinburgh University Students Association */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Current Branding ==&lt;br /&gt;
&lt;br /&gt;
=== Bedlam Theatre ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Bedlamtheatrelogo2007.jpg|150px|left]]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The Bedlam Theatre logo should be shown on all Bedlam Theatre and EUTC related publicity.&lt;br /&gt;
&lt;br /&gt;
The logo should be shown with its surrounding box though the border is optional if the box is shown in contrast to the poster background.&lt;br /&gt;
&lt;br /&gt;
The current branding was designed by Nick Kay for the 2007 Fringe and 07/08 academic year. We are continuing the use of this branding.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/b/b5/Bedlamtheatrelogo2007.jpg Download a high-resolution JPEG of the Bedlam Theatre logo]&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/1/11/BedlamLogoBW.eps Download a vector postscript of the Bedlam Theatre logo, black on white]&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/1/12/BedlamLogoWB.eps Download a vector postscript of the Bedlam Theatre logo, white on black]&lt;br /&gt;
&lt;br /&gt;
=== Edinburgh University Theatre Company ===&lt;br /&gt;
&lt;br /&gt;
Currently the Edinburgh University Theatre Company shares the Bedlam Theatre brand, so does not have a specific logo of it&#039;s own. To show the involvement of the EUTC in the production on posters you may write &amp;quot;Edinburgh University Theatre Company presents...&amp;quot; or similar.&lt;br /&gt;
&lt;br /&gt;
=== Edinburgh University Students Association ===&lt;br /&gt;
&lt;br /&gt;
[[Image:Eusa-logo-2008.jpg|left|150px]]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
All society posters displayed in University buildings must display the EUSA logo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/5/5d/Eusa-logo-2008.jpg Download a high-resolution JPEG of the EUSA logo]&lt;br /&gt;
* [http://wiki.eutc.org.uk/images/2/20/Eusa-logo-2008.eps Download a vector EPS of the EUSA logo]&lt;br /&gt;
&lt;br /&gt;
== Previous Brandings ==&lt;br /&gt;
&lt;br /&gt;
These images should not be used on publicity. Please attribute these images if you can.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:Fringecat.gif|[[Fat Cat|No author]]&lt;br /&gt;
Image:Fatcat.gif|[[Fat Cat|No author]]&lt;br /&gt;
Image:Bedlameutc.gif&lt;br /&gt;
Image:Bedlam.gif&lt;br /&gt;
Image:100cat.gif&lt;br /&gt;
Image:Maintitle.gif&lt;br /&gt;
Image:Logo6.gif&lt;br /&gt;
Image:Logo.gif|Neil Hobbs&lt;br /&gt;
Image:Stamp k.jpg|Chris Mounsey&lt;br /&gt;
Image:Bedlam metal.jpg|Chris Mounsey&lt;br /&gt;
Image:Eutc bed metal.jpg|Chris Mounsey&lt;br /&gt;
Image:Eutc prod metal.jpg|Chris Mounsey&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=File:Eusa-logo-2008.eps&amp;diff=3619</id>
		<title>File:Eusa-logo-2008.eps</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=File:Eusa-logo-2008.eps&amp;diff=3619"/>
		<updated>2008-10-08T19:46:28Z</updated>

		<summary type="html">&lt;p&gt;Xander: New EUSA logo in vector format.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;New EUSA logo in vector format.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=File:Eusa-logo-2008.jpg&amp;diff=3618</id>
		<title>File:Eusa-logo-2008.jpg</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=File:Eusa-logo-2008.jpg&amp;diff=3618"/>
		<updated>2008-10-08T19:44:56Z</updated>

		<summary type="html">&lt;p&gt;Xander: EUSA&amp;#039;s new logo since 2008 - high resolution JPG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;EUSA&#039;s new logo since 2008 - high resolution JPG&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3617</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3617"/>
		<updated>2008-08-28T15:38:48Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** DONE Setting up your own dev version from trunk&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3616</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3616"/>
		<updated>2008-08-28T15:23:45Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing the mysql adapter will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3615</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3615"/>
		<updated>2008-08-28T15:22:16Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing mysql will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;br /&gt;
* Finally, &#039;&#039;&#039;run the XTS server&#039;&#039;&#039;. In whatever directory you have a copy of the XTS source, run:&lt;br /&gt;
  $ python server.py&lt;br /&gt;
You can now visit http://localhost:8080 in a web browser on your own computer to play around. So long as the version signature under the XTS logo shows &amp;quot;DEV&amp;quot;, you&#039;re looking at your own server.&lt;br /&gt;
* Get hacking.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3614</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3614"/>
		<updated>2008-08-28T15:19:25Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing mysql will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;br /&gt;
You&#039;ve now finished installing all of the required software. Next you need to set up the initial data and permissions in the database.&lt;br /&gt;
* Download &#039;&#039;&#039;CocoaMySQL&#039;&#039;&#039;, or an alternative MySQL client of your choosing.&lt;br /&gt;
* &#039;&#039;&#039;Log into your own MySQL server&#039;&#039;&#039; as root.&lt;br /&gt;
* &#039;&#039;&#039;Create a database&#039;&#039;&#039; called &amp;quot;xts&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;Import a database backup&#039;&#039;&#039; from Maude. It&#039;s the fastest way to get up and running with plenty of real-world data.&lt;br /&gt;
* &#039;&#039;&#039;Set permissions&#039;&#039;&#039; so that the anonymous user on localhost (&amp;quot;@localhost&amp;quot;) has full access to the xts database. These are very lax permissions, but they&#039;ll do for a development server.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3613</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3613"/>
		<updated>2008-08-28T15:10:23Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Build a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;. Download the tarball from http://sourceforge.net/projects/mysql-python. Then untar it, patch _mysql.c by hand and install. Sounds hard? It is. Hopefully by the time you come to do this, installing mysql will be as easy as sudo easy_install mysql_python. See http://forums.mysql.com/read.php?50,175059,219216#msg-219216 for more info.&lt;br /&gt;
  $ tar -xvf MySQL-python-1.2.2.tar&lt;br /&gt;
  $ cd MySQL-python-1.2.2&lt;br /&gt;
  $ emacs _mysql.c (... and patch as shown on teh internets -- you need to comment out lines 37-39)&lt;br /&gt;
  $ sudo python setup.py install&lt;br /&gt;
  $ sudo mkdir /usr/local/mysql/lib/mysql&lt;br /&gt;
  $ sudo cp /usr/local/mysql/lib/libmysqlclient_r.15.dylib /usr/local/mysql/lib/mysql/libmysqlclient_r.15.dylib&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3612</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3612"/>
		<updated>2008-08-27T16:03:37Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/download/&lt;br /&gt;
* Install a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;.&lt;br /&gt;
  $ sudo easy_install mysql_python&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3611</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3611"/>
		<updated>2008-08-27T15:59:22Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install &#039;&#039;&#039;web.py&#039;&#039;&#039;&lt;br /&gt;
  $ sudo easy_install web.py&lt;br /&gt;
* In order to run the administration interface, install &#039;&#039;&#039;Django&#039;&#039;&#039;. http://www.djangoproject.com/documentation/install/&lt;br /&gt;
* Install a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;.&lt;br /&gt;
  $ sudo easy_install mysql_python&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3610</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3610"/>
		<updated>2008-08-27T15:56:05Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install &#039;&#039;&#039;XCode Tools&#039;&#039;&#039;. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;.&lt;br /&gt;
  $ sudo easy_install mysql_python&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3609</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3609"/>
		<updated>2008-08-27T15:34:37Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install XCode Tools. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* &#039;&#039;&#039;Add the MySQL server binaries to your path&#039;&#039;&#039;. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to &#039;&#039;&#039;start up your MySQL server&#039;&#039;&#039; by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install a &#039;&#039;&#039;Python/MySQL adapter&#039;&#039;&#039;.&lt;br /&gt;
  $ sudo easy_install mysql_python&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3608</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3608"/>
		<updated>2008-08-27T15:33:40Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Setting Up a Development Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take (and didn&#039;t need to take, but that you will need to on other platforms) to set up a development server on a new MacBook on 2008-08-27.&lt;br /&gt;
&lt;br /&gt;
You need to be familiar with Terminal, and you&#039;ll be using the sudo command to do things as root. If these things sound frightening you should start by googling around a little.&lt;br /&gt;
&lt;br /&gt;
* Install XCode Tools. You&#039;re going to need XCode so that you can build the Python/MySQL adapter later. You can download XCode from http://developer.apple.com/tools/xcode/. It&#039;s free, but it&#039;s a big download. While you&#039;re downloading it, move onto the next couple of steps.&lt;br /&gt;
* &#039;&#039;&#039;Python 2.5&#039;&#039;&#039; is already installed on Mac OS X 10.5. Rejoice.&lt;br /&gt;
* &#039;&#039;&#039;easy_install&#039;&#039;&#039; is already installed on Mac OS X 10.5. Aren&#039;t you glad you bought a Mac?&lt;br /&gt;
* Install a &#039;&#039;&#039;MySQL database server&#039;&#039;&#039;. It&#039;s free and open-source. http://dev.mysql.com&lt;br /&gt;
* Add the MySQL server binaries to your path. To do this you need to create a bash profile.&lt;br /&gt;
  $ sudo emacs .bash_profile&lt;br /&gt;
Then, put this in the new file you&#039;ve just created in EMACS:&lt;br /&gt;
  export PATH=$PATH:/usr/local/mysql/bin&lt;br /&gt;
Then save and close your new profile by pressing CTRL-X, CTRL-S, XTRL-X, CTRL-C. Then to make use of your new profile, close and re-open your terminal.&lt;br /&gt;
* So long as the previous step went well you should now be able to start up your MySQL server by typing:&lt;br /&gt;
  $ sudo safe_mysqld&lt;br /&gt;
If that fails to work, you didn&#039;t manage to reconfigure your path properly. Google for help. &lt;br /&gt;
* Install a Python/MySQL adapter.&lt;br /&gt;
  $ sudo easy_install mysql_python&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3607</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3607"/>
		<updated>2008-08-27T15:12:49Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Documentation */ Adding a set-up section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;br /&gt;
&lt;br /&gt;
== Making Improvements - a HOWTO ==&lt;br /&gt;
&lt;br /&gt;
=== Getting Started ===&lt;br /&gt;
&lt;br /&gt;
==== Setting Up a Development Server ====&lt;br /&gt;
&lt;br /&gt;
These are the steps I needed to take to set up a development server on a new MacBook on 2008-08-27.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3606</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3606"/>
		<updated>2008-08-10T20:34:35Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
** Fun Ideas For Improvements or Otherwise&lt;br /&gt;
*** Booking from portable devices for producers (&amp;quot;Would you like to come? I&#039;ll book you a ticket now.&amp;quot;)&lt;br /&gt;
*** XTS-controlled DMX for Box Office Lighting Fun Times&lt;br /&gt;
*** Heads-up displays for show times and sold out info a-la every cinema you&#039;ve ever been to&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3596</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3596"/>
		<updated>2008-07-26T17:04:12Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Ticket Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
The ticket server is accessible via HTTP on port 8080.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3595</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3595"/>
		<updated>2008-07-26T17:03:19Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** DONE Print Server&lt;br /&gt;
*** DONE API&lt;br /&gt;
*** DONE Making new ticket layouts&lt;br /&gt;
*** DONE Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3594</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3594"/>
		<updated>2008-07-26T17:02:46Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Parts of the System */ Documented the Print Server&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;br /&gt;
&lt;br /&gt;
=== Print Server ===&lt;br /&gt;
&lt;br /&gt;
The print server is a separate entity from the ticketing server that handles ticket printing. It listens on the network for messages instructing it to print tickets.&lt;br /&gt;
&lt;br /&gt;
It is written in pure Java for the convenience of Java&#039;s layout and printing library. It uses the effective users&#039; default printer for printing (so this printer needs to be set to the ticket printer).&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
The print server listens for tickets to print on port . Tickets are sent to the printer as UDP messages on port 8301. The UDP message format consists of six strings terminated by the NULL character. It does not support UTF8 encoding. It is very fail. The strings are, in order:&lt;br /&gt;
&lt;br /&gt;
* Show Name&lt;br /&gt;
* Date (expected format: ddd YYYY-MM-DD)&lt;br /&gt;
* Time (expected format: HH:MM)&lt;br /&gt;
* Booking name (can be an empty string)&lt;br /&gt;
* Ticket serial&lt;br /&gt;
* Ticket type (ie. &amp;quot;Student&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
When the print server receives your ticket and succeeds in dispatching it to the printer it will reply with a UDP packet containing the ticket serial you specified.&lt;br /&gt;
&lt;br /&gt;
==== Making new ticket layouts ====&lt;br /&gt;
&lt;br /&gt;
You need to know Java to write new ticket layouts. &lt;br /&gt;
&lt;br /&gt;
Make a pair of new classes implementing uk.org.opentheatre.xts.Ticket and uk.org.opentheatre.xts.TicketFactory. The former must lay out the ticket, the latter must create instances of the ticket. Look at existing ticket classes for examples on how to do this. &lt;br /&gt;
&lt;br /&gt;
Then, modify the uk.co.bedlamtheatre.BedlamTicketPrintServer to use your new TicketFactory class. You&#039;re now done. You can run your modified BedlamTicketPrintServer straight from your IDE and use the taskbar icon that appears to print test tickets and receive tickets from the XTS Ticket Server (if the print service isn&#039;t running - see [[#Startup - Windows Services]]). When you&#039;re happy with your new layout, replace the classes in C:\XTS\PrinterInterface\bin and either restart the Windows Service or just reboot.&lt;br /&gt;
&lt;br /&gt;
==== Changing the Ticket Logo ====&lt;br /&gt;
&lt;br /&gt;
This is much easier than making a new layout. Just replace C:\Xander\ticketlogo.bmp with your new logo. It should have the same dimensions and should probably be just black and white.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3593</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3593"/>
		<updated>2008-07-26T16:35:58Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* printer.py */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [[#Print Server]] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3592</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3592"/>
		<updated>2008-07-26T16:34:49Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* printer.py */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the [#Print Server] and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3591</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3591"/>
		<updated>2008-07-26T16:27:15Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** DONE Database&lt;br /&gt;
*** DONE Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3590</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3590"/>
		<updated>2008-07-26T16:24:57Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** Verifying bookings&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** Database&lt;br /&gt;
*** Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3589</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3589"/>
		<updated>2008-07-26T16:24:19Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* eXtensible Ticketing System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for more key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** Database&lt;br /&gt;
*** Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3588</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3588"/>
		<updated>2008-07-26T16:24:01Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* eXtensible Ticketing System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do, you (or a suitably inclined geek) should easily be able to add it. Read on for key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** Database&lt;br /&gt;
*** Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3587</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3587"/>
		<updated>2008-07-26T16:23:46Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* eXtensible Ticketing System */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
XTS is the Bedlam Theatre&#039;s new ticketing system. It&#039;s key feature is extensibility, meaning that if it doesn&#039;t do something you want it to do you (or a suitably inclined geek) should easily be able to add it. Read on for key features and read further for technical information that will help you maintain and make changes to the system if that is your want.&lt;br /&gt;
&lt;br /&gt;
If you are just looking for help using the software to sell tickets, try [[Using XTS]].&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** Database&lt;br /&gt;
*** Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=Main_Page&amp;diff=3586</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=Main_Page&amp;diff=3586"/>
		<updated>2008-07-26T16:17:54Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* How do I sign up? */ Tweaked for encouragement.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:IMGP0219.jpg|thumb|350px|The Bedlam Theatre]]Welcome to the Bedlam Wiki. It is hoped that this will become a valuable resource for all [[EUTC]] and Bedlam Theatre matters.&lt;br /&gt;
&lt;br /&gt;
===How does it work?===&lt;br /&gt;
&lt;br /&gt;
Basically this is an online resource which is editable by anybody that has registered.&lt;br /&gt;
&lt;br /&gt;
Simply click EDIT at the top of the screen to edit an article.&lt;br /&gt;
&lt;br /&gt;
If an article doesn&#039;t exist then you can create it - simply search for an article - if it doesn&#039;t already exist you will be invited to create it! Easy! &lt;br /&gt;
&lt;br /&gt;
Here are a few links to look at...&lt;br /&gt;
&lt;br /&gt;
* [[A to Z]]&lt;br /&gt;
* [[How To]]&lt;br /&gt;
* [[Guide to Building|Building Guide]]&lt;br /&gt;
* [[Special:Allpages|All Pages]]&lt;br /&gt;
* [[Special:Categories|Categories]]&lt;br /&gt;
&lt;br /&gt;
===How do I sign up?===&lt;br /&gt;
&lt;br /&gt;
Signing up has been disabled due to spammers but we still want your contributions. Please email [http://www.thatscottishengineer.co.uk Alistair] or one of the [[EUTC Wiki:Administrators|other admins]] (including the [[Secretary]] and [[Tech manager]]) your full name and the user name you want.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Disclamer===&lt;br /&gt;
&lt;br /&gt;
Please be aware that this online community does not speak for, or on behalf of the [[Edinburgh University Theatre Company]] or individuals with current, previous or past responsibility or any of current, previous, past or [[life members]]. Any comments contained within are purely those of the author and not of the company or of any individual.&lt;br /&gt;
&lt;br /&gt;
There is no restriction nor moderation on this wiki - if you see a mistake, please correct it. If you see something inappropriate / libellous then please remove it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Have you got any suggestions? Email [mailto:webmaster@bedlamtheatre.co.uk the webmaster] or [http://www.thatscottishengineer.co.uk Alistair]&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=Bedlam_Fringe&amp;diff=3585</id>
		<title>Bedlam Fringe</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=Bedlam_Fringe&amp;diff=3585"/>
		<updated>2008-07-26T16:15:23Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Fringe 2008 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Every August the Bedlam turns professional and opens up as Fringe Venue 49.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a history of the people involved...&lt;br /&gt;
&lt;br /&gt;
==Fringe 2008==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Colleen Patterson&lt;br /&gt;
*Theatre Manager: Mal Mead&lt;br /&gt;
*Technical Manager: Sam Hansford&lt;br /&gt;
*Press and Publicity Manager: Becs Kamp&lt;br /&gt;
*Business Manager: Fran Walker&lt;br /&gt;
*Graphics Designer: Nick Kay&lt;br /&gt;
*Box Office Managers: Lauren McLeod and Xander Macmillan&lt;br /&gt;
*Cafe Managers: Cat Hobart and Ellie Harrison&lt;br /&gt;
*Box Office Staff: Liz Black, Dylan Read, Fred Gordon, Emma Pattinson, Ellie Richardson, Nicola Hazelton, Lucy Sneddon, Maredith Close&lt;br /&gt;
*Cafe Staff: Amy Brewer, Alex Hatt, Carley Stubbs, Emily Jenkinson&lt;br /&gt;
&lt;br /&gt;
Achievements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- admin --&amp;gt;&lt;br /&gt;
*Repainted [[office]] and redid [[committee]] pigeonholes&lt;br /&gt;
*New Sunday opening times on sunday afternoons with pub quiz and café entertainment&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- auditorium --&amp;gt;&lt;br /&gt;
*Installed new [[seats]]&lt;br /&gt;
*Renovated and refinished the seating rake&lt;br /&gt;
*Laid new carpet in the auditorium&lt;br /&gt;
*Reskinned the [[stage]] (we totally do this every year)&lt;br /&gt;
*Re-finished the stage&#039;s risers with 18mm plywood&lt;br /&gt;
*Spray-painted the [[rig]] black for stealth&lt;br /&gt;
*Moved the [[lighting store]] to the dimmers&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- cafe --&amp;gt;&lt;br /&gt;
*Rebuilt the [[cafe]] servery&lt;br /&gt;
*Partially restored and re-varnished cafe floor&lt;br /&gt;
*Rebuilt cafe boards&lt;br /&gt;
*Fixed the bulge in the [[cafe]] wall&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- box office --&amp;gt;&lt;br /&gt;
*Rewrote the [[XTS|ticketing system]]&lt;br /&gt;
*Fixed the [[FOH Sound|FoH Sound System]]&lt;br /&gt;
*Installed a lighting bar in the box office, bought a Bedlam Theatre logo gobo for projection.&lt;br /&gt;
&lt;br /&gt;
==Fringe 2007==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Matt Wieteska&lt;br /&gt;
*Theatre Manager: Colleen Patterson&lt;br /&gt;
*Technical Manager: Neale Dutton&lt;br /&gt;
*Press and Publicity Manager: Lucy Jackson&lt;br /&gt;
*Graphics Designer: Nick Kay&lt;br /&gt;
*Sponsorship Manager: Becs Kamp&lt;br /&gt;
*Box Office Managers: Alex Hall and Mike Smith&lt;br /&gt;
*Cafe Managers: James &amp;quot;Bruce&amp;quot; Sinclair and Holly Mclay&lt;br /&gt;
*Box Office Staff: Lauren McLeod, Kate Wieteska, Felix Trench, Reg Scott, Chloe Edworthy, Mairi Kellock, Cat Hoyle, Becs Kamp&lt;br /&gt;
*Cafe Staff: Lauren Fried, Becca Day-Preston, Chris Cotter, Craig Hamilton&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Built a wall in the [[auditorium]] to help with soundproofing&lt;br /&gt;
*Reskinned the [[stage]]&lt;br /&gt;
*New [[box office]] printer&lt;br /&gt;
*Installed [[sound]] system&lt;br /&gt;
&lt;br /&gt;
==Fringe 2006==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Charlotte Jarvis&lt;br /&gt;
*Theatre Manager: Alex Engel&lt;br /&gt;
*Technical Manager: Matt Wieteska&lt;br /&gt;
*Press and Publicity Manager: Simon Hodges&lt;br /&gt;
*Graphics Designer: Chris Mounsey&lt;br /&gt;
*Box Office Managers: Helena Larkin and Tom Latter&lt;br /&gt;
*Café Managers: Clemmie Cooke and Charlotte Coles&lt;br /&gt;
*Box Office Staff: Cat Hoyle, James Turner Inman, Richard Shore, Katy Bartholomew, Colleen Patterson, Natalia Prochnicka and Geraldine Heaney &lt;br /&gt;
*Cafe Staff:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Replaced blackout [[curtains]] on [[balcony]] with new black fabric&lt;br /&gt;
*New coffee machine with fancy coffee capabilities for [[cafe]]&lt;br /&gt;
*Built large schedule chalkboards for outside&lt;br /&gt;
*Painted [[office]] white and blue&lt;br /&gt;
*Reskinned the [[stage]]&lt;br /&gt;
&lt;br /&gt;
==Fringe 2005==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Claire Glendenning&lt;br /&gt;
*Theatre Manager: James Turner-Inman&lt;br /&gt;
*Technical Manager: Paul Foxcroft&lt;br /&gt;
*Press and Publicity Manager: Andrew Nielson&lt;br /&gt;
*Graphics Designer: Chris Mounsey&lt;br /&gt;
*Box Office Managers: Heather Hanshaw + Nick Bustin&lt;br /&gt;
*Café Managers: Graeme Wright + Becca Davis&lt;br /&gt;
*Box Office Staff: Jeremy Bidgood, Rob Stott, Rosie Drew, Alex Engel, Charlotte Jarvis&lt;br /&gt;
*Cafe Staff: Emma Drage, &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Replaced carpet in [[auditorium]] with carpet tiles&lt;br /&gt;
*New freezer&lt;br /&gt;
*Improved [[box office]] system with thermal ticket printer and new software&lt;br /&gt;
*Re-hung rig (termtime budget?)&lt;br /&gt;
*Created trus-based awning for front of building (sponsored by Becks)&lt;br /&gt;
*Installed ADSL [[internet connection]], network cabling and wireless network&lt;br /&gt;
*Loads of painting&lt;br /&gt;
*Improved soundproofing in between [[café]] and [[auditorium]] around the door&lt;br /&gt;
*Pimped up the [[office]]&lt;br /&gt;
*New storage solutions in [[techbox]] and [[balcony]] for screws and stuff&lt;br /&gt;
*Various new bits and bobs for the [[café]] e.g. tea light lanterns&lt;br /&gt;
*Purchase of Dog (who is a rabbit) [and is very cute]&lt;br /&gt;
*Re-skinned [[stage]]&lt;br /&gt;
*Sanded down and varnished [[cafe]] floor&lt;br /&gt;
&lt;br /&gt;
==Fringe 2004==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Miriam Raines&lt;br /&gt;
*Theatre Manager: &lt;br /&gt;
*Technical Manager: James Turner-Inman&lt;br /&gt;
*Press and Publicity Manager: &lt;br /&gt;
*Graphics Designer: &lt;br /&gt;
*Box Office Managers: Paul Foxcroft, Martin Cavanagh&lt;br /&gt;
*Café Managers: &lt;br /&gt;
*Box Office Staff: &lt;br /&gt;
*Cafe Staff: &lt;br /&gt;
&lt;br /&gt;
==Fringe 2003==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Cat Smith&lt;br /&gt;
*Theatre Manager: Jono Ellis&lt;br /&gt;
*Technical Manager: Matt Ling&lt;br /&gt;
*Press and Publicity Manager: Sarah Cook&lt;br /&gt;
*Graphics Designer/Website: Neil E. Hobbs&lt;br /&gt;
*Box Office Managers: Alison Timms and Kirsten Morris&lt;br /&gt;
*Café Managers: Victoria Tills and Kati Hind&lt;br /&gt;
*Box Office Staff: &lt;br /&gt;
*Cafe Staff:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
*New potato oven and chiller cabinet for [[cafe]]&lt;br /&gt;
*New [[sound]] system - two speakers, mini disc players, new MC2 amp, graphics - paid for by profit from Fringe 2002 (!)&lt;br /&gt;
*New level in [[costume cupboard]] - see graffiti!&lt;br /&gt;
*Skinned [[stage cupboard]] for the first time and removed wall and rail allowing it to become a stage pit&lt;br /&gt;
*Redid [[cafe]] and [[toilets]]&lt;br /&gt;
*Installed fan in [[cafe]] to improve ventilation&lt;br /&gt;
*Obtained two microwaves &lt;br /&gt;
*Redid [[kitchen]] - repainted and tiled walls, obtained new oven and hobs&lt;br /&gt;
*Cut down number of [[EUTC]] slots to two&lt;br /&gt;
*Held first [[FOB]] [[A_to_Z#AGM_-_Annual_General_Meeting|AGM]]&lt;br /&gt;
*Held first full preview week schedule&lt;br /&gt;
*Held art exhibition in collabaration with ECA&lt;br /&gt;
*Bought picnic table to extend [[cafe]] area (buy a new one!)&lt;br /&gt;
*Made more money than Graeme Timms (sorry long standing debate!)&lt;br /&gt;
&lt;br /&gt;
==Fringe 2002==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Graeme Timms&lt;br /&gt;
*Theatre Manager: Richard Hogg&lt;br /&gt;
*Technical Manager: Matt Gray&lt;br /&gt;
*Press and Publicity Manager: Neil E. Hobbs&lt;br /&gt;
*Graphics Designer/Website: Neil E. Hobbs&lt;br /&gt;
*Box Office Managers: Pete Lowden and Sarah Kerr&lt;br /&gt;
*Café Managers: Cat Smith and Rachel Mountfield&lt;br /&gt;
*Box Office Staff: &lt;br /&gt;
*Cafe Staff:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
*Replaced damaged floorboards on [[stage]] during re-skinning&lt;br /&gt;
*Dug out back passage and laid path and red chips round that side of building&lt;br /&gt;
*Re-built [[box office]] counter&lt;br /&gt;
*Installed Tramp-Cam&lt;br /&gt;
*Much re-wiring of light fittings and sockets&lt;br /&gt;
*Computerised the [[Box office]] ticketing system&lt;br /&gt;
*Built the Info-Cat - (He never quite became a cat)&lt;br /&gt;
*Replaced lighting in [[toilets]]&lt;br /&gt;
*Rebranded &#039;&#039;&#039;Bedlam Fringe&#039;&#039;&#039; as a separate entity from term-time operation&lt;br /&gt;
*First website with up-to-date reviews, show info, etc&lt;br /&gt;
*Much painting&lt;br /&gt;
*Consumption of the more Caley Golden Promise that the Cash and Carry could stock!!&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=FOH_Sound&amp;diff=3584</id>
		<title>FOH Sound</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=FOH_Sound&amp;diff=3584"/>
		<updated>2008-07-26T16:05:57Z</updated>

		<summary type="html">&lt;p&gt;Xander: Added backstage feed information (currently not connected)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Front Of House Sound System =&lt;br /&gt;
&lt;br /&gt;
Front Of House sound is distributed from a Zone Mixer in the Box Office, secured to the underside of the shelf immediately to the left of the Box Office computer.&lt;br /&gt;
&lt;br /&gt;
The Zone Mixer takes up to six inputs and sends sound to three zones. Each zone can be independently set to play back one of the six inputs.&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-26 the mappings are:&lt;br /&gt;
&lt;br /&gt;
=== Inputs ===&lt;br /&gt;
* Input 1: Unassigned&lt;br /&gt;
* Input 2: Box Office CD player&lt;br /&gt;
* Input 3: Box Office Minijack (for iPods, laptops, etc)&lt;br /&gt;
* Input 4: Unassigned&lt;br /&gt;
* Input 5: Unassigned&lt;br /&gt;
* Input 6: Tech Box Feed&lt;br /&gt;
&lt;br /&gt;
=== Zones ===&lt;br /&gt;
* Zone 1: Café&lt;br /&gt;
* Zone 2: Box Office&lt;br /&gt;
* Zone 3: Toilet Corridor&lt;br /&gt;
&lt;br /&gt;
= Maintenance =&lt;br /&gt;
&lt;br /&gt;
== Mono/Stereo ==&lt;br /&gt;
&lt;br /&gt;
The café is the only zone that has stereo playback - this is a limitation of the Zone Mixer. Additionally, the tech box feed is mono so all playback from the tech box is strictly mono. However, sound from other sources will be in stereo in the café.&lt;br /&gt;
&lt;br /&gt;
== Tech Box Feed ==&lt;br /&gt;
&lt;br /&gt;
The tech box feed enters the box office via a cable on the right side of the box office cupboard door frame.&lt;br /&gt;
&lt;br /&gt;
== Backstage Feed ==&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-26 there is cabling for a backstage feed but it is not connected as a zone (we instead are using this zone for the toilet corridor). The backstage feed is potentially useful as a stage monitor for actors in the dressing room, so if this suits you you may like to find the dangling connector pair hidden behind the amps and sub out a zone on the mixer in order to reconnect it.&lt;br /&gt;
&lt;br /&gt;
The backstage feed is wired with cat5e (purple sheath) carrying both mono sound and the signal wires for the zone remote.  &lt;br /&gt;
&lt;br /&gt;
== Remotes ==&lt;br /&gt;
&lt;br /&gt;
Any zone can be controlled remotely by attaching a (wall-mounted) remote. When the zone is controlled remotely the first two knobs for the zone (input select and volume) no longer have any effect on the mixer (having been overridden by the knobs on the remote). As of 2008-07-26, only the café zone is controlled by a remote, on the left wall of the café when facing out. This makes it easier for box office staff to keep the box office and toilet corridor playing from the same input. &lt;br /&gt;
&lt;br /&gt;
== Amplifiers ==&lt;br /&gt;
&lt;br /&gt;
Each zone has a separate amplifier, all amplifiers are stacked on the floor beneath the zone mixer. The toilet corridor amp is only driving one speaker, this is ideal because the other channel on the amplifier does not work. You make want to take this into account if repurposing the amps.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t change the gains on the amplifiers, use the zone volume knobs instead.&lt;br /&gt;
&lt;br /&gt;
As with the tech box sound system, turn on the zone mixer before turning on the amplifiers. When powering down, turn off the amplifiers before turning off the zone mixer.&lt;br /&gt;
&lt;br /&gt;
== Adding more inputs ==&lt;br /&gt;
&lt;br /&gt;
The back of the zone mixer is readily accessible by sticking your head into the shelf space and having a strong light source to hand. The inputs are at the right end of the back of the device (or your left, once you&#039;ve stuck your head in the shelf). Input one is the edgemost, input six is nearest the middle.&lt;br /&gt;
&lt;br /&gt;
Make sure any wires you add are cabletied neatly so that the shelf space beneath the zone mixer is still as usable as possible. Additionally, keep the next person to come along happy by labelling your cables at both ends. You will be loved. &lt;br /&gt;
&lt;br /&gt;
== Doing more interesting stuff with the Zone Mixer ==&lt;br /&gt;
&lt;br /&gt;
If you need to mess with the zone mappings, remotes, zone EQs or other more advanced stuff you should unscrew the zone mixer from its brackets and get a better look - the device is completely self-documented in astonishingly detail by diagrams on the top and the bottom of the case - including required wiring configurations for the connectors and other useful stuff to know.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=FOH_Sound&amp;diff=3583</id>
		<title>FOH Sound</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=FOH_Sound&amp;diff=3583"/>
		<updated>2008-07-26T16:01:21Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Front Of House Sound System */ Proofing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Front Of House Sound System =&lt;br /&gt;
&lt;br /&gt;
Front Of House sound is distributed from a Zone Mixer in the Box Office, secured to the underside of the shelf immediately to the left of the Box Office computer.&lt;br /&gt;
&lt;br /&gt;
The Zone Mixer takes up to six inputs and sends sound to three zones. Each zone can be independently set to play back one of the six inputs.&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-26 the mappings are:&lt;br /&gt;
&lt;br /&gt;
=== Inputs ===&lt;br /&gt;
* Input 1: Unassigned&lt;br /&gt;
* Input 2: Box Office CD player&lt;br /&gt;
* Input 3: Box Office Minijack (for iPods, laptops, etc)&lt;br /&gt;
* Input 4: Unassigned&lt;br /&gt;
* Input 5: Unassigned&lt;br /&gt;
* Input 6: Tech Box Feed&lt;br /&gt;
&lt;br /&gt;
=== Zones ===&lt;br /&gt;
* Zone 1: Café&lt;br /&gt;
* Zone 2: Box Office&lt;br /&gt;
* Zone 3: Toilet Corridor&lt;br /&gt;
&lt;br /&gt;
= Maintenance =&lt;br /&gt;
&lt;br /&gt;
== Mono/Stereo ==&lt;br /&gt;
&lt;br /&gt;
The café is the only zone that has stereo playback - this is a limitation of the Zone Mixer. Additionally, the tech box feed is mono so all playback from the tech box is strictly mono. However, sound from other sources will be in stereo in the café.&lt;br /&gt;
&lt;br /&gt;
== Tech Box Feed ==&lt;br /&gt;
&lt;br /&gt;
The tech box feed enters the box office via a cable on the right side of the box office cupboard door frame.&lt;br /&gt;
&lt;br /&gt;
== Remotes ==&lt;br /&gt;
&lt;br /&gt;
Any zone can be controlled remotely by attaching a (wall-mounted) remote. When the zone is controlled remotely the first two knobs for the zone (input select and volume) no longer have any effect on the mixer (having been overridden by the knobs on the remote). As of 2008-07-26, only the café zone is controlled by a remote, on the left wall of the café when facing out. This makes it easier for box office staff to keep the box office and toilet corridor playing from the same input. &lt;br /&gt;
&lt;br /&gt;
== Amplifiers ==&lt;br /&gt;
&lt;br /&gt;
Each zone has a separate amplifier, all amplifiers are stacked on the floor beneath the zone mixer. The toilet corridor amp is only driving one speaker, this is ideal because the other channel on the amplifier does not work. You make want to take this into account if repurposing the amps.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t change the gains on the amplifiers, use the zone volume knobs instead.&lt;br /&gt;
&lt;br /&gt;
As with the tech box sound system, turn on the zone mixer before turning on the amplifiers. When powering down, turn off the amplifiers before turning off the zone mixer.&lt;br /&gt;
&lt;br /&gt;
== Adding more inputs ==&lt;br /&gt;
&lt;br /&gt;
The back of the zone mixer is readily accessible by sticking your head into the shelf space and having a strong light source to hand. The inputs are at the right end of the back of the device (or your left, once you&#039;ve stuck your head in the shelf). Input one is the edgemost, input six is nearest the middle.&lt;br /&gt;
&lt;br /&gt;
Make sure any wires you add are cabletied neatly so that the shelf space beneath the zone mixer is still as usable as possible. Additionally, keep the next person to come along happy by labelling your cables at both ends. You will be loved. &lt;br /&gt;
&lt;br /&gt;
== Doing more interesting stuff with the Zone Mixer ==&lt;br /&gt;
&lt;br /&gt;
If you need to mess with the zone mappings, remotes, zone EQs or other more advanced stuff you should unscrew the zone mixer from its brackets and get a better look - the device is completely self-documented in astonishingly detail by diagrams on the top and the bottom of the case - including required wiring configurations for the connectors and other useful stuff to know.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=FOH_Sound&amp;diff=3582</id>
		<title>FOH Sound</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=FOH_Sound&amp;diff=3582"/>
		<updated>2008-07-26T15:57:20Z</updated>

		<summary type="html">&lt;p&gt;Xander: Configuration and maintenance info for the Front of House sound system&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Front Of House Sound System =&lt;br /&gt;
&lt;br /&gt;
Front Of House sound is distributed from a Zone Mixer in the Box Office, secured to the underside of the shelf immediately to the left of the Box Office computer.&lt;br /&gt;
&lt;br /&gt;
The Zone Mixer takes up to six inputs and sends sound to three zones. Each zone can be independently set to play back one of the six inputs.&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-26 the mappings are:&lt;br /&gt;
&lt;br /&gt;
 - Input 1: Unassigned&lt;br /&gt;
 - Input 2: Box Office CD player&lt;br /&gt;
 - Input 3: Box Office Minijack (for iPods, laptops, etc)&lt;br /&gt;
 - Input 4: Unassigned&lt;br /&gt;
 - Input 5: Unassigned&lt;br /&gt;
 - Input 6: Tech Box Feed&lt;br /&gt;
&lt;br /&gt;
 - Zone 1: Café&lt;br /&gt;
 - Zone 2: Box Office&lt;br /&gt;
 - Zone 3: Toilet Corridor&lt;br /&gt;
&lt;br /&gt;
== Mono/Stereo ==&lt;br /&gt;
&lt;br /&gt;
The café is the only zone that has stereo playback - this is a limitation of the Zone Mixer. Additionally, the tech box feed is mono so all playback from the tech box is strictly mono. However, sound from other sources will be in stereo in the café.&lt;br /&gt;
&lt;br /&gt;
== Tech Box Feed ==&lt;br /&gt;
&lt;br /&gt;
The tech box feed enters the box office via a cable on the right side of the box office cupboard door frame.&lt;br /&gt;
&lt;br /&gt;
== Remotes ==&lt;br /&gt;
&lt;br /&gt;
Any zone can be controlled remotely by attaching a (wall-mounted) remote. When the zone is controlled remotely the first two knobs for the zone (input select and volume) no longer have any effect on the mixer (being overridden by the knobs on the remote). As of 2008-07-26, only the café zone is controlled by a remote, on the left wall of the café when facing out. This makes it easier for box office staff to keep the box office and toilet corridor playing from the same input. &lt;br /&gt;
&lt;br /&gt;
== Amplifiers ==&lt;br /&gt;
&lt;br /&gt;
Each zone needs a separate amplifier, all amplifiers are stacked on the floor beneath the zone mixer. The toilet corridor amp is only driving one speaker, this is ideal because the other channel on the amplifier does not work. You make want to take this into account if repurposing the amps.&lt;br /&gt;
&lt;br /&gt;
Don&#039;t change the gains on the amplifiers, use the zone volume knobs instead.&lt;br /&gt;
&lt;br /&gt;
As with the tech box sound system, turn on the zone mixer before turning on the amplifiers. When powering down, turn off the amplifiers before turning off the zone mixer.&lt;br /&gt;
&lt;br /&gt;
== Adding more inputs ==&lt;br /&gt;
&lt;br /&gt;
The back of the zone mixer is readily accessible by sticking your head into the shelf space and having a strong light source to hand. The inputs are at the right end of the back of the device (or your left, once you&#039;ve stuck your head in the shelf). Input one is the edgemost, input six is nearest the middle.&lt;br /&gt;
&lt;br /&gt;
Make sure any wires you add are cabletied neatly so that the shelf space beneath the zone mixer is still as usable as possible. Additionally, keep the next person to come along happy by labelling your cables at both ends. You will be loved. &lt;br /&gt;
&lt;br /&gt;
== Doing more interesting stuff with the Zone Mixer ==&lt;br /&gt;
&lt;br /&gt;
If you need to mess with the zone mappings, remotes, zone EQs or other more advanced stuff you should unscrew the zone mixer from it&#039;s brackets and get a better look - the device is completely self-documented by astonishingly detailed diagrams on the top and the bottom of the case - including required wiring configurations for the connectors and other useful stuff to know.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=Bedlam_Fringe&amp;diff=3581</id>
		<title>Bedlam Fringe</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=Bedlam_Fringe&amp;diff=3581"/>
		<updated>2008-07-26T15:38:36Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* Fringe 2008 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Every August the Bedlam turns professional and opens up as Fringe Venue 49.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s a history of the people involved...&lt;br /&gt;
&lt;br /&gt;
==Fringe 2008==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Colleen Patterson&lt;br /&gt;
*Theatre Manager: Mal Mead&lt;br /&gt;
*Technical Manager: Sam Hansford&lt;br /&gt;
*Press and Publicity Manager: Becs Kamp&lt;br /&gt;
*Business Manager: Fran Walker&lt;br /&gt;
*Graphics Designer: Nick Kay&lt;br /&gt;
*Box Office Managers: Lauren McLeod and Xander Macmillan&lt;br /&gt;
*Cafe Managers: Cat Hobart and Ellie Harrison&lt;br /&gt;
*Box Office Staff: Liz Black, Dylan Read, Fred Gordon, Emma Pattinson, Ellie Richardson, Nicola Hazelton, Lucy Sneddon, Maredith Close&lt;br /&gt;
*Cafe Staff: Amy Brewer, Alex Hatt, Carley Stubbs, Emily Jenkinson&lt;br /&gt;
&lt;br /&gt;
Achievements:&lt;br /&gt;
&lt;br /&gt;
Auditorium: installed new [[seats]], renovated and refinished the rake, laid new carpet&amp;lt;br&amp;gt;&lt;br /&gt;
Renovation of [[cafe]] servery&amp;lt;br&amp;gt;&lt;br /&gt;
Repainted [[office]] and redid [[committee]] pigeonholes&amp;lt;br&amp;gt;&lt;br /&gt;
Reskinned the [[stage]]&amp;lt;br&amp;gt;&lt;br /&gt;
Re-finished the stage&#039;s risers with 18mm plywood&amp;lt;br&amp;gt;&lt;br /&gt;
New Sunday opening times, Sunday afternoons&amp;lt;br&amp;gt;&lt;br /&gt;
Spray painted the [[rig]] black&amp;lt;br&amp;gt;&lt;br /&gt;
Fixed the bulge in the [[cafe]] wall&amp;lt;br&amp;gt;&lt;br /&gt;
Moved the [[lighting store]]&amp;lt;br&amp;gt;&lt;br /&gt;
Partially restored and re-varnished cafe floor&amp;lt;br&amp;gt;&lt;br /&gt;
Rebuilt cafe boards&amp;lt;br&amp;gt;&lt;br /&gt;
Threw out loads of stuff&amp;lt;br&amp;gt;&lt;br /&gt;
Designed new ticketing system&amp;lt;br&amp;gt;&lt;br /&gt;
Fixed [[FOH Sound|FoH Sound System]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fringe 2007==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Matt Wieteska&lt;br /&gt;
*Theatre Manager: Colleen Patterson&lt;br /&gt;
*Technical Manager: Neale Dutton&lt;br /&gt;
*Press and Publicity Manager: Lucy Jackson&lt;br /&gt;
*Graphics Designer: Nick Kay&lt;br /&gt;
*Sponsorship Manager: Becs Kamp&lt;br /&gt;
*Box Office Managers: Alex Hall and Mike Smith&lt;br /&gt;
*Cafe Managers: James &amp;quot;Bruce&amp;quot; Sinclair and Holly Mclay&lt;br /&gt;
*Box Office Staff: Lauren McLeod, Kate Wieteska, Felix Trench, Reg Scott, Chloe Edworthy, Mairi Kellock, Cat Hoyle, Becs Kamp&lt;br /&gt;
*Cafe Staff: Lauren Fried, Becca Day-Preston, Chris Cotter, Craig Hamilton&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Built a wall in the [[auditorium]] to help with soundproofing&lt;br /&gt;
*Reskinned the [[stage]]&lt;br /&gt;
*New [[box office]] printer&lt;br /&gt;
*Installed [[sound]] system&lt;br /&gt;
&lt;br /&gt;
==Fringe 2006==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Charlotte Jarvis&lt;br /&gt;
*Theatre Manager: Alex Engel&lt;br /&gt;
*Technical Manager: Matt Wieteska&lt;br /&gt;
*Press and Publicity Manager: Simon Hodges&lt;br /&gt;
*Graphics Designer: Chris Mounsey&lt;br /&gt;
*Box Office Managers: Helena Larkin and Tom Latter&lt;br /&gt;
*Café Managers: Clemmie Cooke and Charlotte Coles&lt;br /&gt;
*Box Office Staff: Cat Hoyle, James Turner Inman, Richard Shore, Katy Bartholomew, Colleen Patterson, Natalia Prochnicka and Geraldine Heaney &lt;br /&gt;
*Cafe Staff:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Replaced blackout [[curtains]] on [[balcony]] with new black fabric&lt;br /&gt;
*New coffee machine with fancy coffee capabilities for [[cafe]]&lt;br /&gt;
*Built large schedule chalkboards for outside&lt;br /&gt;
*Painted [[office]] white and blue&lt;br /&gt;
*Reskinned the [[stage]]&lt;br /&gt;
&lt;br /&gt;
==Fringe 2005==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Claire Glendenning&lt;br /&gt;
*Theatre Manager: James Turner-Inman&lt;br /&gt;
*Technical Manager: Paul Foxcroft&lt;br /&gt;
*Press and Publicity Manager: Andrew Nielson&lt;br /&gt;
*Graphics Designer: Chris Mounsey&lt;br /&gt;
*Box Office Managers: Heather Hanshaw + Nick Bustin&lt;br /&gt;
*Café Managers: Graeme Wright + Becca Davis&lt;br /&gt;
*Box Office Staff: Jeremy Bidgood, Rob Stott, Rosie Drew, Alex Engel, Charlotte Jarvis&lt;br /&gt;
*Cafe Staff: Emma Drage, &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Replaced carpet in [[auditorium]] with carpet tiles&lt;br /&gt;
*New freezer&lt;br /&gt;
*Improved [[box office]] system with thermal ticket printer and new software&lt;br /&gt;
*Re-hung rig (termtime budget?)&lt;br /&gt;
*Created trus-based awning for front of building (sponsored by Becks)&lt;br /&gt;
*Installed ADSL [[internet connection]], network cabling and wireless network&lt;br /&gt;
*Loads of painting&lt;br /&gt;
*Improved soundproofing in between [[café]] and [[auditorium]] around the door&lt;br /&gt;
*Pimped up the [[office]]&lt;br /&gt;
*New storage solutions in [[techbox]] and [[balcony]] for screws and stuff&lt;br /&gt;
*Various new bits and bobs for the [[café]] e.g. tea light lanterns&lt;br /&gt;
*Purchase of Dog (who is a rabbit) [and is very cute]&lt;br /&gt;
*Re-skinned [[stage]]&lt;br /&gt;
*Sanded down and varnished [[cafe]] floor&lt;br /&gt;
&lt;br /&gt;
==Fringe 2004==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Miriam Raines&lt;br /&gt;
*Theatre Manager: &lt;br /&gt;
*Technical Manager: James Turner-Inman&lt;br /&gt;
*Press and Publicity Manager: &lt;br /&gt;
*Graphics Designer: &lt;br /&gt;
*Box Office Managers: Paul Foxcroft, Martin Cavanagh&lt;br /&gt;
*Café Managers: &lt;br /&gt;
*Box Office Staff: &lt;br /&gt;
*Cafe Staff: &lt;br /&gt;
&lt;br /&gt;
==Fringe 2003==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Cat Smith&lt;br /&gt;
*Theatre Manager: Jono Ellis&lt;br /&gt;
*Technical Manager: Matt Ling&lt;br /&gt;
*Press and Publicity Manager: Sarah Cook&lt;br /&gt;
*Graphics Designer/Website: Neil E. Hobbs&lt;br /&gt;
*Box Office Managers: Alison Timms and Kirsten Morris&lt;br /&gt;
*Café Managers: Victoria Tills and Kati Hind&lt;br /&gt;
*Box Office Staff: &lt;br /&gt;
*Cafe Staff:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
*New potato oven and chiller cabinet for [[cafe]]&lt;br /&gt;
*New [[sound]] system - two speakers, mini disc players, new MC2 amp, graphics - paid for by profit from Fringe 2002 (!)&lt;br /&gt;
*New level in [[costume cupboard]] - see graffiti!&lt;br /&gt;
*Skinned [[stage cupboard]] for the first time and removed wall and rail allowing it to become a stage pit&lt;br /&gt;
*Redid [[cafe]] and [[toilets]]&lt;br /&gt;
*Installed fan in [[cafe]] to improve ventilation&lt;br /&gt;
*Obtained two microwaves &lt;br /&gt;
*Redid [[kitchen]] - repainted and tiled walls, obtained new oven and hobs&lt;br /&gt;
*Cut down number of [[EUTC]] slots to two&lt;br /&gt;
*Held first [[FOB]] [[A_to_Z#AGM_-_Annual_General_Meeting|AGM]]&lt;br /&gt;
*Held first full preview week schedule&lt;br /&gt;
*Held art exhibition in collabaration with ECA&lt;br /&gt;
*Bought picnic table to extend [[cafe]] area (buy a new one!)&lt;br /&gt;
*Made more money than Graeme Timms (sorry long standing debate!)&lt;br /&gt;
&lt;br /&gt;
==Fringe 2002==&lt;br /&gt;
&lt;br /&gt;
*Fringe Venue Manager: Graeme Timms&lt;br /&gt;
*Theatre Manager: Richard Hogg&lt;br /&gt;
*Technical Manager: Matt Gray&lt;br /&gt;
*Press and Publicity Manager: Neil E. Hobbs&lt;br /&gt;
*Graphics Designer/Website: Neil E. Hobbs&lt;br /&gt;
*Box Office Managers: Pete Lowden and Sarah Kerr&lt;br /&gt;
*Café Managers: Cat Smith and Rachel Mountfield&lt;br /&gt;
*Box Office Staff: &lt;br /&gt;
*Cafe Staff:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Achievements:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
*Replaced damaged floorboards on [[stage]] during re-skinning&lt;br /&gt;
*Dug out back passage and laid path and red chips round that side of building&lt;br /&gt;
*Re-built [[box office]] counter&lt;br /&gt;
*Installed Tramp-Cam&lt;br /&gt;
*Much re-wiring of light fittings and sockets&lt;br /&gt;
*Computerised the [[Box office]] ticketing system&lt;br /&gt;
*Built the Info-Cat - (He never quite became a cat)&lt;br /&gt;
*Replaced lighting in [[toilets]]&lt;br /&gt;
*Rebranded &#039;&#039;&#039;Bedlam Fringe&#039;&#039;&#039; as a separate entity from term-time operation&lt;br /&gt;
*First website with up-to-date reviews, show info, etc&lt;br /&gt;
*Much painting&lt;br /&gt;
*Consumption of the more Caley Golden Promise that the Cash and Carry could stock!!&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3578</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3578"/>
		<updated>2008-07-25T17:38:15Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* What I plan to write about */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Key Concepts and Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
*** How XTS handles times between 0AM and 3AM.&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** Database&lt;br /&gt;
*** Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3577</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3577"/>
		<updated>2008-07-25T17:34:23Z</updated>

		<summary type="html">&lt;p&gt;Xander: /* General Errors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= XTS Application Programming Interface =&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= General Errors = &lt;br /&gt;
These errors can occur when calling any command, or when calling a command incorrectly. Errors are returned as an [[#&amp;lt;error&amp;gt;]] document.&lt;br /&gt;
* &#039;&#039;&#039;401 notAuthorised&#039;&#039;&#039; You are not authorised to perform the action. You may need to supply a password, or it might simply be impossible to do what you want to do from the machine you&#039;re on.&lt;br /&gt;
* &#039;&#039;&#039;400.1 unrecognisedCommand&#039;&#039;&#039; The command is not recognised. Either you spelled it wrong, the API has changed since the documentation was written or you&#039;re simply doing it wrong.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Commands = &lt;br /&gt;
&lt;br /&gt;
== getshows ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A &amp;lt;shows&amp;gt; document containing [[#&amp;lt;showsummary&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
== getshow ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
== getperformances ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get the performances of.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A &amp;lt;performances&amp;gt; document containing [[#&amp;lt;performance&amp;gt;]]s representing all performances for the specified show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
== getperformance ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;performanceid&#039;&#039;&#039; The ID of the performance to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;performance&amp;gt;]] representing the performance.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.2 performanceNotFound&#039;&#039;&#039; if the performance doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= XML =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;error&amp;gt; ==&lt;br /&gt;
Details an error that occured while processing your request.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;@type&#039;&#039;&#039; The type number of the error, consists of a major and an (optional) minor part separated by a decimal point.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;message&amp;gt;&#039;&#039;&#039; A human-readable description of the error.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;error type=&amp;quot;400.1&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;message&amp;gt;Unrecognised command.&amp;lt;/message&amp;gt;&lt;br /&gt;
  &amp;lt;/error&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;showsummary&amp;gt; ==&lt;br /&gt;
Gives some summary details about a show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;showsummary&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Alice In Wonderland&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Texas Woman&#039;s University&amp;lt;/tagline&amp;gt;&lt;br /&gt;
  &amp;lt;/showsummary&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;show&amp;gt; ==&lt;br /&gt;
A &amp;lt;show&amp;gt; tag describes a single show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;description&amp;gt;&#039;&#039;&#039; The show&#039;s description, if supplied. The usefulness of this field is debatable. I imagined it would carry publicity information that could be insta-formatted into web pages on the Bedlam Theatre website. Perhaps we should leave this tag as &amp;quot;reserved for future deprecation&amp;quot;.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;show&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;15&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Assassins&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Rather Like a Shark/DULOG&amp;lt;/tagline&amp;gt;&lt;br /&gt;
    &amp;lt;description/&amp;gt;&lt;br /&gt;
  &amp;lt;/show&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;performance&amp;gt; ==&lt;br /&gt;
A &amp;lt;performance&amp;gt; tag describes a single performance in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the performance.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;showid&amp;gt;&#039;&#039;&#039; The ID of the performance.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;start&amp;gt;&#039;&#039;&#039; The start time of the performance in seconds since the UNIX epoch.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;startdatetime&amp;gt;&#039;&#039;&#039; The human-readable start time of the performance.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tickets&amp;gt;&#039;&#039;&#039; Ticket details incorporating:&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;total&amp;gt;&#039;&#039;&#039; The total number of seats for the performance (ie the maximum number of tickets that can be sold).&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;sold&amp;gt;&#039;&#039;&#039; The number of tickets that have been sold (net).&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;booked&amp;gt;&#039;&#039;&#039; The number of tickets that are still booked (ie, awaiting collection).&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;heldback&amp;gt;&#039;&#039;&#039; The number of tickets that are held back, ie, reserved for later sale.&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;remaining&amp;gt;&#039;&#039;&#039; The number of tickets that are immediately available for sale.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;performance&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;showid&amp;gt;1&amp;lt;/showid&amp;gt;&lt;br /&gt;
    &amp;lt;start&amp;gt;1217841300&amp;lt;/start&amp;gt;&lt;br /&gt;
    &amp;lt;startdatetime&amp;gt;2008-08-04 10:15&amp;lt;/startdatetime&amp;gt;&lt;br /&gt;
    &amp;lt;tickets&amp;gt;&lt;br /&gt;
      &amp;lt;total&amp;gt;90&amp;lt;/total&amp;gt;&lt;br /&gt;
      &amp;lt;sold&amp;gt;0&amp;lt;/sold&amp;gt;&lt;br /&gt;
      &amp;lt;booked&amp;gt;1&amp;lt;/booked&amp;gt;&lt;br /&gt;
      &amp;lt;heldback&amp;gt;18&amp;lt;/heldback&amp;gt;&lt;br /&gt;
      &amp;lt;remaining&amp;gt;71&amp;lt;/remaining&amp;gt;&lt;br /&gt;
    &amp;lt;/tickets&amp;gt;&lt;br /&gt;
  &amp;lt;/performance&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3576</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3576"/>
		<updated>2008-07-18T17:21:17Z</updated>

		<summary type="html">&lt;p&gt;Xander: This will do for today.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= XTS Application Programming Interface =&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= General Errors = &lt;br /&gt;
These errors can occur when calling any command, or when calling a command incorrectly. Errors are returned as an [[#&amp;lt;error&amp;gt;] document.&lt;br /&gt;
* &#039;&#039;&#039;401 notAuthorised&#039;&#039;&#039; You are not authorised to perform the action. You may need to supply a password, or it might simply be impossible to do what you want to do from the machine you&#039;re on.&lt;br /&gt;
* &#039;&#039;&#039;400.1 unrecognisedCommand&#039;&#039;&#039; The command is not recognised. Either you spelled it wrong, the API has changed since the documentation was written or you&#039;re simply doing it wrong.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= Commands = &lt;br /&gt;
&lt;br /&gt;
== getshows ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A &amp;lt;shows&amp;gt; document containing [[#&amp;lt;showsummary&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
== getshow ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
== getperformances ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get the performances of.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A &amp;lt;performances&amp;gt; document containing [[#&amp;lt;performance&amp;gt;]]s representing all performances for the specified show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
== getperformance ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;performanceid&#039;&#039;&#039; The ID of the performance to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;performance&amp;gt;]] representing the performance.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.2 performanceNotFound&#039;&#039;&#039; if the performance doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= XML =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;error&amp;gt; ==&lt;br /&gt;
Details an error that occured while processing your request.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;@type&#039;&#039;&#039; The type number of the error, consists of a major and an (optional) minor part separated by a decimal point.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;message&amp;gt;&#039;&#039;&#039; A human-readable description of the error.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;error type=&amp;quot;400.1&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;message&amp;gt;Unrecognised command.&amp;lt;/message&amp;gt;&lt;br /&gt;
  &amp;lt;/error&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;showsummary&amp;gt; ==&lt;br /&gt;
Gives some summary details about a show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;showsummary&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Alice In Wonderland&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Texas Woman&#039;s University&amp;lt;/tagline&amp;gt;&lt;br /&gt;
  &amp;lt;/showsummary&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;show&amp;gt; ==&lt;br /&gt;
A &amp;lt;show&amp;gt; tag describes a single show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;description&amp;gt;&#039;&#039;&#039; The show&#039;s description, if supplied. The usefulness of this field is debatable. I imagined it would carry publicity information that could be insta-formatted into web pages on the Bedlam Theatre website. Perhaps we should leave this tag as &amp;quot;reserved for future deprecation&amp;quot;.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;show&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;15&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Assassins&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Rather Like a Shark/DULOG&amp;lt;/tagline&amp;gt;&lt;br /&gt;
    &amp;lt;description/&amp;gt;&lt;br /&gt;
  &amp;lt;/show&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;performance&amp;gt; ==&lt;br /&gt;
A &amp;lt;performance&amp;gt; tag describes a single performance in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the performance.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;showid&amp;gt;&#039;&#039;&#039; The ID of the performance.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;start&amp;gt;&#039;&#039;&#039; The start time of the performance in seconds since the UNIX epoch.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;startdatetime&amp;gt;&#039;&#039;&#039; The human-readable start time of the performance.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tickets&amp;gt;&#039;&#039;&#039; Ticket details incorporating:&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;total&amp;gt;&#039;&#039;&#039; The total number of seats for the performance (ie the maximum number of tickets that can be sold).&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;sold&amp;gt;&#039;&#039;&#039; The number of tickets that have been sold (net).&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;booked&amp;gt;&#039;&#039;&#039; The number of tickets that are still booked (ie, awaiting collection).&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;heldback&amp;gt;&#039;&#039;&#039; The number of tickets that are held back, ie, reserved for later sale.&lt;br /&gt;
** &#039;&#039;&#039;&amp;lt;remaining&amp;gt;&#039;&#039;&#039; The number of tickets that are immediately available for sale.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;performance&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;showid&amp;gt;1&amp;lt;/showid&amp;gt;&lt;br /&gt;
    &amp;lt;start&amp;gt;1217841300&amp;lt;/start&amp;gt;&lt;br /&gt;
    &amp;lt;startdatetime&amp;gt;2008-08-04 10:15&amp;lt;/startdatetime&amp;gt;&lt;br /&gt;
    &amp;lt;tickets&amp;gt;&lt;br /&gt;
      &amp;lt;total&amp;gt;90&amp;lt;/total&amp;gt;&lt;br /&gt;
      &amp;lt;sold&amp;gt;0&amp;lt;/sold&amp;gt;&lt;br /&gt;
      &amp;lt;booked&amp;gt;1&amp;lt;/booked&amp;gt;&lt;br /&gt;
      &amp;lt;heldback&amp;gt;18&amp;lt;/heldback&amp;gt;&lt;br /&gt;
      &amp;lt;remaining&amp;gt;71&amp;lt;/remaining&amp;gt;&lt;br /&gt;
    &amp;lt;/tickets&amp;gt;&lt;br /&gt;
  &amp;lt;/performance&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3575</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3575"/>
		<updated>2008-07-18T17:03:17Z</updated>

		<summary type="html">&lt;p&gt;Xander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= XTS Application Programming Interface =&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= General Errors = &lt;br /&gt;
These errors can occur when calling any command, or when calling a command incorrectly. Errors are returned as an [[#&amp;lt;error&amp;gt;] document.&lt;br /&gt;
* &#039;&#039;&#039;401 notAuthorised&#039;&#039;&#039; You are not authorised to perform the action. You may need to supply a password, or it might simply be impossible to do what you want to do from the machine you&#039;re on.&lt;br /&gt;
* &#039;&#039;&#039;400.1 unrecognisedCommand&#039;&#039;&#039; The command is not recognised. Either you spelled it wrong, the API has changed since the documentation was written or you&#039;re simply doing it wrong.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= Commands = &lt;br /&gt;
&lt;br /&gt;
== getshows ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A &amp;lt;shows&amp;gt; tag containing [[#&amp;lt;showsummary&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
== getshow ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= XML =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;error&amp;gt; ==&lt;br /&gt;
Details an error that occured while processing your request.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;@type&#039;&#039;&#039; The type number of the error, consists of a major and an (optional) minor part separated by a decimal point.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;message&amp;gt;&#039;&#039;&#039; A human-readable description of the error.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;error type=&amp;quot;400.1&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;message&amp;gt;Unrecognised command.&amp;lt;/message&amp;gt;&lt;br /&gt;
  &amp;lt;/error&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;showsummary&amp;gt; ==&lt;br /&gt;
Gives some summary details about a show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;showsummary&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Alice In Wonderland&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Texas Woman&#039;s University&amp;lt;/tagline&amp;gt;&lt;br /&gt;
  &amp;lt;/showsummary&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;show&amp;gt; ==&lt;br /&gt;
A &amp;lt;show&amp;gt; tag describes a single show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;description&amp;gt;&#039;&#039;&#039; The show&#039;s description, if supplied. The usefulness of this field is debatable. I imagined it would carry publicity information that could be insta-formatted into web pages on the Bedlam Theatre website. Perhaps we should leave this tag as &amp;quot;reserved for future deprecation&amp;quot;.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;show&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;15&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Assassins&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Rather Like a Shark/DULOG&amp;lt;/tagline&amp;gt;&lt;br /&gt;
    &amp;lt;description/&amp;gt;&lt;br /&gt;
  &amp;lt;/show&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3574</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3574"/>
		<updated>2008-07-18T17:02:27Z</updated>

		<summary type="html">&lt;p&gt;Xander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== XTS Application Programming Interface ==&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= General Errors = &lt;br /&gt;
These errors can occur when calling any command, or when calling a command incorrectly. Errors are returned as an [[#&amp;lt;error&amp;gt;] document.&lt;br /&gt;
* &#039;&#039;&#039;401 notAuthorised&#039;&#039;&#039; You are not authorised to perform the action. You may need to supply a password, or it might simply be impossible to do what you want to do from the machine you&#039;re on.&lt;br /&gt;
* &#039;&#039;&#039;400.1 unrecognisedCommand&#039;&#039;&#039; The command is not recognised. Either you spelled it wrong, the API has changed since the documentation was written or you&#039;re simply doing it wrong.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= Commands = &lt;br /&gt;
&lt;br /&gt;
== getshows ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A &amp;lt;shows&amp;gt; tag containing [[#&amp;lt;showsummary&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
== getshow ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
= XML =&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;error&amp;gt; ==&lt;br /&gt;
Details an error that occured while processing your request.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;@type&#039;&#039;&#039; The type number of the error, consists of a major and an (optional) minor part separated by a decimal point.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;message&amp;gt;&#039;&#039;&#039; A human-readable description of the error.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;error type=&amp;quot;400.1&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;message&amp;gt;Unrecognised command.&amp;lt;/message&amp;gt;&lt;br /&gt;
  &amp;lt;/error&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;showsummary&amp;gt; ==&lt;br /&gt;
Gives some summary details about a show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;showsummary&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Alice In Wonderland&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Texas Woman&#039;s University&amp;lt;/tagline&amp;gt;&lt;br /&gt;
  &amp;lt;/showsummary&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;show&amp;gt; ==&lt;br /&gt;
A &amp;lt;show&amp;gt; tag describes a single show in the database.&lt;br /&gt;
=== Elements ===&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;id&amp;gt;&#039;&#039;&#039; The ID of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;name&amp;gt;&#039;&#039;&#039; The name of the show.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tagline&amp;gt;&#039;&#039;&#039; The show&#039;s tagline / strapline / subtitle.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;description&amp;gt;&#039;&#039;&#039; The show&#039;s description, if supplied. The usefulness of this field is debatable. I imagined it would carry publicity information that could be insta-formatted into web pages on the Bedlam Theatre website. Perhaps we should leave this tag as &amp;quot;reserved for future deprecation&amp;quot;.&lt;br /&gt;
=== Example ===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
  &amp;lt;show&amp;gt;&lt;br /&gt;
    &amp;lt;id&amp;gt;15&amp;lt;/id&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Assassins&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;tagline&amp;gt;Rather Like a Shark/DULOG&amp;lt;/tagline&amp;gt;&lt;br /&gt;
    &amp;lt;description/&amp;gt;&lt;br /&gt;
  &amp;lt;/show&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3573</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3573"/>
		<updated>2008-07-18T16:44:57Z</updated>

		<summary type="html">&lt;p&gt;Xander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== XTS Application Programming Interface ==&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== getshows ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
=== Returns ===&lt;br /&gt;
&amp;lt;shows&amp;gt; containing [[#&amp;lt;show&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
== getshow ==&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
=== Returns ===&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
=== Errors ===&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3572</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3572"/>
		<updated>2008-07-18T16:42:01Z</updated>

		<summary type="html">&lt;p&gt;Xander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== XTS Application Programming Interface ==&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== getshows ===&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
==== Returns ====&lt;br /&gt;
&amp;lt;shows&amp;gt; containing [[#&amp;lt;show&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
==== Errors ====&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
=== getshow ===&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
==== Returns ====&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
==== Errors ====&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3571</id>
		<title>XTS API</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS_API&amp;diff=3571"/>
		<updated>2008-07-18T16:41:22Z</updated>

		<summary type="html">&lt;p&gt;Xander: This may also take a while.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== XTS Application Programming Interface ==&lt;br /&gt;
&lt;br /&gt;
Correct (though incomplete) as of 2008-07-18 (RC1 &amp;quot;Fat Cat&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== getshows ===&lt;br /&gt;
== Parameters ==&lt;br /&gt;
* No parameters (yet)&lt;br /&gt;
== Returns ==&lt;br /&gt;
&amp;lt;shows&amp;gt; containing [[#&amp;lt;show&amp;gt;]]s representing all shows in the database.&lt;br /&gt;
== Errors ==&lt;br /&gt;
* Never returns an error.&lt;br /&gt;
&lt;br /&gt;
=== getshow ===&lt;br /&gt;
== Parameters ==&lt;br /&gt;
* &#039;&#039;&#039;showid&#039;&#039;&#039; The ID of the show to get.&lt;br /&gt;
== Returns ==&lt;br /&gt;
A [[#&amp;lt;show&amp;gt;]] representing the show.&lt;br /&gt;
== Errors ==&lt;br /&gt;
* &#039;&#039;&#039;404.3 showNotFound&#039;&#039;&#039; if the show doesn&#039;t exist in the database.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
	<entry>
		<id>http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3570</id>
		<title>XTS</title>
		<link rel="alternate" type="text/html" href="http://wiki.friendsofbedlam.co.uk/index.php?title=XTS&amp;diff=3570"/>
		<updated>2008-07-18T16:32:16Z</updated>

		<summary type="html">&lt;p&gt;Xander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== eXtensible Ticketing System ==&lt;br /&gt;
&lt;br /&gt;
This page is a stub. I intend to document as much of the ticketing system as possible but keep forgetting things that I want to write about. Until it&#039;s completed, here&#039;s a list of sections that I intend to write under. This article is currently aimed at people who want to maintain the source code, NOT people who want to learn how to sell tickets.&lt;br /&gt;
&lt;br /&gt;
== What I plan to write about ==&lt;br /&gt;
&lt;br /&gt;
* History / Motivation&lt;br /&gt;
* Things you should know before you start&lt;br /&gt;
** Terminology&lt;br /&gt;
*** &amp;quot;Reserved&amp;quot; vs. &amp;quot;Booked&amp;quot;.&lt;br /&gt;
*** &amp;quot;Holding&amp;quot; tickets.&lt;br /&gt;
*** &amp;quot;Ticket Prototypes&amp;quot;&lt;br /&gt;
*** &amp;quot;Snewts&amp;quot;&lt;br /&gt;
** Principles&lt;br /&gt;
*** Portability (OS Transparency)&lt;br /&gt;
*** Accessibility (Network Transparency)&lt;br /&gt;
*** Extensibility&lt;br /&gt;
*** Readability&lt;br /&gt;
*** Simplicity (Minimum Complexity in the Layers that Matter)&lt;br /&gt;
*** High-Level Scripting&lt;br /&gt;
* Technologies in use&lt;br /&gt;
** HTTP&lt;br /&gt;
** XML&lt;br /&gt;
** HTML&lt;br /&gt;
** CSS&lt;br /&gt;
** Python&lt;br /&gt;
** Java&lt;br /&gt;
* Parts of the system&lt;br /&gt;
** Database&lt;br /&gt;
*** Scheduled Database Backup&lt;br /&gt;
** DONE Ticket Server&lt;br /&gt;
*** DONE Web.py&lt;br /&gt;
*** DONE API&lt;br /&gt;
** Print Server&lt;br /&gt;
*** API&lt;br /&gt;
*** Making new ticket layouts&lt;br /&gt;
*** Changing the ticket logo&lt;br /&gt;
** Static Server&lt;br /&gt;
*** Apache 2.2&lt;br /&gt;
** Administration Server&lt;br /&gt;
** Javascript Client&lt;br /&gt;
*** Ami&lt;br /&gt;
*** Snewts&lt;br /&gt;
*** Prism&lt;br /&gt;
** Reporting&lt;br /&gt;
*** XSLT&lt;br /&gt;
** HTTPProxy&lt;br /&gt;
*** Protecting the ticketing server from the proxy&lt;br /&gt;
** Startup - Windows Services&lt;br /&gt;
*** JSWrapper&lt;br /&gt;
* Directory Structure (C:\XTS\)&lt;br /&gt;
* Installing XTS&lt;br /&gt;
* Making Improvements - A HOWTO&lt;br /&gt;
** Known Issues / Things you might like to work on&lt;br /&gt;
*** Sniffing attacks&lt;br /&gt;
*** No test suite, no TDD&lt;br /&gt;
*** Transactions (there aren&#039;t any)&lt;br /&gt;
*** Printing - it&#039;s pretty crap&lt;br /&gt;
*** Reports - XSLT, but not as it should be&lt;br /&gt;
** Familiarisation&lt;br /&gt;
*** Grokking the Source&lt;br /&gt;
** Tools You Must Use&lt;br /&gt;
*** Firebug&lt;br /&gt;
*** IPython&lt;br /&gt;
** Things You Must Do&lt;br /&gt;
*** Setting up your own dev version from trunk&lt;br /&gt;
*** Working on a test data set&lt;br /&gt;
*** Keeping the documentation up-to-date&lt;br /&gt;
** Safe and Unsafe&lt;br /&gt;
*** Where is the money?&lt;br /&gt;
** Versioning&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
&lt;br /&gt;
== Parts of the System ==&lt;br /&gt;
&lt;br /&gt;
=== Database ===&lt;br /&gt;
&lt;br /&gt;
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through [[#web.py]]&#039;s db module but there may be some report-generating SQL queries that are specific to MySQL in the XTS source. See [[#data.py]] for more info.&lt;br /&gt;
&lt;br /&gt;
The schema is called &amp;quot;xts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Scheduled Database Backups ====&lt;br /&gt;
&lt;br /&gt;
As of 2008-07-18, [[Maude]] is configured to take nightly backups of the XTS database to C:\XTS\Backups. These backups should be scaled back to weeklies or slower at the end of Fringe 2008 or they &#039;&#039;&#039;will&#039;&#039;&#039; eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up &amp;quot;off-site&amp;quot; in case of hard disk failure.&lt;br /&gt;
&lt;br /&gt;
=== Ticket Server ===&lt;br /&gt;
&lt;br /&gt;
The ticket server does the hard work of allocating, booking and selling tickets of various types for various performances of various shows. The ticket server is written in [[#Python]]. It is implemented on top of a web server ([http://www.webpy.org web.py]]), allowing clients to interact with the server via [[#HTTP]] using [[#XML]] for data exchange.&lt;br /&gt;
&lt;br /&gt;
==== API ====&lt;br /&gt;
&lt;br /&gt;
API stands for Application Programming Interface. It tells you how you can write programs that talk to the ticket server in order to do useful things (like get show information, or sell tickets online).&lt;br /&gt;
&lt;br /&gt;
The [[#Javascript Client]] uses the XTS API to make a nice box office interface for selling tickets to customers.&lt;br /&gt;
&lt;br /&gt;
If you know a little XML and HTTP you can write programs that interact with the API yourself.&lt;br /&gt;
&lt;br /&gt;
See [[XTS API]] for further information and full documentation.&lt;br /&gt;
&lt;br /&gt;
==== Security ====&lt;br /&gt;
&lt;br /&gt;
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the [[XTS API|API documentation]].&lt;br /&gt;
&lt;br /&gt;
==== Error Handling ====&lt;br /&gt;
&lt;br /&gt;
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors are caught by the request dispatcher (snewtsUrlInvocation in server.py) and turned into an XML-formatted error that is sent back to the client.&lt;br /&gt;
&lt;br /&gt;
SnewtsErrors consist of an error number (useful to computers) and an error message (useful to people). Errors are grouped into types. For instance, all errors that start with the number 404 represent a requested thing not being there (&amp;quot;Not Found&amp;quot;). However, 404.1 specifically means that it was a ticket that wasn&#039;t found. 404.2 means a performance wasn&#039;t found and so on.&lt;br /&gt;
&lt;br /&gt;
This is important when writing software that talk to the ticket server via the [[#API]]. When reading responses from the server the client software can have a default way of handling 404 errors but additionally can have a specific way of handling 404.5 errors.&lt;br /&gt;
&lt;br /&gt;
Where possible, error numbers correspond to the [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html HTTP status code definitions]. This is mostly because I&#039;m perverse and think it&#039;s funny that when something isn&#039;t there you get a 404 error. However, it can be useful when writing your client software in that a 4xx error indicates that the client probably did something wrong whereas 5xx errors indicate that something went wrong on the server (which is potentially much more serious).&lt;br /&gt;
&lt;br /&gt;
==== Source ====&lt;br /&gt;
&lt;br /&gt;
Alphabetically:&lt;br /&gt;
&lt;br /&gt;
===== constants.py =====&lt;br /&gt;
&lt;br /&gt;
Contains various useful constants used in the rest of the XTS source. This makes the code more readable. In the database, the number 2 represents a ticket that is booked. However, instead of using the number 2 to refer to such tickets in the source code, we use the expression &amp;lt;code&amp;gt;ticketstates[&#039;BOOKED&#039;]&amp;lt;/code&amp;gt;. This makes the code (a lot) more readable.&lt;br /&gt;
&lt;br /&gt;
Funnily enough, it&#039;s generally a bad idea to change the constants. However, you should add to them where appropriate, for instance, if you intend to record new kinds of events in the log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;There is nothing technically &#039;&#039;&#039;constant&#039;&#039;&#039; about the variables in constants.py - they could easily be modified at runtime. If you know how to define constants that are actually constant, or just of a better general approach, then this might be an area of the server that you could improve.&#039;&#039;&lt;br /&gt;
--[[User:Xander|Xander]] 17:21, 18 July 2008 (BST)&lt;br /&gt;
&lt;br /&gt;
===== data.py =====&lt;br /&gt;
&lt;br /&gt;
data.py provides an interface to the database. Wherever XTS needs to get information from the database, it does it by calling a function in data.py. data.py then takes care of turning the information request into SQL, and if necessary, post-processing the response into a useful form for the caller.&lt;br /&gt;
&lt;br /&gt;
You should be able to port XTS to another datastore simply by replacing data.py.&lt;br /&gt;
&lt;br /&gt;
===== exceptions.py =====&lt;br /&gt;
&lt;br /&gt;
exceptions.py defines the SnewtsError exception type. For more information, see [[#Error_Handling]].&lt;br /&gt;
&lt;br /&gt;
===== helpers.py =====&lt;br /&gt;
&lt;br /&gt;
helpers.py contains various functions that help to solve common and recurring problems in the Snewts application (for instance, turning datetime objects into human-readable date strings). This unclutters [[#logic.py]], which should just contain the business logic of how to sell tickets properly. Functions in helpers.py should ideally be moved into [[#XWF]], but who really cares?&lt;br /&gt;
&lt;br /&gt;
===== logic.py =====&lt;br /&gt;
&lt;br /&gt;
logic.py sits between the client request and the database. When the client asks to sell a ticket, logic.py makes sure that the show actually exists, the ticket is valid for the performance, there are enough tickets left and anything else that needs making sure of. If any one bit of XTS is going to get something critically wrong, it&#039;s going to be in logic.py.&lt;br /&gt;
&lt;br /&gt;
logic.py never talks to the database directly. To get data from the database and make changes to the database it must call functions in [[#data.py]].&lt;br /&gt;
&lt;br /&gt;
===== printer.py =====&lt;br /&gt;
&lt;br /&gt;
printer.py is an abstraction layer with one synchronous public function, printTicket(). It takes care of sending the ticket to the printer and making sure that the printer got the ticket. If the print can&#039;t be confirmed it throws a SnewtsError.&lt;br /&gt;
&lt;br /&gt;
===== report.py =====&lt;br /&gt;
&lt;br /&gt;
report.py contains all of the code that formats statistics gathered from the database into XML reports. It also does a little math. See [[#Reporting]].&lt;br /&gt;
&lt;br /&gt;
===== snewts.py =====&lt;br /&gt;
&lt;br /&gt;
snewts.py does the job of recognising requests from clients, checking that the clients are authorised to make the requests, and sending back responses. Simple requests (ie. getPerformances) are fulfilled by getting data from [[#data.py]] directly. More complicated requests are fulfilled by calling business logic in [[#logic.py]] or getting [[#report.py]] to generate reports.&lt;br /&gt;
&lt;br /&gt;
===== status.py =====&lt;br /&gt;
&lt;br /&gt;
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you&#039;re writing client software, you need to anticipate these coming back at you.&lt;/div&gt;</summary>
		<author><name>Xander</name></author>
	</entry>
</feed>