Exemple #1
0
 def setUp(self):
     self.central = pytz.timezone('US/Central')
     self.now = datetime.datetime.now(tz=self.central)
     self.race = Race(race_name='Test Race', race_type=Race.RACE_TYPE_FINALS, race_start_time=self.now)
     self.race.save()
     self.race_control = RaceControl(current_race=self.race)
     self.race_control.save()
     
     self.pick_checkpoint = Checkpoint(checkpoint_number=1, checkpoint_name="Test Checkpoint 1")
     self.pick_checkpoint.save()
     self.drop_checkpoint = Checkpoint(checkpoint_number=2, checkpoint_name="Test Checkpoint 2")
     self.drop_checkpoint.save()
     self.other_checkpoint = Checkpoint(checkpoint_number=3, checkpoint_name="Test Checkpoint 3")
     self.other_checkpoint.save()
     
     self.ready_now_job = Job(job_id=1, race=self.race, pick_checkpoint=self.pick_checkpoint, drop_checkpoint=self.drop_checkpoint, minutes_ready_after_start=0)
     self.ready_now_job.save()
             
     self.racer = Racer(racer_number=320, first_name='Doug', last_name='Suriano', category=Racer.RACER_CATEGORY_MESSENGER)
     self.racer.save()
     
     self.raceentry = RaceEntry(racer=self.racer, race=self.race)
     self.raceentry.save()
     
     self.run = Run(pk=1, job=self.ready_now_job, race_entry=self.raceentry, status=Run.RUN_STATUS_PICKED, utc_time_picked=datetime.datetime.now(tz=pytz.utc))
     self.run.save()
Exemple #2
0
def index(request):
		#user = User.get_by_key_name("key_"+self.cleaned_data['username'].lower())
		username = request.user.username
		user = User.get_by_key_name("key_"+username.lower())
		if user and user.is_active:
			last_scrape = user.nike_last_scrape
		else:
			last_scrape = None
		return object_list(request, Run.all().filter('user ='******'-run_time'),
		                   extra_context={'last_scrape':last_scrape})
Exemple #3
0
class DropTestCase(APITestCase):
    def setUp(self):
        self.central = pytz.timezone('US/Central')
        self.now = datetime.datetime.now(tz=self.central)
        self.race = Race(race_name='Test Race', race_type=Race.RACE_TYPE_FINALS, race_start_time=self.now)
        self.race.save()
        self.race_control = RaceControl(current_race=self.race)
        self.race_control.save()
        
        self.pick_checkpoint = Checkpoint(checkpoint_number=1, checkpoint_name="Test Checkpoint 1")
        self.pick_checkpoint.save()
        self.drop_checkpoint = Checkpoint(checkpoint_number=2, checkpoint_name="Test Checkpoint 2")
        self.drop_checkpoint.save()
        self.other_checkpoint = Checkpoint(checkpoint_number=3, checkpoint_name="Test Checkpoint 3")
        self.other_checkpoint.save()
        
        self.ready_now_job = Job(job_id=1, race=self.race, pick_checkpoint=self.pick_checkpoint, drop_checkpoint=self.drop_checkpoint, minutes_ready_after_start=0)
        self.ready_now_job.save()
                
        self.racer = Racer(racer_number=320, first_name='Doug', last_name='Suriano', category=Racer.RACER_CATEGORY_MESSENGER)
        self.racer.save()
        
        self.raceentry = RaceEntry(racer=self.racer, race=self.race)
        self.raceentry.save()
        
        self.run = Run(pk=1, job=self.ready_now_job, race_entry=self.raceentry, status=Run.RUN_STATUS_PICKED, utc_time_picked=datetime.datetime.now(tz=pytz.utc))
        self.run.save()
    
    def test_not_matching_confirm_code_with_racer(self):
        data = {'racer_number' : 999, 
                'checkpoint': 2,
                'confirm_code' : 1
        }
        response = self.client.post('/api/v1/drop/', data, format='json')
        self.assertEqual(response.data, {'error' : True, 'error_title' : 'Wrong Racer #', 'error_description' : 'Racer # 999 does not a drop off with confirm code 1.'})
    
    def test_incorrect_confirm_code(self):
        data = {'racer_number' : 320, 
                'checkpoint': 2,
                'confirm_code' : 99
        }
        response = self.client.post('/api/v1/drop/', data, format='json')
        self.assertEqual(response.data, {'error' : True, 'error_title' : 'Cannot Find Confirm Code', 'error_description' : "No job's' drop off assoicated with confirm code 99."})
    
    def test_wrong_checkpint(self):
        data = {'racer_number' : 320, 
                'checkpoint': 6,
                'confirm_code' : 1
        }
        response = self.client.post('/api/v1/drop/', data, format='json')
        self.assertEqual(response.data, {'error' : True, 'error_title' : 'Wrong Checkpoint', 'error_description' : 'This drop off needs to be made at Test Checkpoint 2.'})
    
    def test_racer_already_dropped_off(self):
        data = {'racer_number' : 320, 
                'checkpoint': 2,
                'confirm_code' : 1
        }
        response = self.client.post('/api/v1/drop/', data, format='json')
        drop_time = datetime.datetime.now(tz=self.central).strftime('%I:%M %p')
        response = self.client.post('/api/v1/drop/', data, format='json')
        self.assertEqual(response.data, {'error' : True, 'error_title' : 'Job already dropped off', 'error_description' : 'The run was already dropped off at {}.'.format(drop_time)})
    
    def test_ok_drop(self):
        data = {'racer_number' : 320, 
                'checkpoint': 2,
                'confirm_code' : 1
        }
        response = self.client.post('/api/v1/drop/', data, format='json')
        self.assertEqual(response.data, {'error' : False, 'error_title' : None, 'error_description' : None})
