コード例 #1
0
ファイル: connect.py プロジェクト: detcherry/phonoblaster
	def post(self):
		channel_id = str(self.request.get('from'))
		logging.info("%s is ready to receive messages" %(channel_id))
		
		# Init station proxy
		m = re.match(r"(\w+).(\w+)", channel_id)
		shortname = m.group(1)
		station_proxy = StationApi(shortname)
		
		extended_session = station_proxy.add_to_sessions(channel_id)
		
		if(extended_session):
			# Add a taskqueue to warn everyone
			new_session_data = {
				"entity": "session",
				"event": "new",
				"content": extended_session,
			}
			task = Task(
				url = "/taskqueue/multicast",
				params = {
					"station": config.VERSION + "-" + shortname,
					"data": json.dumps(new_session_data)
				}
			)
			task.add(queue_name="sessions-queue")
コード例 #2
0
ファイル: tracks.py プロジェクト: detcherry/phonoblaster
	def get(self):
		shortname = self.request.get("shortname")
		offset = self.request.get("offset")
		station_proxy = StationApi(shortname)
		
		if(station_proxy.station and offset):
			extended_tracks = station_proxy.get_tracks(datetime.utcfromtimestamp(int(offset)))
			self.response.out.write(json.dumps(extended_tracks))
		else:
			self.error(404)
コード例 #3
0
ファイル: profile.py プロジェクト: detcherry/phonoblaster
	def saveProfile(self, key_name, shortname, name, link, type, full, thumb):
		user_profiles = self.user_proxy.profiles
		for i in xrange(0,len(user_profiles)):
			if key_name == user_profiles[i]["key_name"] and user_profiles[i]["created"] is None:
				
				station_proxy = StationApi(shortname)
				station_proxy.put_station(key_name, shortname, name, link, type, full, thumb)
				
				self.user_proxy.set_profile(key_name)
				self.response.out.write(json.dumps({'response': True}))
				
				break
コード例 #4
0
ファイル: likes.py プロジェクト: detcherry/phonoblaster
	def get(self):
		shortname = self.request.get("shortname")
		offset = self.request.get("offset")
		
		host_proxy = StationApi(shortname)
		host = host_proxy.station

		if(host and offset):
			extended_likes = host_proxy.get_likes(datetime.utcfromtimestamp(int(offset)))
			self.response.out.write(json.dumps(extended_likes))
		else:
			self.error(404)
コード例 #5
0
ファイル: likes.py プロジェクト: detcherry/phonoblaster
	def post(self):
		content = json.loads(self.request.get("content"))
		
		response = False;
		if(content["track_id"]):
			track = Track.get_by_id(int(content["track_id"]))
			
			# Check if the track exists on Phonoblaster
			if(track):
				profile = self.user_proxy.profile
				profile_proxy = StationApi(profile["shortname"])
				profile_proxy.add_to_likes(track)
				response = True
		
		self.response.out.write(json.dumps({ "response": response }))
コード例 #6
0
ファイル: background.py プロジェクト: detcherry/phonoblaster
	def post(self, shortname):
		self.blobstore_url = blobstore.create_upload_url('/api/' + shortname + "/background")
		
		self.station_proxy = StationApi(shortname)
		if(self.station_proxy.station):			
			self.process()
		else:
			self.error(404)
コード例 #7
0
ファイル: sessions.py プロジェクト: detcherry/phonoblaster
	def post(self):
		shortname = self.request.get("shortname")
		station_proxy = StationApi(shortname)
		station = station_proxy.station 
		
		output = {}
		if(station):
			# Increment visits counter 
			station_proxy.increment_visits_counter()
			
			# Channel ID and token generation
			time_now = str(timegm(gmtime()))
			random_integer = str(randrange(1000))
			new_channel_id = shortname + "." + time_now + random_integer
			new_channel_token = channel.create_channel(new_channel_id)
			
			listener_key = None
			if(self.user_proxy):
				listener_key = self.user_proxy.user.profile.key()
			
			# Put new session in datastore
			new_session = Session(
				key_name = new_channel_id,
				channel_token = new_channel_token,
				listener = listener_key,
				host = station.key(),
			)
			new_session.put()
			logging.info("New session saved in datastore")

			output = {
				"channel_id": new_channel_id,
				"channel_token": new_channel_token,
			}
			self.response.out.write(json.dumps(output))
		else:
			self.error(404)
			
