gpxity.backends package

define things that should be visible to the user.

gpxity.backends.directory module

This implements gpxity.Directory.

class gpxity.backends.directory.Directory(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backend.Backend

Uses a directory for storage. The filename minus the .gpx ending is used as the track id.

If the track has a title but no storage id yet, use the title as storage id. Make the storage id unique by attaching a number if needed. An track without title gets a random name.

The main directory (given by Directory.url) will have subdirectories YYYY/MM (year/month) with only the tracks for one month. Those are symbolic links to the main file and have the same file name.

If save() is given a value for ident, this is used as id, the file name will be id.gpx. Otherwise, this backend uses Track.title for the id. If a track has no title, it uses a random sequence of characters. Changing the title also changes the id.

Parameters:
  • url (str) – a directory. If no Url is given, either here or through auth, use a unique temporary directory named prefix.X where X are some random characters. If the directory does not exist, it is created.
  • auth (str) – In addition to other backends: if given and url is None, use auth as url.
  • cleanup (bool) – If True, destroy() will remove all tracks. If url was not given, it will also remove the directory.
prefix

str – Class attribute, may be changed. The default prefix for temporary directories. Default value is gpxity.

fs_encoding

str – The encoding for file system names. By default, we expect the file system being able to handle arbitrary UTF-8 encoded names except character ‘/’ and special names ‘.’ and ‘..’. If needed, we will introduce new possible values for fs_encoding like perhaps ‘windows’. Gpxity will never support any other character set but UTF-8. Note that fs_encoding is independent of the platform we are running on - we might use a network file system.

is_temporary

bool – True if no Url was given and we created a temporary directory

decode_category(value: str) → str[source]

Not needed for directory, this is always the internal value.

Returns:the decoded category
destroy()[source]

If cleanup was set at init time, removes all tracks. If url was set at init time, also removes the directory.

encode_category(value: str) → str[source]

Not needed for directory, this is always the internal value.

Returns:the encoded category
get_time() → datetime.datetime[source]

get server time as a Linux timestamp.

Returns:The server time
gpx_path(ident) → str[source]

The full path name for the local copy of a track.

Returns:The full path name
legal_categories

A list with all legal categories.

Returns: list(str)
all legal values for category for this backend.
needs_config = False
supported = {'remove', 'get_time', 'scan', 'write', 'keywords'}
class gpxity.backends.directory.Backup(track)[source]

Bases: object

A context manager making a backup of the gpx file.

If an exception happened, restore the backup. Otherwise, remove it again.

undo_rename()[source]

if something failed, undo change of file name and restore old file.

gpxity.backends.gpsies module

This implements gpxity.GPSIES for https://www.gpsies.com.

so ginge das mit dem API-Key: https://github.com/telemaxx/gpsiesreader/blob/master/gpsies3.py

class gpxity.backends.gpsies.GPSIES(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backend.Backend

The implementation for gpsies.com.

The track ident is the fileId given by gpsies.

Searching arbitrary tracks is not supported. GPSIES only looks at the tracks of a specific user.

GPSIES does not support keywords. If you upload a track with keywords, they will silently be ignored.

Parameters:
decode_category(value: str) → str[source]

Translate the value from Gpsies into internal one.

Returns:The decoded name
default_url = 'https://www.gpsies.com'
destroy()[source]

also close session.

encode_category(value: str) → str[source]

Translate internal value into Gpsies value.

Returns:The encoded name
legal_categories = ('biking', 'trekking', 'walking', 'jogging', 'climbing', 'racingbike', 'mountainbiking', 'pedelec', 'skating', 'crossskating', 'handcycle', 'motorbiking', 'motocross', 'motorhome', 'cabriolet', 'car', 'riding', 'coach', 'packAnimalTrekking', 'swimming', 'canoeing', 'sailing', 'boating', 'motorboat', 'skiingNordic', 'skiingAlpine', 'skiingRandonnee', 'snowshoe', 'wintersports', 'flying', 'train', 'sightseeing', 'geocaching', 'miscellaneous')
session

The requests.Session for this backend. Only initialized once.

Returns:The session
supported = {'remove', 'write_category', 'write_public', 'write', 'write_title', 'write_description', 'scan'}

gpxity.backends.mmt module

This implements gpxity.MMT for http://www.mapmytracks.com.

There are some problems with the server running at mapmytracks.com:
  • it is not possible to change an existing track - if the track changes, the track must be re-uploaded and gets a new track id This invalididates references held by other backend instances (maybe on other clients). But I could imagine that most similar services have this problem too.
  • does not support GPX very well beyond track data. One problem is that it does not support gpx.time, it ignores it in uploads and uses the time of the earliest trackpoint. To be consistent, Gpxity follows that for now and does not respect gpx.time either.
  • there is an official description of an API at https://github.com/MapMyTracks but this does not implement everything needed. For the missing parts we simulate what a web browser would do, see MMT._read_all() and MMT._write_attribute(). Of course that could fail if MMT changes its site. Which is true for the api itself, it can and does get incompatible changes at any time without notice to users or deprecation periods.
  • downloading tracks with that abi is very slow and hangs forever for big tracks (at least this was so in Feb 2017, maybe have to test again occasionally).
  • not all parts of MMT data are supported like images (not interesting for me, at least not now).
class gpxity.backends.mmt.MMT(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backend.Backend

The implementation for MapMyTracks.

The track ident is the number given by MapMyTracks.

MMT knows tags. We map Track.keywords to MMT tags. MMT will change keywords: It converts the first character to upper case. See Track.keywords for how Gpxity handles this.

Parameters:
decode_category(value: str) → str[source]

Translate the value from MMT into internal one.

Since gpxity once decided to use MMT definitions for tracks, this should mostly be 1:1 here.

Returns:the decoded value
default_url = 'http://www.mapmytracks.com'
destroy()[source]

also close session.

encode_category(value: str) → str[source]

Translate internal value into MMT value.

Returns:the translated value
get_time() → datetime.datetime[source]

get MMT server time.

Returns:The server time
is_free_account

Return True if the current account is not PLUS enabled.

legal_categories = ('Cycling', 'Running', 'Mountain biking', 'Sailing', 'Walking', 'Hiking', 'Driving', 'Off road driving', 'Motor racing', 'Motorcycling', 'Enduro', 'Skiing', 'Cross country skiing', 'Canoeing', 'Kayaking', 'Sea kayaking', 'SUP boarding', 'Rowing', 'Swimming', 'Windsurfing', 'Orienteering', 'Mountaineering', 'Skating', 'Horse riding', 'Hang gliding', 'Hand cycling', 'Gliding', 'Flying', 'Kiteboarding', 'Snowboarding', 'Paragliding', 'Hot air ballooning', 'Nordic walking', 'Miscellaneous', 'Skateboarding', 'Snowshoeing', 'Jet skiing', 'Powerboating', 'Wheelchair', 'Indoor cycling')
mid

the member id on MMT belonging to auth.

Returns:The mid
session

The requests.Session for this backend. Only initialized once.

Returns:The session
supported = {'lifetrack', 'remove', 'write_category', 'write_public', 'write', 'write_remove_keywords', 'write_title', 'get_time', 'lifetrack_end', 'write_add_keywords', 'write_description', 'scan', 'keywords'}

gpxity.backends.trackmmt module

This implements only a minimum of what MMT can do.

Upload entire tracks and extend a track. That is what oruxmaps does - see examples/mmt_server.

TrackMMT is used to test mmt_server.

class gpxity.backends.trackmmt.TrackMMT(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backends.mmt.MMT

This is a minimal implementation, it only supports listing and retrieving tracks and life tracking.

This is used for testing gpxity_server which in turn is used to receive life tracking data from smartphone apps like oruxmaps.

is_free_account

Our own local server can do lifeftracking.

Returns:False
legal_categories = ('Cycling', 'Running', 'Mountain biking', 'Indoor cycling', 'Sailing', 'Walking', 'Hiking', 'Swimming', 'Driving', 'Off road driving', 'Motor racing', 'Motorcycling', 'Enduro', 'Skiing', 'Cross country skiing', 'Canoeing', 'Kayaking', 'Sea kayaking', 'Stand up paddle boarding', 'Rowing', 'Windsurfing', 'Kiteboarding', 'Orienteering', 'Mountaineering', 'Skating', 'Skateboarding', 'Horse riding', 'Hang gliding', 'Gliding', 'Flying', 'Snowboarding', 'Paragliding', 'Hot air ballooning', 'Nordic walking', 'Snowshoeing', 'Jet skiing', 'Powerboating', 'Pedelec', 'Crossskating', 'Handcycle', 'Motorhome', 'Cabriolet', 'Coach', 'Pack animal trekking', 'Train', 'Miscellaneous')
supported = {'lifetrack_end', 'get_time', 'write', 'lifetrack', 'keywords'}

gpxity.backends.server_directory module

This implements gpxity.ServerDirectory.

class gpxity.backends.server_directory.ServerDirectory(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backends.directory.Directory

Like Directory but the track ids are different: Just a number.

A new id is generated by adding 1 to the highest existing id.

The symbolic links per YYYY/MM use the title of the track as link name.

supported = {'remove', 'get_time', 'scan', 'write', 'keywords'}

gpxity.backends.mailer module

This implements gpxity.Mailer: a mailing backend. It can only write.

class gpxity.backends.mailer.Mailer(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backend.Backend

Mailing backend. Write-only.

subject_template

This builds the mail subject. {title} and {distance} will be replaced by their respective values. Other placeholders are not yet defined.

min_interval

seconds. Mails are not sent more often. Default is None. If None, never send until Mailer.flush() is called. This is used for bundling several writes into one single mail: gpxdo merge –copy will send all tracks with one single mail. Lifetracking uses this to send mails with the current track only every X seconds, the mail will only contain the latest version of the track.

outstanding_tracks

Do not change this dict. Key is track.id_in_backend(), value is a clone of the track. This freezes the current title in the clone.

url

Holds the address of the recipient.

destroy()[source]

Mail the rest.

flush()[source]

Now is the time to write.

id_count = 0
supported = {'lifetrack_end', 'write', 'keywords'}

gpxity.backends.wptrackserver module

This implements gpxity.WPTrackServer.

WPTrackserver talks directly to the WP mysql database holding the trackserver data.

This backend does not directly support Track.category, Track.status, Track.keywords. All this is added to the description when writing and extracted when reading. So the description in the backend will contain all keywords, but Track.description does not.

The database has a maximum field length of 255 for strings. If it is exceeded, the last part of the strings will be thrown away silently when writing into the database.

class gpxity.backends.wptrackserver.WPTrackserver(url=None, auth=None, cleanup=False, timeout=None)[source]

Bases: gpxity.backend.Backend

Talk directly to the wordpress mysql database holding the trackserver data.

See https://www.grendelman.net/wp/trackserver-wordpress-plugin/

The section in auth.cfg could look like

[wptrackserver:username] Url = hostname Mysql =user@db_name Password = mysql_password

username is the wordpress user name.

hostname is the server wordpress is running on

user is the mysql user. Find it in the wordpress config file, look for DB_USER.

db_name is the name of the database. Find it in the wordpress config file, look for DB_NAME.

mysql_password is for the mysql user. Find it in the wordpress config file, look for DB_PASSWORD.

classmethod is_disabled() → bool[source]

True if this backend is disabled by env variable GPXITY_DISABLE_BACKENDS.

or because python mysql is not installed.

This variable is a comma separated list of Backend class names.

Returns:True if disabled
legal_categories = ('Cycling', 'Running', 'Mountain biking', 'Sailing', 'Walking', 'Hiking', 'Driving', 'Off road driving', 'Motor racing', 'Motorcycling', 'Enduro', 'Skiing', 'Cross country skiing', 'Canoeing', 'Kayaking', 'Sea kayaking', 'SUP boarding', 'Rowing', 'Swimming', 'Windsurfing', 'Orienteering', 'Mountaineering', 'Skating', 'Horse riding', 'Hang gliding', 'Hand cycling', 'Gliding', 'Flying', 'Kiteboarding', 'Snowboarding', 'Paragliding', 'Hot air ballooning', 'Nordic walking', 'Miscellaneous', 'Skateboarding', 'Snowshoeing', 'Jet skiing', 'Powerboating', 'Wheelchair', 'Indoor cycling')
needs_config = False
supported = {'remove', 'scan', 'write', 'keywords'}