Exemple #4
0
def get_nike_plus_data(request):


	# TODO: protect against the case where a user_id hasn't been set. force this to be set upon registration?
	# TODO: Only set new last_scrape_time if the scrape is successful
	
	username = request.user.username
	user = User.get_by_key_name("key_"+username.lower())
	
	if user and user.is_active:
		last_scrape_time = user.nike_last_scrape
		userId = user.nike_user_id
	else:
		last_scrape_time = None
		
	if not last_scrape_time:
		last_scrape_time = datetime.datetime(1970, 1, 1) # Set it to an arbitrary early date
				
	#response = urllib2.urlopen('http://nikeplus.nike.com/nikeplus/v1/services/widget/get_public_run_list.jsp?userID=%s' % userId).read()
	#response = urlfetch.fetch('https://secure-nikerunning.nike.com/nikeplus/v1/services/app/run_list.jsp')
	#response = urlfetch.fetch('http://nikerunning.nike.com/nikeplus/v2/services/app/run_list.jsp?userID=%s&startIndex=0&endIndex=5' % userId)
	
	# don't specify startIndex and endIndex in the URL i.e. get all runs
	response = urlfetch.fetch('http://nikerunning.nike.com/nikeplus/v2/services/app/run_list.jsp?userID=%s' % userId)
	import logging
	logging.debug(response.content)		
	
	dom = minidom.parseString(response.content)
	
	run_ids_and_times = []
	# N.B. in the following code I replaced 'startTime' with 'syncTime' - this makes sense
	
	# AUG 14TH 2010 - NOTE - THIS IS PROBABLY REALLY INEFFICIENT!!!
	# WOULD BE BETTER TO LIMIT THE AMOUNT OF RUNS I GET IN THE REQUEST (i.e. use startIndex/endIndex)
	# THIS LIMIT NEEDS TO BE BASED ON nike_last_scrape
	#
	# IDEA: START AT END OF XML FILE AND MOVE BACKWARDS, CHECKING THE syncTime value until
	# it becomes earlier than nike_last_scrape 
	for run in dom.getElementsByTagName('run'):
		run_id = run.getAttribute('id')
		
		sync_time = run.getElementsByTagName('syncTime')[0]
		sync_time = sync_time.toxml()
		sync_time = sync_time.replace('<syncTime>', '') # Get rid of the opening syncTime tag
		sync_time = sync_time.split('+')[0] # Strip off the time zone stuff and closing tag
		sync_time = datetime.datetime.strptime(sync_time, '%Y-%m-%dT%H:%M:%S')
		
		run_ids_and_times.append((run_id, sync_time))
		##run = Run(run_id=run_id, run_time=run_time)
		##run.put()
		
	# Only keep the runs which have been synced after the last_scrape_time
	run_ids_and_times = [(run_id, t) for (run_id, t) in run_ids_and_times if t > last_scrape_time]

	# Set last scrape time to now
	# TODO - uncomment the following line
	#user.nike_last_scrape = datetime.datetime.now()
	user.put()
	
	# No new runs so just return
	# TODO: Give the user some feedback e.g. a message saying 'No new runs'
	if len(run_ids_and_times) == 0:
		return HttpResponseRedirect('/runs/')
		
	cookie = Cookie.SimpleCookie()
	cookie.load(response.headers.get('set-cookie', ''))
	cookie['plusid'] = user.nike_user_id +"&nikerunning.nike.com"
	headers = {
				'Host' : 'runlogger.appspot.com',
				'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)',
				'Cookie' : _makeCookieHeader(cookie)
			  }
	
	# Save the new run(s)
	for run in dom.getElementsByTagName('run'):
		for (run_id, t) in run_ids_and_times:
			if run.getAttribute('id') == run_id:
				
				# Get the time the run started
				run_time = run.getElementsByTagName('startTime')[0]
				run_time = run_time.toxml()
				run_time = run_time.replace('<startTime>', '') # Get rid of the opening startTime tag
				run_time = run_time.split('+')[0] # Strip off the time zone stuff and closing tag
				run_time = datetime.datetime.strptime(run_time, '%Y-%m-%dT%H:%M:%S')
				
				distance = run.getElementsByTagName('distance')[0]
				distance = distance.toxml()
				distance = distance.replace('<distance>', '')
				distance = distance.replace('</distance>', '')
				
				dist_len = len('%.2f' % float(distance)) # Length of distance string when truncated to 2 D.P.
				distance = float(distance[:dist_len])
				
				duration = run.getElementsByTagName('duration')[0]
				duration = duration.toxml()
				duration = duration.replace('<duration>', '')
				duration = duration.replace('</duration>', '')
				# TODO - TEST OUT THIS CODE WITH RUNS OVER AN HOUR LONG - WILL IT WORK?
				duration = float(duration)/1000/60 # Convert duration in ms to minutes
				decimal_part_of_mins, mins = math.modf(duration)
				gt_1hour = False
				if mins >= 60:
					gt_1hour = True
					mins_when_duration_gt_1hour, hours = math.modf(mins/60)
					mins = mins_when_duration_gt_1hour * 60
					
				secs = decimal_part_of_mins * 60
				
				if gt_1hour:
					duration_pretty = '%s:%s:%02d' % (int(hours), int(round(mins)), int(round(secs)))
				else:
					duration_pretty = '%s:%02d' % (int(mins), int(round(secs)))
				
				# Get GPX data
				# TODO - don't hardcode the run ID!
				response = urlfetch.fetch('https://secure-nikerunning.nike.com/nikeplus/v2/services/app/get_gps_detail.jsp?_plus=true&id=%s&format=json' % run_id, headers=headers)
				
				logging.debug('gpx data is:')
				logging.debug(response.content)			
				new_run = Run(user=user, run_id=run_id, run_time=run_time, distance=distance, 
								duration=duration, duration_pretty=duration_pretty, gpx_data=unicode(response.content))
				new_run.put()
	
	return HttpResponseRedirect('/runs/')
Exemple #5
0
def detail(request, key):
	# isn't there a better way to do this?
	# e.g. by doing p = Poll.get_by_key_name(key) - didn't seem to work for me
	p = db.get(key)
	return object_detail(request, Run.all(), key)