Swingtime documentation contents¶
Table of Contents¶
About Swingtime¶
Welcome¶
Swingtime is a Django application similar to a stripped-down version of iCal for Mac OS X or Google Calendar.
Swingtime provides a models.Event model that acts as metadata container
for one or more models.Occurrence objects, which describe specific
start and end times.
Swingtime relies heavily upon both the datetime standard library package and
the dateutil package, featuring direct support for the dateutil.rrule
interface to create occurrences.
A fairly simple example:
>>> from datetime import *
>>> from swingtime import models as swingtime
>>> et = swingtime.EventType.objects.create(abbr='work', label='Work Related Events')
>>> evt = swingtime.Event.objects.create(
... title='New TPS Cover Sheet',
... description='Kiss off, Lumbergh!',
... event_type=et
... )
>>> evt.add_occurrences(datetime(2013,4,1,16), datetime(2013,4,1,16,15), count=5)
>>> for o in evt.occurrence_set.all():
... print o
...
New TPS Cover Sheet: 2013-04-01T16:00:00
New TPS Cover Sheet: 2013-04-02T16:00:00
New TPS Cover Sheet: 2013-04-03T16:00:00
New TPS Cover Sheet: 2013-04-04T16:00:00
New TPS Cover Sheet: 2013-04-05T16:00:00
A bit more elaborate example, using the the convenience function models.create_event:
>>> # pay day is the last Friday of the month at 5pm
>>> evt = swingtime.create_event(
... 'Pay day',
... ('pay', 'Payroll'), # alternate means to add EventType on the fly
... freq=rrule.MONTHLY,
... byweekday=rrule.FR(-1),
... until=datetime(2013,8,1),
... start_time=datetime(2013,4,1,17)
... )
>>> for o in evt.occurrence_set.all():
... print o
...
Pay day: 2013-04-26T17:00:00
Pay day: 2013-05-31T17:00:00
Pay day: 2013-06-28T17:00:00
Pay day: 2013-07-26T17:00:00
Features¶
- Support for adding complex event occurrences via
dateutil - Ready-made
forms.MultipleOccurrenceFormfor handling complex input - Daily, monthly, and annual view functions
- Grid-based daily view generator, complete with alternating or sequential
EventTypeCSS-class handling - Slightly better than average documentation, a few test cases, and commented code
- Active support (I have to eat my own dogfood)
- Built-in demo project / application
Requirements¶
- Python 2.7, 3.4
- Django 1.7+
- python-dateutil.
Installation¶
Note
The swingtime documentation assumes familiarity with and installation of
Python deployment tools pip,
virtualenv, and
virtualenvwrapper.
Get Swingtime¶
Full project source code¶
git:$ git clone https://github.com/dakrauth/django-swingtime.git django-swingtime $ cd django-swingtime
Download:
$ curl -o swingtime.zip -L https://github.com/dakrauth/django-swingtime/archive/master.zip $ unzip swingtime.zip $ cd django-swingtime-master
Documentation¶
Note
Building the documentation requires Sphinx to be installed.
Install the swingtime project as shown in Full project source code
and build the docs as follows:
$ cd docs
$ make html
Browse the file build/html/index.html.
Running the Tests¶
Note
From the django-swingtime root directory
$ cd tests
$ python manage.py test swingtime
$ ./cover # <-- run `coverage`
$ cd ../
$ tox
Demo¶
Swingtime comes with its own demo project and application. The demo is themed as a Karate studio’s website and allows you see and interact with the Swingtime application.
Within the Swingtime demo is an app named karate, which defines the custom
management command loaddemo. This command will pre-populate your
initial database with some events and occurrences based upon the current date and
time.
Currently, Swingtime does not include any templates of its own. The demo project provides some sample templates to use as a guide or starting point.
Running the demo¶
Install the swingtime project as shown in Full project source code.
You can set up your environment to run the demo in a virtualenv by doing the
following from the root swingtime project directory:
$ mkvirtualenv swingtime_demo
$ pip install -r requirements.txt
$ cd demo
$ python manage.py loaddemo
$ python manage.py runserver
loaddemo is just a simple wrapper around migrate and a short script to load
some data into your new database - by default, a sqlite3 database named
karate.db - in the root directory of the demo.
Note
You can optionally run the development server to check for deprecation warnings:
$ python -Wd manage.py runserver
Now, you are ready to browse to http://127.0.0.1:8000/
models — Swingtime Object Model Definitions¶
Functions¶
create_event¶
-
models.create_event(title, event_type[, description, start_time, end_time, note, **rrule_params])¶ Convenience function to create an
Event, optionally create anEventType, and associatedOccurrenceinstances.Occurrencecreation rules match those forEvent.add_occurrences().Returns the newly created
Eventinstance.Parameters
event_type- can be either an
EventTypeobject or 2-tuple of(abbreviation,label), from which anEventTypeis either created or retrieved. description- sets the event’s description if not
None start_time- will default to the current hour if
None end_time- will default to
start_timeplusswingtime_settings.DEFAULT_OCCURRENCE_DURATIONhour ifNone note- if not
None, add aNoteinstance to the new event rrule_params- follows the
dateutilsAPI (see http://labix.org/python-dateutil)
Example:
from datetime import datetime, time from swingtime import models as swingtime from dateutil import rrule event = swingtime.create_event( 'Beginner Class', ('bgn', 'Beginner Classes'), description='Open to all beginners', start_time=datetime.combine(datetime.now().date(), time(19)), count=6, byweekday=(rrule.MO, rrule.WE, rrule.FR) )
Classes¶
Note¶
EventType¶
Event¶
-
class
models.Event(django.db.models.Model)¶ Container model for general metadata and associated
Occurrenceentries.-
title¶ models.CharField
-
description¶ models.CharField
-
event_type¶ models.ForeignKey for
EventType
-
notes¶ generic.GenericRelation for
Note
-
get_absolute_url()¶ return (‘swingtime-event’, [str(self.id)])
-
add_occurrences(start_time, end_time[, **rrule_params])¶ Add one or more occurences to the event using a comparable API to
dateutil.rrule.If
rrule_paramsdoes not contain afreq, one will be defaulted torrule.DAILY.Because
rrule.rrulereturns an iterator that can essentially be unbounded, we need to slightly alter the expected behavior here in order to enforce a finite number of occurrence creation.If both
countanduntilentries are missing fromrrule_params, only a singleOccurrenceinstance will be created using the exactstart_timeandend_timevalues.
-
upcoming_occurrences()¶ Return all occurrences that are set to start on or after the current time.
-
next_occurrence()¶ Return the single occurrence set to start on or after the current time if available, otherwise
None.
-
daily_occurrences([dt])¶ Convenience method wrapping
Occurrence.objects.daily_occurrences.
-
OccurrenceManager¶
-
class
models.OccurrenceManager(models.Manager)¶ -
daily_occurrences([dt, event])¶ Returns a queryset of for instances that have any overlap with a particular day.
Parameters
dt- may be either a datetime.datetime, datetime.date object, or
None. IfNone, default to the current day event- can be an
Eventinstance for further filtering
-
Occurrence¶
-
class
models.Occurrence(django.db.models.Model)¶ Represents the start end time for a specific occurrence of a master
Eventobject.-
start_time¶ models.DateTimeField
-
end_time¶ models.DateTimeField
-
event¶ models.ForeignKey - a non-editable Event object
-
notes¶ generic.GenericRelation
Note
-
get_absolute_url()¶ ‘swingtime-occurrence’, [str(self.event.id), str(self.id)])
-
__cmp__()¶ Compare two
Occurrencestart times
-
title¶ Shortcut for the occurrence’s
Event.title
-
event_type¶ Shortcut for the occurrence’s
EventType
-
views — Swingtime Views¶
Functions¶
event_listing¶
-
views.event_listing(request[, template='swingtime/event_list.html', events=None, **extra_context])¶ View all
events.If
eventsis a queryset, clone it. IfNonedefault to allEventobjects.Context parameters:
- events
- an iterable of
Eventobjects - extra_context
- extra variables passed to the template context
event_view¶
-
views.event_view(request, pk[, template='swingtime/event_detail.html', event_form_class=forms.EventForm, recurrence_form_class=forms.MultipleOccurrenceForm])¶ View an
Eventinstance and optionally update either the event or its occurrences.Context parameters:
- event
- the event keyed by
pk - event_form
- a form object for updating the event
- recurrence_form
- a form object for adding occurrences
occurrence_view¶
-
views.occurrence_view(request, event_pk, pk[, template='swingtime/occurrence_detail.html', form_class=forms.SingleOccurrenceForm])¶ View a specific occurrence and optionally handle any updates.
Context parameters:
- occurrence
- the occurrence object keyed by
pk - form
- a form object for updating the occurrence
add_event¶
-
views.add_event(request[, template='swingtime/add_event.html', event_form_class=forms.EventForm, recurrence_form_class=forms.MultipleOccurrenceForm])¶ Add a new
Eventinstance and 1 or more associatedOccurrenceinstancess.Context parameters:
- dtstart
- a datetime.datetime object representing the GET request value if present, otherwise None
- event_form
- a form object for updating the event
- recurrence_form
- a form object for adding occurrences
_datetime_view¶
-
views._datetime_view(request template, dt[, timeslot_factory=None, items=None, params=None])¶ Build a time slot grid representation for the given datetime
dt. See utils.create_timeslot_table documentation for items and params.Context parameters:
- day
- the specified datetime value (dt)
- next_day
- day + 1 day
- prev_day
- day - 1 day
- timeslots
- time slot grid of (time, cells) rows
day_view¶
-
views.day_view(request, year, month, day[, template='swingtime/daily_view.html', **params])¶ See documentation for function``_datetime_view``.
today_view¶
-
views.today_view(request[, template='swingtime/daily_view.html', **params])¶ See documentation for function``_datetime_view``.
year_view¶
-
views.year_view(request, year[, template='swingtime/yearly_view.html', queryset=None])¶ Context parameters:
- year
- an integer value for the year in questin
- next_year
- year + 1
- last_year
- year - 1
- by_month
- a sorted list of (month, occurrences) tuples where month is a datetime.datetime object for the first day of a month and occurrences is a (potentially empty) list of values for that month. Only months which have at least 1 occurrence is represented in the list
month_view¶
-
views.month_view(request, year, month[, template='swingtime/monthly_view.html', queryset=None])¶ Render a tradional calendar grid view with temporal navigation variables.
Context parameters:
- today
- the current datetime.datetime value
- calendar
- a list of rows containing (day, items) cells, where day is the day of the month integer and items is a (potentially empty) list of occurrence for the day
- this_month
- a datetime.datetime representing the first day of the month
- next_month
- this_month + 1 month
- last_month
- this_month - 1 month
forms — Swingtime Forms¶
Convenience forms for adding and updating Event and Occurrence objects.
Functions¶
timeslot_options¶
-
forms.timeslot_options([interval=swingtime_settings.TIMESLOT_INTERVAL, start_time=swingtime_settings.TIMESLOT_START_TIME, end_delta=swingtime_settings.TIMESLOT_END_TIME_DURATION, fmt=swingtime_settings.TIMESLOT_TIME_FORMAT])¶ Create a list of time slot options for use in swingtime forms.
The list is comprised of 2-tuples containing a 24-hour time value and a 12-hour temporal representation of that offset.
timeslot_offset_options¶
-
forms.timeslot_offset_options([interval=swingtime_settings.TIMESLOT_INTERVAL, start_time=swingtime_settings.TIMESLOT_START_TIME, end_delta=swingtime_settings.TIMESLOT_END_TIME_DURATION, fmt=swingtime_settings.TIMESLOT_TIME_FORMAT])¶ Create a list of time slot options for use in swingtime forms.
The list is comprised of 2-tuples containing the number of seconds since the start of the day and a 12-hour temporal representation of that offset.
Data¶
Classes¶
MultipleIntegerField¶
-
class
forms.MultipleIntegerField(django.forms.MultipleChoiceField)¶ A form field for handling multiple integers.
- def __init__(self, choices, size=None, label=None, widget=None):
- if widget is None:
- widget = forms.SelectMultiple(attrs={‘size’ : size or len(choices)})
SplitDateTimeWidget¶
MultipleOccurrenceForm¶
-
class
forms.MultipleOccurrenceForm(django.forms.Form)¶ -
day¶ forms.DateField
-
start_time_delta¶ forms.IntegerField
-
end_time_delta¶ forms.IntegerField
-
repeats¶ forms.ChoiceField
-
count¶ forms.IntegerField
-
until¶ forms.DateField
-
freq¶ forms.IntegerField
-
interval¶ forms.IntegerField
-
week_days¶ MultipleIntegerField
-
month_ordinal¶ forms.IntegerField
-
month_ordinal_day¶ forms.IntegerField
-
each_month_day = MultipleIntegerField(
-
year_months¶ MultipleIntegerField
-
is_year_month_ordinal¶ forms.BooleanField(required=False)
-
year_month_ordinal¶ forms.IntegerField(widget=forms.Select(choices=ORDINAL))
-
year_month_ordinal_day¶ forms.IntegerField(widget=forms.Select(choices=WEEKDAY_LONG))
-
__init__([*args, **kws])¶ if
initialcontainsdtstart- adatetime.datetimeinstance - the appropriate unspecifiedinitialwill be defaulted for the form.
-
clean()¶ populates
cleaned_datawithstart_timeandend_timevalues
-
save(event): Returns an
Eventobject
-
utils — Swingtime Utilities¶
Common features and functions for swingtime
Functions¶
html_mark_safe¶
-
utils.html_mark_safe(func)¶ Decorator for functions return strings that should be treated as template safe.
time_delta_total_seconds¶
-
utils.time_delta_total_seconds(time_delta)¶ Calculate the total number of seconds represented by a
datetime.timedeltaobject
month_boundaries¶
-
utils.month_boundaries([dt=None])¶ Return a 2-tuple containing the datetime instances for the first and last dates of the current month or using
dtas a reference.
css_class_cycler¶
create_timeslot_table¶
-
utils.create_timeslot_table([dt=None, items=None, start_time=swingtime_settings.TIMESLOT_START_TIME, end_time_delta=swingtime_settings.TIMESLOT_END_TIME_DURATION, time_delta=swingtime_settings.TIMESLOT_INTERVAL, min_columns=swingtime_settings.TIMESLOT_MIN_COLUMNS, css_class_cycles=css_class_cycler, proxy_class=DefaultOccurrenceProxy])¶ Create a grid-like object representing a sequence of times (rows) and columns where cells are either empty or reference a wrapper object for event occasions that overlap a specific time slot.
Currently, there is an assumption that if an occurrence has a
start_timethat falls with the temporal scope of the grid, then thatstart_timewill also match an interval in the sequence of the computed row entries.dt- a
datetime.datetimeinstance orNoneto default to now items- a queryset or sequence of
Occurrenceinstances. IfNone, default to the daily occurrences fordt start_time- a
datetime.timeinstance, defaulting toswingtime_settings.TIMESLOT_START_TIME end_time_delta- a
datetime.timedeltainstance, defaulting toswingtime_settings.TIMESLOT_END_TIME_DURATION time_delta- a
datetime.timedeltainstance, defaulting toswingtime_settings.TIMESLOT_INTERVAL min_column- the minimum number of columns to show in the table, defaulting to
swingtime_settings.TIMESLOT_MIN_COLUMNS css_class_cycles- if not
None, a callable returning a dictionary keyed by desiredEventTypeabbreviations with values that iterate over progressive CSS class names for the particular abbreviation; defaults tocss_class_cycler() proxy_class- a wrapper class for accessing an
Occurrenceobject, which should also exposeevent_typeandevent_classattrs, and handle the custom output via its __unicode__ method; defaults toDefaultOccurrenceProxy
Classes¶
BaseOccurrenceProxy¶
-
class
utils.BaseOccurrenceProxy(object)¶ A simple wrapper class for handling the representational aspects of an
Occurrenceinstance.
DefaultOccurrenceProxy¶
-
class
utils.DefaultOccurrenceProxy(BaseOccurrenceProxy)¶ Through the
__unicode__method, outputs a safe string anchor tag for theOccurrenceinstance, followed by simple token placeholders to represent additional slot fillings.
swingtime_settings — Configuration Settings¶
Settings¶
Swingtime has it’s settings module (conf/swingtime_settings.py) that
simulates how each Django project’s setting.py file functions. You can
overwrite any or all of the configuration parameters described in
swingtime_settings by creating a file in your own project and referencing
that file in your project settings using the name SWINGTIME_SETTINGS_MODULE.
For example, from the demo’s configuration:
SWINGTIME_SETTINGS_MODULE = 'demo.swingtime_settings'
-
swingtime_settings.TIMESLOT_TIME_FORMAT¶ A “strftime” string for formatting start and end time selectors in forms. The default format is:
'%I:%M %p'
-
swingtime_settings.TIMESLOT_INTERVAL¶ Used for creating start and end time form selectors as well as time slot grids. Value should be
datetime.timedeltavalue representing the incremental differences between temporal options. The default is:``datetime.timedelta(minutes=15)``
-
swingtime_settings.TIMESLOT_START_TIME¶ A datetime.time value indicting the starting time for time slot grids and form selectors. The default is:
``datetime.time(9)``
-
swingtime_settings.TIMESLOT_END_TIME_DURATION¶ A
datetime.timedeltavalue indicating the offset value fromTIMESLOT_START_TIMEfor creating time slot grids and form selectors. The purpose for using a time delta is that it possible to span dates. For instance, one could have a starting time of 3pm (15:00) and wish to indicate a ending value 1:30am (01:30), in which case a value ofdatetime.timedelta(hours=10.5)could be specified to indicate that the 1:30 represents the following date’s time and not the current date. Default:``datetime.timedelta(hours=+8)``
-
swingtime_settings.TIMESLOT_MIN_COLUMNS¶ Indicates a minimum value (default:
4) for the number grid columns to be shown in the time slot table.
-
swingtime_settings.DEFAULT_OCCURRENCE_DURATION¶ Indicate the default length in time for a new occurrence, specifed by using a
datetime.timedeltaobject, defaulting to:``datetime.timedelta(hours=+1)``
-
swingtime_settings.CALENDAR_FIRST_WEEKDAY¶ If not
None, passed tocalendar.setfirstweekdayfunction. Default:6
Changes in Swingtime¶
Release 0.7.1 (January 29, 2016)¶
- Added model migrations
- Added support for Django 1.9
- Removed support for Django < 1.7
- More docs for running demo and installing
Release 0.6 (April 5, 2015)¶
- Added
bulk_createinEvent.add_occurrences(siolag161) - Support for Django 1.8
- Added tests and docs
Release 0.5 (February 11, 2015)¶
- Added tox, Travis CI, a separate tests project, and MANIFEST.in
- Cleaned up demo project, docs, setup.py
- Removed support for Django<1.6
Release 0.4.1 (February 10, 2015)¶
- Bugfix for form rrule
Release 0.4 (September 18, 2014)¶
- Added support for Python 3.4
Release 0.3.3 (September 17, 2014)¶
- Added support for Django 1.5, 1.6, 1.7
Release 0.2.2 (March 16, 2013)¶
- Registered in PyPI
- Installs with pip
Release 0.2 (Decemeber 18, 2008)¶
- First public release.
Authors¶
- David A Krauth <dakrauth@gmail.com>
- James O’Donnell - setup script
- siolag
- brousch
- muelli
- FortschrittApps