コード例 #8
0
ファイル: background.py プロジェクト: detcherry/phonoblaster
class ApiBackgroundHandler(PictureHandler):
	def post(self, shortname):
		self.blobstore_url = blobstore.create_upload_url('/api/' + shortname + "/background")
		
		self.station_proxy = StationApi(shortname)
		if(self.station_proxy.station):			
			self.process()
		else:
			self.error(404)
	
	def save(self, image):		
		image_url = "/picture/" + str(image.key()) + "/view"
		thumbnail_blob_key = self.save_thumbnail(image) 
		thumbnail_url = "/picture/" + str(thumbnail_blob_key) + "/view"
		
		self.station_proxy.update_background(image_url, thumbnail_url)					
		
		data = {
			"entity": "background",
			"event": "new",
			"content": image_url,
		}
		
		task = Task(
			url = "/taskqueue/multicast",
			params = {
				"station": config.VERSION + "-" + self.station_proxy.station.shortname,
				"data": json.dumps(data)
			}
		)
		task.add(queue_name="worker-queue")
		
		self.response.out.write(json.dumps({
			"response": True,
			"src_full": image_url,
			"src_thumb": thumbnail_url,
			"blobstore_url": self.blobstore_url,
		}))
コード例 #9
0
ファイル: home.py プロジェクト: detcherry/phonoblaster
	def get(self):
		if(self.user_proxy):
			user = self.user_proxy.user
			user_profile = StationApi(self.user_proxy.profile["shortname"])
			user_broadcasts = user_profile.reorder_buffer(user_profile.buffer)["broadcasts"]
			user_live_broadcast = None
			if(len(user_broadcasts)>0):
				user_live_broadcast = user_broadcasts[0]

			live_broadcasts = []
			latest_active_stations = []
			
			q = Station.all()
			q.order("-active")
			stations = q.fetch(30)
			logging.info(str(len(stations))+" latest stations retrieved from datastore")

			all_broadcasts_keys = []
			for i in xrange(0,len(stations)):
				all_broadcasts_keys.extend(stations[i].broadcasts)
			
			all_broadcasts = db.get(all_broadcasts_keys)
			logging.info(str(len(all_broadcasts))+" broadcasts associated with stations retrieved from datastore")			
			
			couple = {}
			for s in stations:
				name = str(s.key().name())
				couple[name] = {
					"station": s,
					"broadcasts": [],
					"live": None,
				}
				
			for b in all_broadcasts:
				name = str(Broadcast.station.get_value_for_datastore(b).name())
				couple[name]["broadcasts"].append(b)
			logging.info("Broadcasts group by station")
						
			# What is the live track for each station?
			now = datetime.utcnow()
			for k, v in couple.iteritems():
				station = v["station"]
				broadcasts = v["broadcasts"]
				
				timestamp = station.timestamp
				
				elapsed = 0
				live = None
				
				total_duration = 0
				for broadcast in broadcasts:
					if(broadcast.youtube_duration):
						total_duration += broadcast.youtube_duration
					else:
						if(broadcast.soundcloud_duration):
							total_duration += broadcast.soundcloud_duration
						else:
							total_duration += 0
				
				# Check if buffer is not empty
				if total_duration > 0:
					offset = (timegm(now.utctimetuple()) - timegm(timestamp.utctimetuple())) % total_duration
					for broadcast in broadcasts:
						if(broadcast.youtube_id):
							id = broadcast.youtube_id
							title = broadcast.youtube_title
							duration = broadcast.youtube_duration
							thumbnail = "https://i.ytimg.com/vi/" + broadcast.youtube_id + "/default.jpg"
						else:
							id = broadcast.soundcloud_id
							title = broadcast.soundcloud_title
							duration = broadcast.soundcloud_duration
							thumbnail = broadcast.soundcloud_thumbnail
													
						# Current broadcast math pattern below
						if elapsed + duration > offset:
							live = {
								'id': id,
								'title': title,
								'duration': duration,
								'thumbnail': thumbnail,
							}
							
							couple[k]["live"] = live							
							break

						# We must keep browsing the list before finding the current track
						else:
							elapsed += duration
			logging.info("Live broadcast determined for each station")
			
			for s in stations:
				name = s.key().name()
				if(couple[name]["live"]):
					latest_active_stations.append(couple[name]["station"])
					live_broadcasts.append(couple[name]["live"])
			
			# Display all the user stations
			template_values = {
				"number_of_sessions": user_profile.number_of_sessions,
				"live": user_live_broadcast,
				"feed": zip(latest_active_stations, live_broadcasts),
			}
			self.render("home.html", template_values)
			
		else:
			self.render("welcome.html", None)
