From 06c387b295f3f49337e02a1a1a3fa7760d8c5573 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Sat, 4 Oct 2014 22:09:20 +0200 Subject: [PATCH] Update documentation --- doc/conf.py | 16 +++-- doc/development/concepts.rst | 125 +++++++++++++++++++++++++++++------ doc/development/setup.rst | 49 ++++++++++---- doc/requirements.txt | 1 + 4 files changed, 155 insertions(+), 36 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index d7f9a08daa..c90f03bcfc 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -104,7 +104,7 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'haiku' +#html_theme = "" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -156,10 +156,10 @@ html_static_path = ['_static'] #html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +html_domain_indices = False # If false, no index is generated. -#html_use_index = True +html_use_index = False # If true, the index is split into individual pages for each letter. #html_split_index = False @@ -184,15 +184,21 @@ html_static_path = ['_static'] # Output file base name for HTML help builder. htmlhelp_basename = 'tixldoc' +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +if not on_rtd: # only import and set the theme if we're building docs locally + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', + 'papersize': 'a4paper', # The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', + 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', diff --git a/doc/development/concepts.rst b/doc/development/concepts.rst index c321d3461f..f9c3b78c81 100644 --- a/doc/development/concepts.rst +++ b/doc/development/concepts.rst @@ -4,46 +4,133 @@ Implementation Concepts Basic terminology ----------------- +The components +^^^^^^^^^^^^^^ + +The project tixl is split into several components. The main three of them are: + +**tixlbase** + Tixlbase is the foundation below all other components. It is primarily + responsible for the data structures and database communication. It also hosts + several utilities which are used by multiple other components. + +**tixlcontrol** + Tixlcontrol is the web-based backend software which allows organizers to + create and manage their events, items, orders and tickets. + +**tixlpresale** + Tixlpresale is the ticket-shop itself, containing all the parts visible to the + end user. + Users and events ^^^^^^^^^^^^^^^^ -Tixl is all about **events**, which are defined as something happening somewhere. Every Event is managed by the **organizer**, an abstract entity running the event. +Tixl is all about **events**, which are defined as something happening somewhere. +Every Event is managed by the **organizer**, an abstract entity running the event. -Tixl is used by **users**, of which it knows two types: +Tixl is used by **users**. We want to enable global users who can just login into +tixl and buy tickets for as many events as they like but at the same time it +should be possible to create some kind of local user to have a temporary account +just to buy tickets for one single event. + +The problem is, we cannot use usernames as primary keys for our users, as we +do not want one username to be blocked forever just because of one temporary +account using it (people would have to think of a new username for every temporary +account they create). On the other hand, we can not use e-mail addresses either, +as those are not unique (imagine one person having multiple temporary accounts) +and they should not be required for temporary account (to enable anonymity). + +Therefore, we split our users into two groups and use an internal **identifier** +as our primary key: **Local users** - Local users do only exist inside the scope of one event. They are identified by usernames, which are only valid for exactly one event. + Local users do only exist inside the scope of one event. They are identified by + usernames, which are only valid for exactly one event. Internally, their identifier + is "{username}@{event.id}.event.tixl" **Global users** - Global users exist everywhere in the installation of Tixl. They can buy tickets for multiple events and they can be managers of one or more Organizers/Events. Global users are identified by e-mail addresses. + Global users exist everywhere in the installation of Tixl. They can buy tickets + for multiple events and they can be managers of one or more Organizers/Events. + Global users are identified by e-mail addresses. -For more information about this user concept and reasons behind it, see the docstring of the ``tixlbase.models.User`` class. Items and variations ^^^^^^^^^^^^^^^^^^^^ -The purpose of tixl is to sell **items** (which belong to **events**) to **users**. An **item** is a abstract thing, popular examples being event tickets or a piece of merchandise, like 'T-Shirt'. An **item** can have multiple **properties** with multiple **values** each. For example, the **item** 'T-Shirt' could have the **property** 'Size' with **values** 'S', 'M' and 'L' and the **property** 'Color' with **values** 'black' and 'blue'. +The purpose of tixl is to sell **items** (which belong to **events**) to **users**. +An **item** is a abstract thing, popular examples being event tickets or a piece of +merchandise, like 'T-Shirt'. An **item** can have multiple **properties** with multiple +**values** each. For example, the **item** 'T-Shirt' could have the **property** 'Size' +with **values** 'S', 'M' and 'L' and the **property** 'Color' with **values** 'black' +and 'blue'. -Any combination of those **values** is called a **variation**. Using the examples from above, a possible **variation** would be 'T-Shirt S blue'. +Any combination of those **values** is called a **variation**. Using the examples from +above, a possible **variation** would be 'T-Shirt, S, blue'. Restrictions ^^^^^^^^^^^^ -The probably most powerful concepts of tixl is the very abstract concept of **restricitons**. We already know that **items** can come in very different **variations**, but a **restriction** decides whether an item is available for sale and assign **prices** to **variations**. There are **restriction types**, which are pieces of code implementing the restrictions and **restriction instances**, which are configurations made by the **organzier**. Although **restrictions** are a very abstract concept which can be used to do nearly anything, there are a few obvious examples: +The probably most powerful concepts of tixl is the very abstract concept of **restricitons**. +We already know that **items** can come in very different **variations**, but a +**restriction** decides whether an variation is available for sale and assign **prices** +to **variations**. There are **restriction types** (pieces of code implementing the +restriction logic) and **restriction instances** (the specific configurations made by the +organzier). Although **restrictions** are a very abstract concept which can be used +to do nearly anything, there are a few obvious examples: -* One easy example is the time restriction, which allows the sale of certain item variations only within a certain time frame. As restrictions can also assign a price to a variation, this can also be used to implement something like 'early-bird prices' for your tickets by using multiple time restrictions with different prices. -* The most obvious example is the number restriction, which limits the sale of the tickets to a maximum number. You can use this either to stop selling tickets completely when your house is full or for creating limited 'VIP tickets'. -* A more advanced example is a restriction by user, for example reduced ticket prices for members who are members of a special group. -* Arbitrary sophisticated features like coupon codes are also possible to be implemented using this feature. +* One easy example is a restriction by time, which allows the sale of certain item variations + only within a certain time frame. As restrictions can also assign a price to a variation, + this can also be used to implement something like 'early-bird prices' for your tickets by + using multiple time restrictions with different prices. +* The most obvious example is the restriction by number, which limits the sale of the tickets to + a maximum number. You can use this either to stop selling tickets completely when your house + is full or for creating limited 'VIP tickets'. We'll come to this again later. +* A more advanced example is a restriction by user, for example reduced ticket prices for + members who are members of a special group. +* Arbitrary sophisticated features like coupon codes are also possible to be implemented using + this feature. -Any number of **restrictions** can be applied to the whole of a **item** or to a specific **variation**. The processing of the restriction follows the following set of rules: +Any number of **restrictions** can be applied to the whole of a **item** or even to a specific +**variation**. The processing of the restriction follows the following set of rules: -* **Variation**-specific rules have precedence over **item**-specific rules. -* The restrictions are being processed in random order (there may not be any assumptions about the evaluation order). -* Multiple restriction instances of **different restriction types** are linked with *and*, so if both a time frame and a number restriction are applied to an item, the item is only avaliable for sale within the given time frame *and* only as long as items are available. -* Multiple restriction instances of the **same restriction type** are linked with *or*, so if two time frames are applied to an item, the item is available for sale in both of the time frames. (This behaviour is actually a decision of the restriction type itself, so this rule is not enforced but rather a general rule of thumb). +* Variation-specific rules have precedence over item-specific rules. +* The restrictions are being processed in random order (there may not be any assumptions about + the evaluation order). +* Multiple restriction instances of **different restriction types** are linked with *and*, so + if both a time frame and a restriction by number are applied to an item, the item is only avaliable + for sale during the given time frame *and* only as long as items are available. +* Multiple restriction instances of the **same restriction type** are typically linked with *or*, + although this is the decision of the restriction logic itself and not mandatory. So for example + the restriction by time would implement this default logic, because if two time frames are applied + to an item, the item should be available for sale in both of the time frames (it just does not make + sense otherwise on an one-dimensional time axis). * If multiple restrictions apply which set the price, the *cheapest* price determines the final price. -Restriction types can be introduced by 3rd-party code and do not require changes to the tixl codebase. +Restrictions can be implemented using a plugin system and do not require changes to the tixl codebase. -.. note:: This pluggability of restrictions is implemented using the 'signal and receiver' pattern provided by Django. Restrictions can therefore live in seperate Django apps. +Restriction by number +""""""""""""""""""""" + +The restriction by number is a special case, as it is the only (planned) restriction type demanding +special care in the implementation to never sell more tickets than allowed, even under heavy load. + +* There is a concept of **quotas**. A quota is basically a number of items combined with information + about how many of them are still available. +* Every time a user places a item in the cart, a **lock** object is created, reducing the number of + available items in the pool by one. The lock is valid for a fixed time (e.g. 30 minutes), but not + instantly deleted afther those 30 minutes (we'll get to that). +* Every time a user places a binding order, the lock object is replaced by an **order** which behaves + much the same as the lock. It reduces the number of available item and is valid for a fixed time, this + time for the configured payment term (e.g. 14 days). +* If the order is being paid, the **order** becomes permanent. +* Once there are no available tickets left and a user wants to buy a ticket, a lock which is in place + for more than the allowed time frame is being removed in favor of the new buyer. If there are no + abandoned locks available, an unpaid order being older than the configured payment term is being + removed. If there are none of them as well, this quota is sold out. +* The same quota can apply to multiple items and one item can be affected by multiple quotas, to + enable both of the following features at the same time: + + * You'll want to make sure you never have more then X people at your event, so you'll create a quota + applying to all ticket items. + * You want to reduce the first Y tickets in price, so you'll create a restriction which is bound by + a quota of Y and reduces the price. diff --git a/doc/development/setup.rst b/doc/development/setup.rst index 079defba59..a26ba3c72e 100644 --- a/doc/development/setup.rst +++ b/doc/development/setup.rst @@ -8,8 +8,8 @@ Just clone our git repository including its submodules:: git clone --recursive https://github.com/tixl/tixl.git cd tixl/ -Dependencies ------------- +External Dependencies +--------------------- * Python 3.4 or newer * ``pip`` for Python 3 * ``git`` @@ -18,12 +18,17 @@ Dependencies Your local python environment ----------------------------- -Please execute ``python -V`` or ``python3 -V`` to make sure you have Python 3.4 installed. Also make sure you have pip for Python 3 installed, you can execute ``pip3 -V`` to check. Then use Python 3.4's internal tools to create a virtual environment and activate it for your current session:: +Please execute ``python -V`` or ``python3 -V`` to make sure you have Python 3.4 +installed. Also make sure you have pip for Python 3 installed, you can execute +``pip3 -V`` to check. Then use Python 3.4's internal tools to create a virtual +environment and activate it for your current session:: pyvenv env source env/bin/activate -You should now see a ``(env)`` prepended to your shell prompt. +You should now see a ``(env)`` prepended to your shell prompt. You have to do this +in every shell you use to work with tixl (or configure your shell to do so +automatically). Working with the code --------------------- @@ -38,33 +43,53 @@ Then, create the local database:: Create the translation files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To generate updated translation files, run a:: +If you're working with the translation, you can use the following command to scan the +source code for strings to be translated and update the ``*.po`` files accordingly:: make localegen -To compile the language files for use, run:: +To actually see tixl in your language, you have to compile the ``*.po`` files to their +optimized binary ``*.mo`` counterparts:: make localecompile Run the development server ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Execute:: +To run the local development webserver, execute:: python manage.py runserver -to start a local development webserver on port 8000. +and head to http://localhost:8000/ -Static code checks -^^^^^^^^^^^^^^^^^^ +Code checks and unit tests +^^^^^^^^^^^^^^^^^^^^^^^^^^ Before you check in your code into git, always run:: flake8 . + python manage.py validate + python manage.py test + +to check for syntax, style and other errors. The ``flake8`` command by default is a bit +stricter than what we really enforce, but we do enforce that all commits produce no output +from:: + + flake8 --ignore=E123,E128,F403,F401,N802 . + +It is therefore a good idea to put this command into your git hook ``.git/hooks/pre-commit``, +for example:: + + #!/bin/sh + cd $GIT_DIR/../src + source ../env/bin/activate + flake8 --ignore=E123,E128,F403,F401,N802 . + -to check for syntax, style and other errors. Working with the documentation ------------------------------ -First, you should install the requiremente necessary for building the documentation. Make sure you have your virtual python enviroment activated (see above). Then, install the packages by executing:: +First, you should install the requirements necessary for building the documentation. +Make sure you have your virtual python enviroment activated (see above). Then, install the +packages by executing:: cd doc/ pip install -r requirements.txt diff --git a/doc/requirements.txt b/doc/requirements.txt index cfd22b5851..cbdcd750b9 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,2 +1,3 @@ Sphinx markupsafe +sphinx_rtd_theme