class UserRents(ApiResource): """rest resource for rents sent by a user""" db = MongoClient("maincontainer", "transactions").connect() db_cars = MongoClient("maincontainer", "cars").connect() # to be used def post( self, userId ): # insert transaction #tocheck if car is not in use and is in sharing rent = RentSchema().parse() toinsert = {"author": userId} for k in ["addressedto", "carId", "isAccepted", "hasKey", "isEnded"]: # aggiungere hasKey toinsert[k] = rent[k] toinsert["date"] = json_util.loads(json.dumps(rent["date"])) try: same_rent = self.db.find_one({ "author": userId, "carId": toinsert["carId"], "isEnded": False }) if same_rent is not None: return {"executed": False} self.db.insert_one(toinsert) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True} def get(self, userId): # get made transactions query = {"author": userId} try: results = self.db.find(query) except PyMongoError as e: print(e) return {"executed": False} return Response(json.dumps({"data": list(results)}, default=json_util.default), mimetype="application/json")
class ReceivedRents(ApiResource): """rest resource for rents received by a user""" db = MongoClient("maincontainer", "transactions").connect() def get(self, userId): # get received transactions query = {"addressedto": userId} try: results = self.db.find(query) except PyMongoError as e: print(e) return {"executed": False} return Response( json.dumps({"data": list(results)}, default=json_util.default), mimetype="application/json" )
class SpecificUserCar(ApiResource): """rest resource for specific car owned by a specific user""" db = MongoClient("maincontainer", "cars").connect() def get(self, userId, objId): try: cursor = self.db.find_one({"proprietarioID": userId, "_id": ObjectId(objId)}) except PyMongoError as e: print(e) return {"executed": False} except InvalidId as e: abort(400) return if cursor is None: abort(404) else: return Response( json.dumps({"data": cursor}, default=json_util.default), mimetype="application/json" ) def delete(self, userId, objId): try: cursor = self.db.find_one({"proprietarioID": userId, "_id": ObjectId(objId)}) except PyMongoError as e: print(e) return {"executed": False} except InvalidId: abort(400) return if cursor is None: abort(404) else: if cursor["inuso"]: return {"executed": False} else: try: self.db.delete_one({"_id": ObjectId(objId)}) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True}
class GlobalStats(ApiResource): """rest resource for stats leaderboard""" db = MongoClient("maincontainer", "gameinfo").connect() def get(self): try: cursor = self.db.find({}).sort("exp", DESCENDING) except PyMongoError as e: print(e) return abort(404) if cursor.count(): return Response( json.dumps({"data": list(cursor)}, default=json_util.default), mimetype="application/json" ) else: return {"data": []}
class UserCars(ApiResource): """rest resource for cars owned by a specific user""" db = MongoClient("maincontainer", "cars").connect() def get(self, userId): query = {"proprietarioID": userId} try: results = self.db.find(query) except PyMongoError as e: print(e) return {"executed": False} return Response(json.dumps({"data": list(results)}, default=json_util.default), mimetype="application/json") def post(self, userId): car = CarSchema().parse() toinsert = {"produttore": car["produttore"]} for k in [ "modello", "descrizione", "targa", "posizione", "inuso", "prezzo" ]: toinsert[k] = car[k] toinsert["proprietarioID"] = userId toinsert["dataIm"] = json_util.loads(json.dumps(car["dataIm"])) toinsert["sharing"] = json_util.loads(json.dumps(car["sharing"])) try: self.db.insert(toinsert) except PyMongoError as e: print(e) return {"executed": False} # return Response(json.dumps({"executed": True}, default=json_util.default), mimetype="application/json") return Response(json.dumps({ "executed": True, "result": toinsert }, default=json_util.default), mimetype="application/json")
class DateActiveCars(ApiResource): """rest resource for active cars during date ordered by distance from x,y point""" db = MongoClient("maincontainer", "cars").connect() def get(self, date, x, y): try: cdate = datetime.strptime(date, "%Y-%m-%d") float(x) float(y) except ValueError as e: print(e) return {"executed": False} query = { "inuso": False, "sharing.inizio": { "$lte": cdate }, "sharing.fine": { "$gte": cdate }, "posizione": { "$near": { "$geometry": { "type": "Point", "coordinates": [float(x), float(y)] } } } } try: results = self.db.find(query) except PyMongoError as e: print(e) return {"executed": False} return Response(json.dumps({"data": list(results)}, default=json_util.default), mimetype="application/json")
class UserActiveCars(ApiResource): """rest resource for active cars owned by a user ordered by distance from x,y point""" db = MongoClient("maincontainer", "cars").connect() def get(self, userId, x, y): try: float(x), float(y) except ValueError as e: print(e) return {"executed": False} query = { "inuso": { "$ne": "true" }, "proprietarioID": userId, "sharing": { "$exists": "true" }, "posizione": { "$near": { "$geometry": { "type": "Point", "coordinates": [float(x), float(y)] } } } } try: results = self.db.find(query) except PyMongoError as e: print(e) return {"executed": False} return Response(json.dumps({"data": list(results)}, default=json_util.default), mimetype="application/json")
class UserMissionStats(ApiResource): """rest resource for gamification stats of a user""" db = MongoClient("maincontainer", "gameinfo").connect() db_missions = MongoClient("maincontainer", "missions").connect() def get(self, userId): try: missions = self.db_missions.find({}) stats = self.db.find_one({"user": userId}) except PyMongoError as e: print(e) return {"executed": False} if stats: missions = list(missions) for mission in missions: if "missions" in stats and str( mission["_id"]) in stats["missions"]: to_merge = stats["missions"][str(mission["_id"])] mission["value"] = to_merge["value"] mission["complete"] = to_merge["complete"] else: mission["value"] = 0 mission["complete"] = False return Response(json.dumps({"data": missions}, default=json_util.default), mimetype="application/json") else: return {"executed": False} def post(self, userId): try: stats = self.db.find_one({"user": userId}) except PyMongoError as e: print(e) return {"executed": False} p = reqparse.RequestParser() p.add_argument("mission", required=True, location="json") command = p.parse_args() if "missions" not in stats: stats["missions"] = {} if command["mission"] == "tutorial": # tutorial if "5d4dd80975c90b34b4a85d80" not in stats["missions"]: stats["missions"]["5d4dd80975c90b34b4a85d80"] = { "value": 1, "complete": True } gained = 100 stats["exp"] += gained stats["tutorial"] = True else: return {"executed": False} if command["mission"] == "first_auto": # auto if "5d4d8f4c984d5d350c264be4" not in stats["missions"]: stats["missions"]["5d4d8f4c984d5d350c264be4"] = { "value": 1, "complete": True } gained = 40 stats["exp"] += gained else: return {"executed": False} try: self.db.update_one({"user": userId}, {"$set": stats}) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True, "gained": gained}
class UserStats(ApiResource): """rest resource for gamification stats of a user""" db = MongoClient("maincontainer", "gameinfo").connect() def get(self, userId): query = {"user": userId} projection = {"_id": 0} try: results = self.db.find_one(query, projection) except PyMongoError as e: print(e) return {"executed": False} if results is not None: # is present user stats? return Response(json.dumps({"data": results}, default=json_util.default), mimetype="application/json") else: # creating user stats obj = { "user": userId, "exp": 0, "nSent": 0, "nReceived": 0, "nHours": 0 } try: self.db.insert(obj) except PyMongoError as e: print(e) return {"executed": False} return Response(json.dumps({"data": obj}, default=json_util.default), mimetype="application/json") def put(self, userId): # daily reward try: data = self.db.find_one({"user": userId}) except PyMongoError as e: print(e) return {"executed": False} if not data: return {"executed": False} gain = random.randrange(5, 30) if "lastReward" in data: delta = (datetime.utcnow().timestamp() - data["lastReward"].timestamp()) / 3600 print(delta) if delta >= 24: self.db.update_one({"user": userId}, { "$inc": { "exp": gain }, "$set": { "lastReward": datetime.utcnow() } }) return {"executed": True, "gained": gain} else: return {"executed": False} else: self.db.update_one({"user": userId}, { "$inc": { "exp": gain }, "$set": { "lastReward": datetime.utcnow() } }) return {"executed": True, "gained": gain} def post(self, userId): # change image p = reqparse.RequestParser() p.add_argument("path", required=True, location="json") newimg = p.parse_args() try: self.db.update_one({"user": userId}, {"$set": { "avatar": newimg["path"] }}) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True}
class SpecificReceivedRent(ApiResource): """rest resource for rent identified by objId""" db = MongoClient("maincontainer", "transactions").connect() db_cars = MongoClient("maincontainer", "cars").connect() db_game = MongoClient("maincontainer", "gameinfo").connect() db_miss = MongoClient("maincontainer", "missions").connect() def updateMissions(self, user, var, amount): missions = self.db_miss.find({"vref": var}) info = self.db_game.find_one({"user": user}) if "missions" not in info: info["missions"] = {} for m in missions: mid = str(m["_id"]) if mid in info["missions"]: # update status if info["missions"][mid]["value"] + amount >= m["threshold"]: info["missions"][mid]["complete"] = True info["exp"] += m["prize"] else: info["missions"][mid]["value"] += amount else: # insert status info["missions"][mid] = {"value": amount, "complete": False} if amount >= m["threshold"]: info["missions"][mid]["complete"] = True info["exp"] += m["prize"] self.db_game.update_one({"user": user}, {"$set": info}) def put(self, userId, objId): # confirm transaction # RentSchema try: cursor = self.db.find_one({ "_id": ObjectId(objId), "addressedto": userId, "isAccepted": False, "isEnded": False }) except PyMongoError as e: print(e) return {"executed": False} except InvalidId as e: print(e) return abort(400) if cursor is None: abort(404) else: try: self.db.update_one({"_id": ObjectId(objId)}, {"$set": { "isAccepted": True }}) self.db.update_many( { "carId": cursor["carId"], "_id": { "$not": { "$eq": ObjectId(objId) } } }, {"$set": { "isEnded": True, "reason": "denied" }} # maybe add end date? ) self.db_cars.update_one({"_id": ObjectId(cursor["carId"])}, {"$set": { "inuso": True }}) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True} # def put(self, userId, objId): # close used transaction # to copy and move # try: # cursor = self.db.find_one( # {"_id": ObjectId(objId), "author": userId, "isAccepted": True, "isEnded": False} # ) # except PyMongoError as e: # print(e) # return {"executed": False} # except InvalidId as e: # print(e) # return abort(400) # if cursor is None: # abort(404) # else: # try: # self.db.update_one({"_id": ObjectId(objId)}, {"$set": {"isEnded": True}}) # self.db_cars.update_one({"_id": ObjectId(cursor["carId"])}, {"$set": {"inuso": False}}) ## update points # except PyMongoError as e: # print(e) # return {"executed": False} # return {"executed": True} def delete(self, userId, objId): # deny transaction or close # maybe add end date? preq = reqparse.RequestParser() preq.add_argument("command", required=True, location="json") command = preq.parse_args() if command["command"] == "deny": query = { "_id": ObjectId(objId), "addressedto": userId, "isAccepted": False, "isEnded": False } else: query = { "_id": ObjectId(objId), "addressedto": userId, "isAccepted": True, "hasKey": True, "isEnded": False } try: cursor = self.db.find_one(query) except PyMongoError as e: print(e) return {"executed": False} except InvalidId as e: print(e) return abort(400) if cursor is None: abort(404) else: try: now_time = datetime.utcnow() if command["command"] == "deny": self.db.update_one( {"_id": ObjectId(objId)}, {"$set": { "isEnded": True, "reason": "denied" }}) else: self.db.update_one( {"_id": ObjectId(objId)}, {"$set": { "isEnded": True, "endDate": now_time }}) self.db_cars.update_one({"_id": ObjectId(cursor["carId"])}, {"$set": { "inuso": False }}) # update points # what if doesn't exists? last_rent = self.db.find_one({"_id": ObjectId(objId)}) receiver = {"user": userId} sender = {"user": last_rent["author"]} hours = math.ceil( (last_rent["endDate"].timestamp() - last_rent["startDate"].timestamp()) / 3600) self.db_game.update_one(sender, { "$inc": { "nHours": hours, "nSent": 1, "exp": 20 * hours } }) self.db_game.update_one( receiver, {"$inc": { "nReceived": 1, "exp": 40 * hours }}) # update missions # sender sender = last_rent["author"] self.updateMissions(sender, "nHours", hours) self.updateMissions(sender, "nSent", 1) self.updateMissions(sender, "exp", 20 * hours) # receiver self.updateMissions(userId, "nReceived", 1) self.updateMissions(userId, "exp", 40 * hours) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True} # if __name__ == "__main__": # SpecificReceivedRent().updateMissions("test", "nHours", 100)
class SpecificUserRent(ApiResource): """rest resource for rent identified by objId""" db = MongoClient("maincontainer", "transactions").connect() db_cars = MongoClient("maincontainer", "cars").connect() def put(self, userId, objId): # confirm key received try: cursor = self.db.find_one({ "_id": ObjectId(objId), "author": userId, "isAccepted": True, "hasKey": False, "isEnded": False }) except PyMongoError as e: print(e) return {"executed": False} except InvalidId as e: print(e) return abort(400) if cursor is None: abort(404) else: now_time = datetime.utcnow() try: self.db.update_one( {"_id": ObjectId(objId)}, {"$set": { "hasKey": True, "startDate": now_time }}) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True} def delete(self, userId, objId): # delete transaction i made try: cursor = self.db.find_one({ "_id": ObjectId(objId), "author": userId, "isAccepted": False, "isEnded": False }) except PyMongoError as e: print(e) return {"executed": False} except InvalidId as e: print(e) return abort(400) if cursor is None: abort(404) else: try: self.db.update_one( {"_id": ObjectId(objId)}, {"$set": { "isEnded": True, "reason": "aborted" }}) except PyMongoError as e: print(e) return {"executed": False} return {"executed": True}