コード例 #10
0
ファイル: buffer.py プロジェクト: detcherry/phonoblaster
	def post(self):
		# getting station shortname, youtube_tracks to add and initializing station proxy
		shortname = self.request.get('shortname')
		content = json.loads(self.request.get("content"))				
		position = self.request.get('position')

		station_proxy = StationApi(shortname)
		data = None
		response = None

		if(station_proxy.station):
			key_name = station_proxy.station.key().name()
			
			if(self.user_proxy.is_admin_of(str(key_name))):
				logging.info("User is admin of the station. Authorized to make changes to the buffer.")
				
				if position is '':
					# Adding tracks to buffer
					extended_broadcast = station_proxy.add_track_to_buffer(content)

					if not extended_broadcast:
						response = {
							'response': False,
							'error': 1, 
							'message': 'Buffer full or broadcast not found.'
						}
					else:
						response = {
							'response': True,
							'message': 'Broadcast successfully added to buffer.'
						}

						now = datetime.utcnow()
						data = {
							"entity": "buffer",
							"event": "new",
							"content": {
								"item": extended_broadcast,
								"created": timegm(now.utctimetuple())*1000 + math.floor(now.microsecond/1000),
							}
						}

				else:
					# Changing broadcast position in buffer
					extended_broadcast = station_proxy.move_track_in_buffer(content, int(position))

					if extended_broadcast:
						response = {
							'response': True, 
							'message': 'Broadcast with key_name: '+ content + ' is now at: ' + position
						}

						now = datetime.utcnow()
						data = {
							"entity": "buffer",
							"event": "new",
							"content": {
								'id': content,
								'position': int(position),
								"created": timegm(now.utctimetuple())*1000 + math.floor(now.microsecond/1000),
							},
						}
					else:
						response = {
							'response':False,
							'error': 0, 
							'message': 'Error while changing position (at '+ position +') of incomming track with key_name = '+ content
						}

				# Add a taskqueue to warn everyone
				if data:
					task = Task(
						url = "/taskqueue/multicast",
						params = {
							"station": config.VERSION + "-" + shortname,
							"data": json.dumps(data)
							}
					)
					task.add(queue_name="buffer-queue")
				
			else:
				logging.info("User is not admin. Not authorized to make a change to the buffer")
				self.error(403)
				
		else:
			logging.info("Station not found. Not possible to make a change to the buffer")
			self.error(404)

		self.response.out.write(json.dumps(response))
