gpxity.backends package

define things that should be visible to the user.

gpxity.backends.directory module

This implements gpxity.directory.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

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

Type:str
fs_encoding

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.

Type:str
is_temporary

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

Type:bool
destroy()[source]

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

gpx_path(ident) → str[source]

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

Returns:The full path name
needs_config = False
supported = {'keywords', 'remove', 'scan', 'write'}
test_is_expensive = False
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.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:
default_url = 'https://www.gpsies.com'
destroy()[source]

also close session.

session

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

Returns:The session
supported = {'own_categories', 'remove', 'scan', 'write', 'write_category', 'write_description', 'write_public', 'write_title'}
supported_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', 'trailrunning', 'speedhiking', 'wintersports', 'flying', 'train', 'sightseeing', 'geocaching', 'miscellaneous')

gpxity.backends.openrunner module

This implements gpxity.openrunner.Openrunner for https://www.openrunner.com.

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

Bases: gpxity.backend.Backend

The implementation for openrunner.com.

The track ident is the ID given by openrunner.

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

Parameters:
current_subscription

Get the current subscription model.

Returns: The name of the subscription.

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

Translate the value from Openrunner into internal one.

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

also close session.

max_field_sizes = {'keywords': 200}
point_precision = 5
session

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

Returns:The session
session_response

The last response received.

Returns: The response

supported = {'keywords', 'own_categories', 'remove', 'scan', 'write'}
supported_categories = ('Cycling - Road', 'Canoe-Kayak', 'Cycling - Gravel', 'Cycling - MTB', 'Cycling - Touring', 'Footbiking', 'Hiking', 'Horse riding', 'Longboard', 'Nordic walking', 'River navigation', 'Rollerblading', 'Running - Trail', 'Running - Urban Trail', 'Running- Road', 'Skiing - Backcountry', 'Skiing - Crosscountry', 'Skiing - Rollerskiing', 'Skiing - Touring', 'Snowshoeing', 'Stand Up Paddle', 'Swimming', 'Swimrun', 'Walking', 'Autre')
class gpxity.backends.openrunner.Encoding[source]

Bases: object

Openrunner transfers point data in a compressed format.

static decode_points(input_str) → list[source]

Decode str into a list of points.

Returns: list(GPXTrackPoint)

static encode_number(nbr) → str[source]

Encode a single unsigned number.

Returns: the encoded string

static encode_points(points) → str[source]

Encode a list of points.

Returns: the encoded string

static encode_signed_number(nbr) → str[source]

Encode a single signed number.

Returns: The encoded string

gpxity.backends.mmt module

This implements gpxity.mmt.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:
default_url = 'https://www.mapmytracks.com'
destroy()[source]

also close session.

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.

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 = {'keywords', 'own_categories', 'remove', 'scan', 'write', 'write_add_keywords', 'write_category', 'write_description', 'write_public', 'write_remove_keywords', 'write_title'}
supported_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')

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.

destroy()[source]

Would need implementations for scan and remove.

is_free_account

Our own local server can do lifeftracking.

Returns:False
supported = {'keywords', 'own_categories', 'write'}
test_is_expensive = False

gpxity.backends.server_directory module

This implements gpxity.server_directory.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 = {'keywords', 'remove', 'scan', 'write'}

gpxity.backends.mailer module

This implements gpxity.mailer.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.

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.

config.from

The name of the mail sender. Default “gpxity”.

config.port

The port of the smtp server to talk to. Default 25

config.smtp

The name of the smtp server. Default “localhost”.

config.interval

seconds. Mails are not sent more often. Default is None. If None, always send when 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.

Type:str
destroy()[source]

Mail the rest.

flush()[source]

Now is the time to write.

id_count = 0
supported = {'keywords', 'write'}
test_is_expensive = False

gpxity.backends.wptrackserver module

This implements gpxity.wptrackserver.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.

ident_format = '{:06}'
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
needs_config = False
supported = {'keywords', 'remove', 'scan', 'write'}
test_is_expensive = False