XTS
Contents
eXtensible Ticketing System
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's completed, here'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.
What I plan to write about
- History / Motivation
- Things you should know before you start
- Key Concepts and Terminology
- "Reserved" vs. "Booked".
- "Holding" tickets.
- "Ticket Prototypes"
- "Snewts"
- How XTS handles times between 0AM and 3AM.
- Principles
- Portability (OS Transparency)
- Accessibility (Network Transparency)
- Extensibility
- Readability
- Simplicity (Minimum Complexity in the Layers that Matter)
- High-Level Scripting
- Key Concepts and Terminology
- Technologies in use
- HTTP
- XML
- HTML
- CSS
- Python
- Java
- Parts of the system
- Database
- Scheduled Database Backup
- DONE Ticket Server
- DONE Web.py
- DONE API
- Print Server
- API
- Making new ticket layouts
- Changing the ticket logo
- Static Server
- Apache 2.2
- Administration Server
- Javascript Client
- Ami
- Snewts
- Prism
- Reporting
- XSLT
- HTTPProxy
- Protecting the ticketing server from the proxy
- Startup - Windows Services
- JSWrapper
- Database
- Directory Structure (C:\XTS\)
- Installing XTS
- Making Improvements - A HOWTO
- Known Issues / Things you might like to work on
- Sniffing attacks
- No test suite, no TDD
- Transactions (there aren't any)
- Printing - it's pretty crap
- Reports - XSLT, but not as it should be
- Familiarisation
- Grokking the Source
- Tools You Must Use
- Firebug
- IPython
- Things You Must Do
- Setting up your own dev version from trunk
- Working on a test data set
- Keeping the documentation up-to-date
- Safe and Unsafe
- Where is the money?
- Versioning
- Known Issues / Things you might like to work on
Documentation
Parts of the System
Database
XTS uses a MySQL database. It should be very easy to port XTS to other databases, most access is abstracted through #web.py'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.
The schema is called "xts".
Scheduled Database Backups
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 will eventually consume all available disk space on the machine. Furthermore the database should occasionally be backed up "off-site" in case of hard disk failure.
Ticket Server
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 (web.py]), allowing clients to interact with the server via #HTTP using #XML for data exchange.
API
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).
The #Javascript Client uses the XTS API to make a nice box office interface for selling tickets to customers.
If you know a little XML and HTTP you can write programs that interact with the API yourself.
See XTS API for further information and full documentation.
Security
The ticket server uses host and password authentication to decide who can do what using the API. Full details are in the API documentation.
Error Handling
When the server encounters an error (for instance, a ticket that you are selling has already been sold), internally it throws a SnewtsError exception.
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.
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 ("Not Found"). However, 404.1 specifically means that it was a ticket that wasn't found. 404.2 means a performance wasn't found and so on.
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.
Where possible, error numbers correspond to the HTTP status code definitions. This is mostly because I'm perverse and think it's funny that when something isn'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).
Source
Alphabetically:
constants.py
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 ticketstates['BOOKED']
. This makes the code (a lot) more readable.
Funnily enough, it'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.
There is nothing technically constant 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. --Xander 17:21, 18 July 2008 (BST)
data.py
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.
You should be able to port XTS to another datastore simply by replacing data.py.
exceptions.py
exceptions.py defines the SnewtsError exception type. For more information, see #Error_Handling.
helpers.py
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?
logic.py
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's going to be in logic.py.
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.
printer.py
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't be confirmed it throws a SnewtsError.
report.py
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.
snewts.py
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.
status.py
status.py contains definitions of all of the errors that XTS may reply with when something goes wrong. If you're writing client software, you need to anticipate these coming back at you.