コード例 #11
0
ファイル: buffer.py プロジェクト: detcherry/phonoblaster
	def delete(self, key_name):
		# Getting shortname from key_name, which is the ID of the track to delete from buffer. Then initializing station proxy
		m = re.match(r"(\w+).(\w+).(\w+).(\w+)", key_name)
		shortname = m.group(1)
		station_proxy = StationApi(shortname)
		response = {}

		if(station_proxy.station):
			
			station_key_name = station_proxy.station.key().name()
			
			if(self.user_proxy.is_admin_of(str(station_key_name))):
				logging.info("User is admin of the station. Authorized to delete in buffer.")
			
				broadcasts = station_proxy.buffer['broadcasts'][::]
		
				if len(broadcasts) < 2:
					response = {
						'response': False,
						'error':0,
						'message': 'A buffer cannot be empty.'
					}
				else :
					# Deleting track
					result = station_proxy.remove_track_from_buffer(key_name)
				
					if result:
						# Track deletion successful
						response = {
							'response': True
						}
						
						# Add a taskqueue to warn everyone
						now = datetime.utcnow()
						data = {
							"entity": "buffer",
							"event": "remove",
							"content": {
								"id": key_name,
								"created": timegm(now.utctimetuple())*1000 + math.floor(now.microsecond/1000),
							}
						}

						task = Task(
							url = "/taskqueue/multicast",
							params = {
								"station": config.VERSION + "-" + shortname,
								"data": json.dumps(data),
							},
						)
						task.add(queue_name="buffer-queue")
					else:
						# Track deletion failed
						response = {
							'response': False,
						}
			else:
				logging.info("User is not admin. Not authorized to delete in buffer")
				self.error(403)
		else:
			logging.info("Station not found. Not possible to delete in buffer")
			self.error(404)
			
		self.response.out.write(json.dumps(response))
コード例 #12
0
ファイル: track.py プロジェクト: detcherry/phonoblaster
	def delete(self):
		cursor = self.request.get("cursor")
		track_id = self.request.get("track_id")
		typeModel = self.request.get("type")

		if(track_id):
			track = Track.get_by_id(int(track_id))
			logging.info("Getting from datastore track with track_id = " + track_id)

			if(track):
				logging.info("Track found")

				if(typeModel == "broadcast"):
					# Deleting broadcasts associated to track
					query = Broadcast.all()
					query.filter("track", track)

					if(cursor):
						logging.info("Cursor found")
						query.with_cursor(start_cursor = cursor)

					broadcasts = query.fetch(100)
					logging.info("Fetched : %d Broadcast(s) from datastore."%(len(broadcasts)))
					
					if(len(broadcasts)>0):
						db.delete(broadcasts)
						logging.info("Deleted : %d Broadcast(s) from datastore."%(len(broadcasts)))

						task = Task(
							method = 'DELETE',
							url = "/taskqueue/deletetrack",
							params = {
								"cursor": cursor,
								"track_id": track_id,
								"type": typeModel,
							}
						)
						task.add(queue_name="worker-queue")
					else:
						task = Task(
							method = 'DELETE',
							url = "/taskqueue/deletetrack",
							params = {
								"track_id": track_id,
								"type": "like",
							}
						)
						task.add(queue_name="worker-queue")

				elif (typeModel == "like"):
					# Deleting likes associated to track
					query = Like.all()
					query.filter("track", track)
					
					if(cursor):
						logging.info("Cursor found")
						query.with_cursor(start_cursor = cursor)

					like = query.get()

					if like is None:
						logging.info("No like for this track, deleting track.")
						track.delete()
					else:
						try:
							listener_proxy = StationApi(like.listener.shortname)
							listener_proxy.decrement_likes_counter()
							logging.info("Listener Like counter decremented")
						except:
							logging.info("User has not created a station (likes used to be linked to user to stations)")
						
						Track.decrement_likes_counter(track.key().id())
						logging.info("Track likes counter decremented")

						like.delete()
						logging.info("Like deleted from datastore")

						cursor = query.cursor()

						task = Task(
							method = 'DELETE',
							url = "/taskqueue/deletetrack",
							params = {
								"cursor": cursor,
								"track_id": track_id,
								"type": typeModel,
							}
						)
						task.add(queue_name="worker-queue")
						
				response = True
		else:
			response = False
		self.response.out.write(json.dumps({ "response": response }))