Commits

Anonymous committed 5eb7c7e Draft

Aggregate status by hour

  • Participants
  • Parent commits 26dc018

Comments (0)

Files changed (4)

 cron:
+
 - description: get online status
   url: /task/status
-  schedule: every 5 minutes
+  schedule: every 1 minutes
+
+- description: hour aggregation
+  url: /task/status/hour
+  schedule: every 1 hours
 </head>
 <body>
 
-	<h1>online status</h1>
+<a href="/">По часам</a>
+<a href="/minute">По минутам</a>
+
 	<div id="chart_div" style="width: 1100px; height: 500px;"></div>
 
 </body>
   properties:
   - name: user_id
   - name: time
+
+- kind: Status
+  properties:
+  - name: user_id
+  - name: time
+    direction: desc
+
+- kind: StatusHour
+  properties:
+  - name: user_id
+  - name: time
+    direction: desc
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 
-import webapp2
+import md5
 import logging
+import time
+import datetime
+from webapp2 import RequestHandler, WSGIApplication
+
 
 from google.appengine.ext import db
+from google.appengine.api import taskqueue
 
 import vkontakte
 
 
 
 class Status(db.Model):
+	user_id = db.IntegerProperty(required=True)
 	time = db.DateTimeProperty(auto_now_add=True)
-	user_id = db.IntegerProperty(required=True)
 	online = db.IntegerProperty()
 
+class StatusHour(db.Model):
+	user_id = db.IntegerProperty()
+	time = db.DateTimeProperty()
+	online = db.IntegerProperty(default=0)
+
 log = logging.getLogger('task')
 
-class GetStatus(webapp2.RequestHandler):
+###############
+##   Tasks   ##
+###############
+
+date_format = '%y-%m-%d-%H'
+
+class GetStatus(RequestHandler):
 	def get(self):
-		self.response.headers['Content-Type'] = 'text/html'
-		
 		user_id = USER_ID
 		online = get_status(user_id)
 		log.info('Online: %d' , online)
 		status = Status(user_id=user_id, online=online)
 		status.put()
 
+		if online > 0:
+			timeParam = status.time.strftime(date_format)
+			try:
+				taskqueue.add(url='/task/status/hour', name='aggregate-hour-'+timeParam, params={'time': timeParam})
+			except taskqueue.TaskAlreadyExistsError:
+				pass
+
 	def post(self):
 		self.get()
 
 
+def get_key(user_id, time_str):
+	'Create key for StatusHour'
+	m = md5.new(str(user_id)+time_str)
+	return m.hexdigest()
+
+class GetStatusHour(RequestHandler):
+
+	def get(self):
+		user_id = USER_ID
+		timeParam = self.request.get('time')
+		
+		update = True
+		if timeParam == '':
+			update = False
+			timeParam = datetime.datetime.now().strftime(date_format)
+			log.info('Aggregate '+timeParam)
+		
+		key = get_key(user_id, timeParam)
+		st = StatusHour.get_or_insert(key)
+
+		if st.user_id is None: # create new
+			st.user_id = user_id
+			st.time = datetime.datetime.strptime(timeParam, date_format)
+			st.put()
+
+		if update: # status changed
+			st.online = 1
+			st.put()
+
+	def post(self):
+		self.get()	
+
+
 #########################
 ##        Graph        ##
 #########################
 
 import jinja2
 import os
-import datetime
 
 jinja_environment = jinja2.Environment(
     loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
 
-class GraphStatus(webapp2.RequestHandler):
+class GraphStatus(RequestHandler):
 	def get(self):
 		user_id = USER_ID
-		time = datetime.datetime.now() + datetime.timedelta(-7)
 		statuses = Status.all()\
 			.filter('user_id', user_id)\
-			.filter('time > ', time)\
-			.order('time')
+			.order('-time').fetch(1000)
 		
+		def byDate(st):
+			return st.time
+
+		statuses = sorted(statuses, key=byDate)
 		for status in statuses:
 			status.timestamp = int(status.time.strftime('%s'))*1000
 
 		self.response.out.write(template.render(template_values))
 
 
-app = webapp2.WSGIApplication([('/task/status', GetStatus),
-							   ('/', GraphStatus),
+
+class GraphStatusHour(RequestHandler):
+	def get(self):
+		user_id = USER_ID
+		statuses = StatusHour.all()\
+			.filter('user_id', user_id)\
+			.order('-time').fetch(1000)
+		
+		def byDate(st):
+			return st.time
+
+		statuses = sorted(statuses, key=byDate)
+		for status in statuses:
+			status.timestamp = int(status.time.strftime('%s'))*1000
+
+		template_values = {
+			'user_id': user_id,
+			'statuses': statuses
+		}
+		template = jinja_environment.get_template('index.html')
+		self.response.out.write(template.render(template_values))
+
+
+app = WSGIApplication([('/task/status', GetStatus),
+					   ('/task/status/hour', GetStatusHour),
+					   ('/minute', GraphStatus),
+					   ('/', GraphStatusHour),
 							  ],
                               debug=True)