Skip to content

Commit

Permalink
Updated unit tests for new ServiceRecord object, added a bunch more f…
Browse files Browse the repository at this point in the history
…or destination eligibility.
  • Loading branch information
cpfair committed Jun 1, 2013
1 parent 6b1f727 commit 3fc7ae0
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 58 deletions.
7 changes: 7 additions & 0 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import tapiriik.database
tapiriik.database.db = tapiriik.database._connection["tapiriik_test"]
tapiriik.database.cachedb = tapiriik.database._connection["tapiriik_cache_test"]

from tapiriik.testing import *
import unittest
unittest.main()

tapiriik.database._connection.drop_database("tapiriik_test")
tapiriik.database._connection.drop_database("tapiriik_cache_test")
8 changes: 4 additions & 4 deletions tapiriik/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def DisconnectService(serviceRecord, preserveUser=False):
def AuthByService(serviceRecord):
return db.users.find_one({"ConnectedServices.ID": serviceRecord._id})

def SetFlowException(user, sourceServiceRecord, targetServiceRecord, flowToTarget=True, flowtoSource=True):
def SetFlowException(user, sourceServiceRecord, targetServiceRecord, flowToTarget=True, flowToSource=True):
if "FlowExceptions" not in user:
user["FlowExceptions"] = []

