def test_my_ranking_weekly(self): from models import User, AuthToken, UserStats from django.test import RequestFactory from django.core.urlresolvers import reverse from views import my_ranking_weekly users = [] for i in range(10): u = User() u.email = '*****@*****.**' + str(i) u.public_name = 'TEST' + str(i) u.save() users.append(u) UserStats.record_stats(u, i * 100, datetime.date.today()) auth = AuthToken() auth.token_string = AuthToken.gen_token_string('*****@*****.**') auth.user = users[9] auth.valid = True auth.save() factory = RequestFactory() rq = factory.get(reverse('my_ranking_weekly'), data={'token': auth.token_string}) response = my_ranking_weekly(rq) data = json.loads(response.content) self.assertEqual(data['status'], 'OK')
def test_all_time(self): from models import UserStats, User import datetime from django.test import RequestFactory from django.core.urlresolvers import reverse from views import all_time_top_ten day = datetime.datetime(2017, 10, 20) for i in range(11): u = User(public_name='Roulio', email=str(i)) u.save() s = UserStats(user=u, start_date=day) s.monday_steps = 10 + i s.save() s = UserStats(user=u, start_date=day - datetime.timedelta(days=7)) s.monday_steps = 10 + i s.save() factory = RequestFactory() rq = factory.get(reverse('all_time_top_ten')) response = all_time_top_ten(rq) self.assertIsNotNone(response)
def top_ten(request): week = request.GET.get('week') if week: try: week = datetime.strptime(week, '%m-%d-%Y') except: return JsonResponse({'status': 'ILLEGAL_DATE_FORMAT'}) from models import UserStats top10_stats = UserStats.get_weekly_top_10(week) top10 = [] for s in top10_stats: all_time_stats = UserStats.get_all_time_stats(s.user) prestige, challenge_progress = divmod(all_time_stats.get('all_time_steps'), 100) top10.append({'name': s.user.public_name, 'id': s.user.pk, 'prestige': prestige, 'total_steps': s.total_steps() }) return JsonResponse({'status': 'OK', 'top_10': top10, })
def my_ranking_weekly(request): from models import UserStats week = request.GET.get('week') token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) token = AuthToken.objects.get(token_string=token_param) if week: try: week = datetime.strptime(week, '%m-%d-%Y') except: return JsonResponse({'status': 'ILLEGAL_DATE_FORMAT'}) ranking_list = [] for ranking, user, total_steps, isUser in UserStats.get_weekly_ranking(token.user, week): all_time_stats = UserStats.get_all_time_stats(user) prestige, challenge_progress = divmod(all_time_stats.get('all_time_steps'), 100) ranking_list.append({'name': user.public_name, 'id': user.pk, 'prestige': prestige, 'total_steps': total_steps, 'isUser': isUser, 'ranking': ranking, }) return JsonResponse({'status': 'OK', 'ranking': ranking_list, })
def userFeed(self, targetdate, user, reqId): if user: logging.info('getting stats for user: %s' %user) stats = UserStats.gql('WHERE instapaper_account = :1 order by date desc', user).fetch(14) if stats is None: logging.info('Not enough data for graph') self.repsonse.out.write('Not enough data for graph') return stats = [ x for x in stats if x is not None ] logging.info('retrieved %s stats' % len(stats)) description = {"date": ("string", "Date"), "count":("number", "Count")} columnnames = [ "date", "count" ] data_table = gviz_api.DataTable(description) userCnt = [] for uCnt in stats: logging.info('account:%s' % uCnt.to_xml()) entry = {"date": uCnt.date, "count":uCnt.count} userCnt.append(entry) data_table.LoadData(userCnt) self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(data_table.ToJSonResponse(columns_order=(columnnames) , req_id=reqId)) return if not targetdate: today = datetime.date.today() yesterday=datetime.date.today() - datetime.timedelta(days=1) targetdate=yesterday else: try: targetdate=datetime.datetime.strptime(targetdate, '%Y-%m-%d').date() except: e = sys.exc_info()[1] logging.error('error formating date %s => %s' %(targetdate, e)) targetdate=datetime.date.today() - datetime.timedelta(days=1) logging.info('User stats feed') stats = UserStats.gql('WHERE date = :1 and count > 10 order by count desc', targetdate).fetch(50) if stats is None: logging.info('Not enough data for graph') self.repsonse.out.write('Not enough data for graph') return stats = [ x for x in stats if x is not None ] logging.info('retrieved %s stats' % len(stats)) description = {"account": ("string", "User"), "count":("number", "Count")} columnnames = [ "account", "count" ] data_table = gviz_api.DataTable(description) userCnt = [] for uCnt in stats: logging.info('account:%s' % uCnt.to_xml()) entry = {"account": uCnt.instapaper_account, "count":uCnt.count} userCnt.append(entry) data_table.LoadData(userCnt) self.response.headers['Content-Type'] = 'text/plain' self.response.out.write(data_table.ToJSonResponse(columns_order=(columnnames) , req_id=reqId))
def save(self): profile = UserProfile() stats = UserStats() stats.save() username = self.cleaned_data["username"] email = self.cleaned_data["email"] password = self.cleaned_data["password"] display_image = self.cleaned_data["display_image"] if display_image is None: admin = UserProfile.objects.get(id=1) display_image = admin.display_image profile.user = User.objects.create_user(username, email, password) profile.display_image = display_image profile.stats = stats profile.save()
def my_ranking_all_time(request): from models import UserStats token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) token = AuthToken.objects.get(token_string=token_param) ranking_list = [] for ranking, user, total_steps, isUser in UserStats.get_all_time_ranking(token.user): prestige, challenge_progress = divmod(total_steps, 100) ranking_list.append({'name': user.public_name, 'id': user.pk, 'prestige': prestige, 'total_steps': total_steps, 'isUser': isUser, 'ranking': ranking, }) return JsonResponse({'status': 'OK', 'ranking': ranking_list, })
def log_distance(request): from models import UserStats token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) steps = request.GET.get('steps') if not steps: HttpResponseBadRequest('steps parameter is required') steps = int(steps) token = AuthToken.objects.get(token_string=token_param) user = token.user UserStats.record_stats(user, steps) return JsonResponse({'status': 'OK'})
def _get_user_stats(self, user): """Returns stat for one user in readable form.""" rank = self._get_ranklist()[user.key] statList = {'wins': user.wins, 'losses': user.losses, 'ties': user.ties, 'points': user.points, 'name': user.name, 'rank': rank } us = UserStats() for field in us.all_fields(): for name in statList: if field.name == name: setattr(us, field.name, statList[name]) return us
def profile(request): token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) from models import UserStats token = AuthToken.objects.get(token_string=token_param) weekly_stats = UserStats.get_weekly_stats(token.user) all_time_stats = UserStats.get_all_time_stats(token.user) prestige, challenge_progress = divmod(all_time_stats.get('all_time_steps'), 100) return JsonResponse({'status': 'OK', 'nick_name': token.user.public_name, 'all_time_stats': all_time_stats, 'weekly_stats': weekly_stats, 'current_challenge': { 'id': '1', 'prestige': prestige, 'name': 'mount_europa', 'total_steps': '100', 'current_steps': challenge_progress, }, })
def get(self, d): if d is None: logging.info('no date.exit') return date=datetime.datetime.strptime(d, '%Y-%m-%d').date() #if period == 'daily': # allUsers = UserStats.all() #else: # self.response.out.write('get outta here') # return allUsers = UserStats.gql('WHERE date = :1', date).fetch(1000) if not allUsers: logging.info('not stats for %s delete , exit' %d) return logging.info('total stats for %s delete %d' % (d, len(allUsers))) for u in allUsers: u.delete() logging.info('done')
def getBadge(self): targetdate=datetime.datetime.now().date() - datetime.timedelta(days=1) stats = UserStats.gql('WHERE date = :1 and count > 10 order by count desc', targetdate).fetch(3) logging.info('trophy badger: fetched stats %s' % len(stats)) stats = [ s.instapaper_account for s in stats if s is not None ] if stats is None or len(stats) == 0: logging.info('Not enough data for calc badge') return None if stats[0] == self.user: logging.info('User was number ONE user yesterday') return '1' if stats[1] == self.user: logging.info('User was number TWO user yesterday') return '2' if stats[2] == self.user: logging.info('User was number THREE user yesterday') return '3' logging.info('trophy badge %s: not initialized' % self.user ) return None
def get(self, period): date_ = self.request.get('date', None) if date_: date = datetime.datetime.strptime(date_, '%Y-%m-%d') else: date = datetime.datetime.now() - datetime.timedelta(days=1) logging.info('fetching stats for %s and %s' %(period,str(date.date()))) if period == 'daily': stats = UserStats.gql('WHERE date = :1 order by count desc', date).fetch(100) elif period == 'weekly': self.response.out.write('TODO') return else: self.response.out.write('Get outta here') return if not stats: self.response.out.write('not stats for %s and date %s retreived no data' %( period, date_)) return self.response.headers["Content-type"] = "application/json" self.response.out.write(simplejson.dumps(stats, default=lambda s: {'u':{'account':s.instapaper_account, 'cout': s.count}}))
def all_time_top_ten(request): from models import UserStats top10_stats = UserStats.get_all_time_top_10() top10 = [] for user, steps in top10_stats: if steps == 0: continue prestige, challenge_progress = divmod(steps, 100) top10.append({'name': user.public_name, 'id': user.pk, 'prestige': prestige, 'total_steps': steps }) return JsonResponse({'status': 'OK', 'top_10': top10, })
def weekly_stat(request): week = request.GET.get('week') token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) if week: try: week = datetime.strptime(week, '%m-%d-%Y') except: return JsonResponse({'status': 'ILLEGAL_DATE_FORMAT'}) from models import UserStats token = AuthToken.objects.get(token_string=token_param) weekly_stats = UserStats.get_weekly_stats(token.user, week) return JsonResponse({'status': 'OK', 'week_of': week - datetime.timedelta(days=week.weekday()), 'weekly_stats': weekly_stats, })
def test_total_steps(self): from models import UserStats import datetime today = datetime.datetime(2017, 10, 20) monday = today - datetime.timedelta(days=today.weekday()) tuesday = monday + datetime.timedelta(days=1) wednesday = monday + datetime.timedelta(days=2) thursday = monday + datetime.timedelta(days=3) friday = monday + datetime.timedelta(days=4) saturday = monday + datetime.timedelta(days=5) sunday = monday + datetime.timedelta(days=6) s = UserStats() s.add(25, monday) s.add(25, monday) s.add(7, tuesday) s.add(89, wednesday) s.add(2, thursday) s.add(3, friday) s.add(5, saturday) s.add(9, sunday) self.assertEqual(s.total_steps(), 25 + 25 + 7 + 89 + 2 + 3 + 5 + 9)
def test_add(self): from models import UserStats import datetime today = datetime.datetime(2017, 10, 20) monday = today - datetime.timedelta(days=today.weekday()) tuesday = monday + datetime.timedelta(days=1) wednesday = monday + datetime.timedelta(days=2) thursday = monday + datetime.timedelta(days=3) friday = monday + datetime.timedelta(days=4) s = UserStats() self.assertEqual(s.monday_steps, 0) s.add(25, monday) self.assertEqual(s.monday_steps, 25) s.add(25, monday) self.assertEqual(s.monday_steps, 50) s.add(7, tuesday) self.assertEqual(s.tuesday_steps, 7) s.add(89, wednesday) self.assertEqual(s.wednesday_steps, 89) s.add(2, thursday) self.assertEqual(s.thursday_steps, 2) s.add(3, friday) self.assertEqual(s.friday_steps, 3)
def post(self): dt = self.request.get("date", None) cursor = self.request.get("last_cursor", None) logging.info("date from request %s " % dt) if dt is None: date = datetime.datetime.now().date() - datetime.timedelta(days=1) logging.info("aggregatine users from yesterday.") else: date = datetime.datetime.strptime(dt, "%Y-%m-%d").date() if date >= datetime.datetime.now().date(): logging.info("too early , wait") self.response.out.write("too early . wait") return memcache_key_sessions = ( "sessions_for_date_" + str(datetime.datetime.today().date()) + "_" + str(date) + "_" + str(cursor) ) cached_sessions = memcache.get(memcache_key_sessions) if cached_sessions: logging.info("getting from cache for date %s" % str(date)) sessions = cached_sessions else: sessions = SessionModel.getDailyDataWithOffset(date, cursor) logging.info("session batch size %d" % len(sessions)) memcache.set(memcache_key_sessions, sessions) if sessions is None: logging.info("no sessions for date %s" % str(date)) return for s in sessions: memcache_key_s = "user_detail_" + str(datetime.datetime.now().date()) + "_" + str(date) + "_" + str(s.key()) if memcache.get(memcache_key_s): logging.info("skippin processed key %s for date %s" % (s.key(), str(date))) continue # links stats add to queue taskqueue.add( queue_name="data-consolidation", url="/aggregate_data", params={"sessionKey": s.key(), "upper_limit_date": date}, ) # TODO also create tas cue for user consolidation userStats = UserStats.gql("WHERE instapaper_account = :1 and date = :2", s.instaright_account, date).get() if userStats is None: logging.info("no user stats for user: %s and date: %s" % (s.instaright_account, str(date))) userStats = UserStats() userStats.instapaper_account = s.instaright_account userStats.count = 1 userStats.date = date userStats.put() else: logging.info("updating user stats for user %s and date %s" % (s.instaright_account, str(date))) userStats.count = userStats.count + 1 userStats.put() user_detail = UserDetails.gql("WHERE instapaper_account = :1", s.instaright_account).get() if user_detail is None: logging.info("new user: %s" % s.instaright_account) user_detail = UserDetails() user_detail.instapaper_account = s.instaright_account user_detail.last_active_date = s.date user_detail.put() # task queue that gathers info try: fetch_task_url = "/user/" + urllib2.quote(s.instaright_account) + "/fetch" except: logging.warn("can't fetch info for user %s " % s.instaright_account) logging.info("adding task on url %s" % fetch_task_url) taskqueue.add(queue_name="user-info", url=fetch_task_url) else: logging.info("updating usage for user: %s" % s.instaright_account) user_detail.last_active_date = s.date user_detail.links_added = user_detail.links_added + 1 user_detail.put() memcache.set(memcache_key_s, s.key()) # IMPORTANT:delete daily badges for user memcache.delete("badge_" + s.instaright_account) logging.info("done for date %s" % str(date)) self.response.out.write("done for date %s" % str(date))
from google.appengine.ext import db from models import UserStats ss = UserStats.all() print ss.count() for s in ss: print s.date print s.count