def post(self, stream_id): yield motor.Op(self.db.streams.update, {"_id":ObjectId(stream_id)}, {"$set":{"status": "ready"}}, multi=False) stream_obj = yield motor.Op(self.db.streams.find_one, {"_id":ObjectId(stream_id)}, {"pipeline_server": 1, "quality": 1, "_id": 0}) pr = PipelineRouter(self.db, stream_id) server = yield tornado.gen.Task(pr.get_server) if "error" in server or server is None: server = yield motor.Op(self.db.servers.find_one, { "type": "pipeline", "level": {"$lte": 9}, "down": False}, {"local_ip":1, "port":1}, sort=[('level', -1)]) url = pr.get_restart_url(server) post_args = { "stream": stream_id, "quality": min(stream_obj["quality"]) } response = yield tornado.gen.Task(pr.request, url=url, post_args=post_args) self.write(response) self.finish()
def on_metadata(self): if "stream_id" in self.metadata: pr = PipelineRouter(self.db, self.metadata["stream_id"]) server = yield tornado.gen.Task(pr.get_server) url = pr.get_updates_url(server) # websocket.enableTrace(True) cache_hash = url + "?stream_id=" + self.metadata["stream_id"] if cache_hash in self.settings["ws_cache"]: self.client_receiver = self.settings["ws_cache"][cache_hash] else: # print "vyt" client = websocket.create_connection(url) # client = yield tornado.gen.Task(websocket.create_connection, url) # print "at" client.send(json.dumps(self.metadata)) # print client self.client_receiver = ClientWSReceiver(cache_hash, client) self.client_receiver.start() self.settings["ws_cache"][cache_hash] = self.client_receiver self.client_receiver.add_handler(self) print(self.metadata) if "action" in self.metadata: print('send ', self.metadata) self.client_receiver.client.send(self.metadata)
def on_metadata(self): if "stream_id" in self.metadata: pr = PipelineRouter(self.db, self.metadata["stream_id"]) server = yield tornado.gen.Task(pr.get_server) url = pr.get_updates_url(server) # websocket.enableTrace(True) self.client = websocket.create_connection(url) self.client.send(json.dumps(self.metadata)) self.client_receiver = ClientWSReceiver(self) self.client_receiver.start()
def post(self, stream_id): pr = PipelineRouter(self.db, stream_id) url = pr.get_terminal_url({ "local_ip": self.get_argument("local-ip"), "port": int(self.get_argument("port")) }) post_args = { "command": "use " + stream_id + ";" + self.get_argument("command") } response = yield tornado.gen.Task(pr.request, url=url, post_args=post_args) self.write(response) self.finish()
def on_metadata(self): if "stream_id" in self.metadata: stream = yield motor.Op( self.db.streams.find_one, {"_id": ObjectId(self.metadata["stream_id"])}, { "reencoding": 1, "_id": 0 }) if stream['reencoding']: pr = PipelineRouter(self.db, self.metadata["stream_id"]) server = yield tornado.gen.Task(pr.get_server) url = pr.get_live_url(server) # websocket.enableTrace(True) self.client = websocket.create_connection(url) self.client.send(json.dumps(self.metadata)) else: self.close()
def post(self): stream_id = self.get_argument("stream-id") group_id = self.get_argument("group-id") ids = self.request.arguments['group[]'][1:-1] artists = self.request.arguments['artist[]'] title = self.request.arguments['title[]'] remove = self.request.arguments['remove[]'] dec_count = 0 dec = 0 for i in range(len(ids)): try: id = ObjectId(ids[i]) except: id = None if id is not None: if remove[i] == "1": yield motor.Op(self.db.media.update, { "_id": id, "groups.id": group_id }, {"$pull": { "groups": { "id": group_id } }}, upsert=False, multi=False) group = yield motor.Op(self.db.media.find_one, {"_id": id}, { "groups": 1, "file_id": 1, "size": 1, "_id": 0 }) dec_count += 1 dec += group["size"] if len(group["groups"]) == 0: yield motor.Op(self.db.files.remove, {"_id": ObjectId(group["file_id"])}) yield motor.Op(self.db.media.remove, {"_id": id}) else: set = { "artist": artists[i], "title": title[i], "groups.$.weight": i } yield motor.Op(self.db.media.update, { "_id": id, "groups.id": group_id }, {"$set": set}, upsert=False, multi=False) if dec > 0: self.db.users.update({"_id": ObjectId(self.get_current_user())}, {"$dec": { "size": dec }}, upsert=False, multi=False) # self.db.streams.update({"_id":ObjectId(stream_id)}, # {"$dec":{"size": group["size"]}}, upsert=False, multi=False) self.db.streams.update({"_id": ObjectId(stream_id)}, {"$dec": { "count": dec_count, "size": dec }}, upsert=False, multi=False) stream_obj = yield motor.Op(self.db.streams.find_one, {"_id": ObjectId(stream_id)}, { "status": 1, "pipeline_server": 1, "_id": 0 }) if stream_obj["pipeline_server"] is not None: pipeline = yield motor.Op( self.db.servers.find_one, {"_id": ObjectId(stream_obj["pipeline_server"])}, { "local_ip": 1, "port": 1, "_id": 0 }) post_args = {"stream": stream_id, "group": group_id} pr = PipelineRouter(self.db, None) url = pr.get_playlist_update_url(pipeline) yield tornado.gen.Task(pr.request, url=url, post_args=post_args) self.write({"msg": "Successfully saved"}) self.finish()
def save(self, tags, file, original_filename, size, processed_filepath, user_id, stream_id, original_file_size, title, artist, group_id, quality, original_file): # Save file to database fs = gridfs.GridFS(self.db) file_id = fs.put(file) # Format tags in order to database can consume tags_db = {} for k, v in tags.items(): if type(v) == gst.Buffer: tags_db[unicode(k)] = {} try: tags_db[unicode(k)]["data"] = make_thumb(v) except: pass elif isinstance(v, basestring) or isinstance(v, int) or isinstance( v, float) or isinstance(v, long): tags_db[unicode(k)] = v if "artist" in tags_db: artist = self.__get_most_valid([artist, tags_db["artist"]]) else: artist = self.__get_most_valid([artist]) if "title" in tags_db: title = self.__get_most_valid([title, tags_db["title"]]) else: title = self.__get_most_valid([title]) if "album" in tags_db: album = self.__get_most_valid([tags_db["album"]]) else: album = "Unknown" # Insert structure to database, which contains the metatags # constructed from tags and available informations about file if "weight" in original_file: weight = original_file["weight"] else: weight = self.__get_id() file = { "user_id": user_id, "original_filename": original_filename, "file_id": unicode(file_id), "size": size, "tags": tags_db, "title": title, "artist": artist, "album": album, "stream_id": stream_id, "played": 0, "random": random.uniform(0, 1), "quality": quality, "created_at": datetime.datetime.utcnow(), "groups": [{ "id": group_id, "weight": weight }] } # groups = [ # {"id": ObjectId(), "weight": X} # ] self.db.media.insert(file) # Update limits to user self.db.users.update({"_id": ObjectId(user_id)}, {"$inc": { "size": size - original_file_size }}, upsert=False, multi=False) self.db.streams.update( {"_id": ObjectId(stream_id)}, {"$inc": { "count": 1, "size": size - original_file_size }}, upsert=False, multi=False) stream_obj = self.db.streams.find_one({"_id": ObjectId(stream_id)}, { "status": 1, "pipeline_server": 1, "_id": 0 }, upsert=False, multi=False) # print unicode(stream_obj) if stream_obj["status"] is None: self.db.streams.update({"_id": ObjectId(stream_id)}, {"$set": { "status": "ready" }}, upsert=False, multi=False) if stream_obj["pipeline_server"] is not None: # SEND TO PIPE UPDATE PLAYLIST pipeline = self.db.servers.find_one( {"_id": ObjectId(stream_obj["pipeline_server"])}, { "local_ip": 1, "port": 1, "_id": 0 }, upsert=False, multi=False) post_args = {"stream": stream_id, "group": group_id} pr = PipelineRouter(self.db, None) url = pr.get_playlist_update_url(pipeline) pr.request_sync(url, post_args) # Remove processed temp file, because we no longer need it try: os.remove(processed_filepath) except OSError: pass
def get(self): stream = yield motor.Op( self.db.streams.find_one, {"_id": ObjectId(self.get_argument("streamId"))}, { "name": 1, "description": 1, "genres": 1, "status": 1, "public": 1, "cover_image": 1, "picture": 1, "user_id": 1, "pipeline_server": 1, "quality": 1, "reencoding": 1, "users": 1, "_id": 0 }) if stream is None: raise tornado.web.HTTPError(500) if stream["user_id"] == self.get_current_user(): stream["password"] = stream["users"][0]["password"] del stream["users"] user = yield motor.Op(self.db.users.find_one, {"_id": ObjectId(stream["user_id"])}, { "name": 1, "email": 1, "picture": 1, "site": 1, "country": 1, "_id": 1 }) del stream["user_id"] user["id"] = unicode(user["_id"]) del user["_id"] final_response = {} final_response["user"] = user final_response["stream"] = stream if stream["status"] == "ready": pipeline = yield motor.Op(self.db.servers.find_one, { "type": "pipeline", "level": { "$lte": 9 }, "down": False }, { "local_ip": 1, "port": 1 }, sort=[('level', -1)]) if pipeline is None: final_response["error"] = "Not enough Pipeline servers" self.write(final_response) self.finish() else: post_args = {"stream": self.get_argument("streamId")} if stream["reencoding"]: post_args["quality"] = self.get_argument("quality", None) if "quality" not in post_args: post_args["quality"] = min(stream['quality']) if post_args["quality"] is None: post_args["quality"] = min(stream['quality']) pr = PipelineRouter(self.db, unicode(self.get_argument("streamId"))) url = pr.get_start_streaming_url(pipeline) response = yield tornado.gen.Task(pr.request, url=url, post_args=post_args) # try again if "error" in response: if not (response["error"] == 'No such stream' and not stream['reencoding']): # mark server as down response = yield motor.Op(self.db.servers.update, {"_id": pipeline["_id"]}, {"$set": { "down": True }}, upsert=False, multi=False) # try again with different server pipeline = yield motor.Op(self.db.servers.find_one, { "type": "pipeline", "level": { "$lte": 9 }, "down": False }, { "local_ip": 1, "port": 1 }, sort=[('level', -1)]) if pipeline is None: final_response["error"] = "Not enough Pipeline servers" self.write(final_response) self.finish() else: if "error" in response: response = yield tornado.gen.Task(pr.request, url=url, post_args=post_args) final_response = dict(final_response.items() + response.items()) self.write(final_response) self.finish() elif stream["status"] == "steady" or stream["status"] == "playing": query = { "type": "streaming", "streaming.streaming": True, "level": { "$lte": 9 }, "down": False, "streaming.stream": self.get_argument("streamId") } if stream["reencoding"]: # print "QUALUTY "+unicode(float(self.get_argument("quality"))) query["streaming.quality"] = self.get_argument("quality", None) if query["streaming.quality"] is None: query["streaming.quality"] = min(stream['quality']) streaming_server = yield motor.Op(self.db.servers.find_one, query, { "public_ip": 1, "port": 1, "streaming.mount": 1 }, sort=[('level', -1)]) if streaming_server is None: pipeline = yield motor.Op( self.db.servers.find_one, {"_id": ObjectId(stream["pipeline_server"])}, { "local_ip": 1, "port": 1, "_id": 0 }) post_args = {"stream": self.get_argument("streamId")} if stream["reencoding"]: post_args["quality"] = self.get_argument("quality", None) if "quality" not in post_args: post_args["quality"] = min(stream['quality']) if post_args["quality"] is None: post_args["quality"] = min(stream['quality']) pr = PipelineRouter(self.db, unicode(self.get_argument("streamId"))) url = pr.get_scale_url(pipeline) response = yield tornado.gen.Task(pr.request, url=url, post_args=post_args, raw_result=True) if self.is_error(response): yield motor.Op( self.db.streams.update, {"_id": ObjectId(self.get_argument("streamId"))}, {"$set": { "status": "ready" }}, multi=True) yield motor.Op( self.db.servers.update, { "streaming.stream": (self.get_argument("streamId")), "streaming.streaming": True }, {"$set": { "streaming.streaming": False }}, multi=True) #TODO yield motor.Op( self.db.servers.update, {"_id": ObjectId(stream["pipeline_server"])}, {"$set": { "down": True }}, upsert=False, multi=False) reset_state = False try: if response.error: response = { "error": "Error while connecting to backend" } else: response = json.loads(unicode(response.body)) if "error" in response and response[ "error"] == "No such stream": reset_state = True except: response = { "error": "Error while parsing response from backend" } if reset_state: yield motor.Op( self.db.streams.update, {"_id": ObjectId(self.get_argument("streamId"))}, {"$set": { "status": "ready" }}, multi=True) final_response = dict(final_response.items() + response.items()) self.write(final_response) self.finish() else: response = { "public_ip": streaming_server["public_ip"], "port": streaming_server["port"], "mount": streaming_server["streaming"]["mount"], } final_response = dict(final_response.items() + response.items()) self.write(final_response) self.finish() else: final_response["error"] = "Unknown state of stream" self.write(final_response) self.finish()