Expand All @@ -107,10 +107,10 @@ def SetFlowException(user, sourceServiceRecord, targetServiceRecord, flowToTarge
user["FlowExceptions"][:] = [x for x in user["FlowExceptions"] if x != forwardException]
elif not flowToTarget and forwardException not in user["FlowExceptions"]:
user["FlowExceptions"].append(forwardException)
if flowtoSource is not None:
if flowtoSource:
if flowToSource is not None:
if flowToSource:
user["FlowExceptions"][:] = [x for x in user["FlowExceptions"] if x != backwardsException]
elif not flowtoSource and backwardsException not in user["FlowExceptions"]:
elif not flowToSource and backwardsException not in user["FlowExceptions"]:
user["FlowExceptions"].append(backwardsException)
db.users.update({"_id": user["_id"]}, {"$set": {"FlowExceptions": user["FlowExceptions"]}})

Expand Down
3 changes: 1 addition & 2 deletions tapiriik/services/Endomondo/endomondo.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ def DownloadActivity(self, serviceRecord, activity):
[x for x in activity.UploadedTo if x["Connection"] == serviceRecord][0].pop("ActivityData")
if len(activity.Waypoints) <= 1:
activity.Exclude = True
return activity
return activity # the activity is fully populated at this point, thanks to meh API design decisions
return activity

def UploadActivity(self, serviceRecord, activity):
#http://api.mobile.endomondo.com/mobile/track?authToken=token&workoutId=2013-02-27%2020:51:45%20EST&sport=18&duration=0.08&calories=0.00&hydration=0.00&goalType=BASIC&goalType=DISTANCE&goalDistance=0.000000&deflate=true&audioMessage=true
Expand Down
2 changes: 1 addition & 1 deletion tapiriik/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def _mergeConfig(base, config):
def HasConfiguration(svcRec):
if not svcRec.Service.Configurable:
return False # of course not
return "Config" in svcRec and len(svcRec.Config.values()) > 0
return hasattr(svcRec, "Config") and len(svcRec.Config.values()) > 0

def GetConfiguration(svcRec):
svc = svcRec.Service
Expand Down
75 changes: 41 additions & 34 deletions tapiriik/sync/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,43 @@ def _accumulateActivities(svc, svcActivities, activityList):
continue
activityList.append(act)

def _determineEligibleRecipientServices(activity, recipientServices, excludedServices, user, silent=False):
from tapiriik.auth import User
eligibleServices = []
for destinationSvcRecord in recipientServices:
if destinationSvcRecord in excludedServices:
if not silent: # Should really use legit logging instead of print()
print("\t\tExcluded " + destinationSvcRecord.Service.ID)
continue # we don't know for sure if it needs to be uploaded, hold off for now
flowException = False
if hasattr(activity, "Origin"):
# we know the activity origin - do a more intuitive flow exception check
if User.CheckFlowException(user, activity.Origin, destinationSvcRecord):
flowException = True
else:
for src in [x["Connection"] for x in activity.UploadedTo]:
if User.CheckFlowException(user, src, destinationSvcRecord):
flowException = True
break
# this isn't an absolute failure - it's possible we could still take an indirect route
# at this point there's no knowledge of the origin of this activity, so this behaviour would happen anyways at the next sync
if flowException:
for secondLevelSrc in [x for x in recipientServices if x != destinationSvcRecord]:
if not User.CheckFlowException(user, secondLevelSrc, destinationSvcRecord):
flowException = False
break
if flowException:
if not silent:
print("\t\tFlow exception for " + destinationSvcRecord.Service.ID)
continue
destSvc = destinationSvcRecord.Service
if destSvc.RequiresConfiguration(destinationSvcRecord) and not Service.HasConfiguration(destinationSvcRecord):
if not silent:
print("\t\t" + destSvc.ID + " not configured")
continue # not configured, so we won't even try
eligibleServices.append(destinationSvcRecord)
return eligibleServices

def PerformGlobalSync():
from tapiriik.auth import User
users = db.users.find({"NextSynchronization": {"$lte": datetime.utcnow()}, "SynchronizationWorker": None}) # mongoDB doesn't let you query by size of array to filter 1- and 0-length conn lists :\
Expand All @@ -102,7 +139,6 @@ def PerformGlobalSync():
db.sync_worker_stats.insert({"Timestamp": datetime.utcnow(), "Worker": os.getpid(), "TimeTaken": syncTime})

def PerformUserSync(user, exhaustive=False):
from tapiriik.auth import User
connectedServiceIds = [x["ID"] for x in user["ConnectedServices"]]

if len(connectedServiceIds) <= 1:
Expand Down Expand Up @@ -134,7 +170,7 @@ def PerformUserSync(user, exhaustive=False):
extAuthDetails = [x["ExtendedAuthorization"] for x in allExtendedAuthDetails if x["ID"] == conn._id]
if not len(extAuthDetails):
print("No extended auth details for " + svc.ID)
excludedServices.append(conn._id)
excludedServices.append(conn)
continue
# the connection never gets saved in full again, so we can sub these in here at no risk
conn.ExtendedAuthorization = extAuthDetails[0]
Expand All @@ -145,12 +181,12 @@ def PerformUserSync(user, exhaustive=False):
except (APIAuthorizationException, ServiceException, ServiceWarning) as e:
etype = SyncError.NotAuthorized if issubclass(e.__class__, APIAuthorizationException) else SyncError.System
tempSyncErrors[conn._id].append({"Step": SyncStep.List, "Type": etype, "Message": e.Message + "\n" + _formatExc(), "Code": e.Code})
excludedServices.append(conn._id)
excludedServices.append(conn)
if not issubclass(e.__class__, ServiceWarning):
continue
except Exception as e:
tempSyncErrors[conn._id].append({"Step": SyncStep.List, "Type": SyncError.System, "Message": _formatExc()})
excludedServices.append(conn._id)
excludedServices.append(conn)
continue
Sync._accumulateActivities(svc, svcActivities, activities)

Expand Down Expand Up @@ -197,36 +233,7 @@ def PerformUserSync(user, exhaustive=False):
# download the full activity record
print("\tActivity " + str(activity.UID) + " to " + str([x.Service.ID for x in recipientServices]))

eligibleServices = []
for destinationSvcRecord in recipientServices:
if destinationSvcRecord._id in excludedServices:
print("\t\tExcluded " + destinationSvcRecord.Service.ID)
continue # we don't know for sure if it needs to be uploaded, hold off for now
flowException = False
if hasattr(activity, "Origin"):
# we know the activity origin - do a more intuitive flow exception check
if User.CheckFlowException(user, activity.Origin, destinationSvcRecord):
flowException = True
else:
for src in [x["Connection"] for x in activity.UploadedTo]:
if User.CheckFlowException(user, src, destinationSvcRecord):
flowException = True
break
# this isn't an absolute failure - it's possible we could still take an indirect route
# at this point there's no knowledge of the origin of this activity, so this behaviour would happen anyways at the next sync
if flowException:
for secondLevelSrc in [x for x in recipientServices if x != destinationSvcRecord]:
if not User.CheckFlowException(user, secondLevelSrc, destinationSvcRecord):
flowException = False
break
if flowException:
print("\t\tFlow exception for " + destinationSvcRecord.Service.ID)
continue
destSvc = destinationSvcRecord.Service
if destSvc.RequiresConfiguration(destinationSvcRecord) and not Service.HasConfiguration(destinationSvcRecord):
print("\t\t" + destSvc.ID + " not configured")
continue # not configured, so we won't even try
eligibleServices.append(destinationSvcRecord)
eligibleServices = self._determineEligibleRecipientServices(activity=activity, recipientServices=recipientServices, excludedServices=excludedServices, user=user)

if not len(eligibleServices):
print("\t No eligible destinations")
Expand Down
2 changes: 1 addition & 1 deletion tapiriik/testing/gpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_constant_representation(self):

mid = GPXIO.Dump(act)

act2 = GPXIO.Parse(mid)
act2 = GPXIO.Parse(bytes(mid,"UTF-8"))
act2.TZ = act.TZ # we need to fake this since local TZ isn't defined in GPX files, and TZ discovery will flail with random activities
act2.AdjustTZ()
act.Distance = act2.Distance = None # same here
Expand Down
Loading

0 comments on commit 3fc7ae0

Please sign in to comment.