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(account)[source]

Bases: gpxity.backend.Backend

Uses a directory for storage.

The filename minus the .gpx ending is used as GpxFile.id_in_backend.

If the Directory has a title but no id_in_backend, use the title as id_in_backend. Make the storage id unique by attaching a number if needed. A gpxfile without title gets a random name.

The main directory (given by account.url) will have subdirectories YYYY/MM (year/month) with only the gpxfiles 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 GpxFile.title for the id. If a gpxfile has no title, it uses a random sequence of characters. Changing the title also changes the id.

Parameters

Account – If its url is unset, this will create a temporary directory named prefix.X where X are some random characters. It will be removed in __exit__ / detach.

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

accepts_zero_points = True
detach()[source]

also remove temporary directory.

dump_ids(prefix, ident)[source]

For debugging show the IDs found in a file.

gpx_path(ident) → str[source]

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

Returns

The full path name

supported = {'keywords', 'remove', 'rename', 'scan', 'write'}
test_is_expensive = False

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(account)[source]

Bases: gpxity.backend.Backend

The implementation for gpsies.com.

The gpxfile ident is the fileId given by gpsies.

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

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

Parameters

account (Account) – The account to be used. Alternatively a dict can be passed to build an ad hoc Account instance.

default_url = 'https://www.gpsies.com'
detach()[source]

also close session.

property 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(account)[source]

Bases: gpxity.backend.Backend

The implementation for openrunner.com.

The gpxfile ident is the ID given by openrunner.

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

Parameters

account (Account) – The account to be used. Alternatively a dict can be passed to build an ad hoc Account instance.

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'
detach()[source]

also close session.

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

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

Returns

The session

property subscription

Get the subscription model.

Returns: The name of the subscription.

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', 'Other')

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 GpxFile - if the GpxFile changes, the GpxFile must be re-uploaded and gets a new 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 gpxfile 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() 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 gpxfiles with that abi is very slow and hangs forever for big gpxfiles (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(account)[source]

Bases: gpxity.backend.Backend

The implementation for MapMyTracks.

The gpxfile ident is the number given by MapMyTracks.

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

Parameters

account (Account) – The account to be used. Alternatively a dict can be passed to build an ad hoc Account instance.

default_url = 'https://www.mapmytracks.com'
detach()[source]

also close session.

get_time() → datetime.datetime[source]

get MMT server time.

Returns

The server time

property mid

the member id on MMT belonging to Account.

Returns

The mid

property session

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

Returns

The session

property subscription

Return free or full.

Returns: free or full

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 gpxfiles and extend a gpxfile. That is what oruxmaps does - see examples/mmt_server.

TrackMMT is used to test mmt_server.

class gpxity.backends.trackmmt.TrackMMT(account)[source]

Bases: gpxity.backends.mmt.MMT

This is a minimal implementation, it only supports listing and retrieving gpxfiles 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.

detach()[source]

Would need implementations for scan and remove.

property subscription

Our own local server can do lifeftracking.

Returns

full

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

gpxity.backends.mailer module

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

class gpxity.backends.mailer.Mailer(account)[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.

url

Holds the address of the recipient.

account.mailfrom

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

account.port

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

account.smtp

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

account.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 gpxfiles with one single mail. Lifetracking uses this to send mails with the current gpxfile only every X seconds, the mail will only contain the latest version of the gpxfile.

Type

str

accepts_zero_points = True
detach()[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 GpxFile.category, GpxFile.status, GpxFile.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 GpxFile.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(account=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 the acounts file could look like:

Account wp
    Backend WPTrackserver
    Username wordpress_username
    Url localhost
    Mysql wordpress_7@wordpress_7
    Password xxxx
    Fences 53.7505,10.7445/750

Find the values for MySql in the wordpress config file (DB_USER and DB_NAME).

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

supported = {'keywords', 'remove', 'rename', 'scan', 'write'}
test_is_expensive = False

gpxity.backends.memory module

This implements gpxity.memory.Memory.

class gpxity.backends.memory.Memory(account=None)[source]

Bases: gpxity.backend.Backend

Keep it in RAM only.

Uses id(GpxFile) as id_in_backend, if none is given. Memory.clone() returns self._new_id_from

Useful if you want to do multiple manipulations and batch_changes() would be inconvenient.

Parameters

Account – If its url is unset, this will create a temporary directory named prefix.X where X are some random characters. It will be removed in __exit__ / detach.

accepts_zero_points = True
clone()[source]

Return myself.

supported = {'keywords', 'remove', 'rename', 'scan', 'write'}
test_is_expensive = False