def initialize_database(app, db): """Drop and restore database in a consistent state""" with app.app_context(): db.drop_all() db.create_all() for i in range(100): discount_type = DiscountType(words.get_random(), 'price * %f' % random.random(), Influencer(names.get_full_name())) discount_name = words.get_random(random.randint(2, 4)) discount = Discount(discount_name, words.get_random().upper(), random.randrange(1, 100) * random.random(), discount_type) db.session.add(discount) first_discount_type = DiscountType('Save with Sherry', 'price * .8', Influencer('Sherry')) second_discount_type = DiscountType('Sunday Savings', 'price * .9', None) third_discount_type = DiscountType('Monday Funday', 'price * .95', None) first_discount = Discount('Black Friday', 'BFRIDAY', 5.1, first_discount_type) second_discount = Discount('SWEET SUNDAY', 'OFF', 300.1, second_discount_type) third_discount = Discount('Monday Funday', 'PARTY', 542.1, third_discount_type) db.session.add(first_discount) db.session.add(second_discount) db.session.add(third_discount) db.session.commit()
def initialize_database(app, db): """Drop and restore database in a consistent state""" with app.app_context(): db.drop_all() db.create_all() first_discount = Discount('Black Friday', 'BFRIDAY', 5.1) second_discount = Discount('SWEET SUNDAY', 'OFF', 300.1) third_discount = Discount('Monday Funday', 'PARTY', 5242.1) db.session.add(first_discount) db.session.add(second_discount) db.session.add(third_discount) db.session.commit()
def get(self): user_id = logic.get_current_userid(self.request.cookies.get('user')) if user_id is None: self.redirect('/') return discount_key_str = self.request.GET.get('id') user, status, errcode = logic.user_get(user_id, None) if status != "OK": self.render("error.html", {'error_code': errcode, 'error_string': status, 'lang': LANG}) return discount, status, errcode = logic.discount_get(discount_key_str, user_id) if status != "OK": self.render("error.html", {'error_code': errcode, 'error_string': status, 'lang': LANG}) return try: discount = Discount.to_json(discount, None, None) is_new = False logging.info("EDIT OR NEW? " + str(self.request.GET.get('new')) + " == true? -- " + str(self.request.GET.get('new') == 'true')) if self.request.GET.get('new') == 'true': is_new = True self.render('discount_edit.html', {'is_new': is_new, 'discount': discount, 'user': user, 'lang' : LANG }); except TypeError, e: self.render("error.html", {'error_code': 500, 'error_string': str(e), 'lang': LANG}) return
def status(): if flask_request.method == 'GET': discounts = Discount.query.all() app.logger.info(f"Discounts available: {len(discounts)}") influencer_count = 0 for discount in discounts: if discount.discount_type.influencer: influencer_count += 1 app.logger.info( f"Total of {influencer_count} influencer specific discounts as of this request" ) return jsonify([b.serialize() for b in discounts]) elif flask_request.method == 'POST': # create a new discount with random name and value discounts_count = len(Discount.query.all()) new_discount_type = DiscountType('Random Savings', 'price * .9', None) new_discount = Discount('Discount ' + str(discounts_count + 1), words.get_random(random.randomint(2, 4)), random.randint(10, 500), new_discount_type) app.logger.info(f"Adding discount {new_discount}") db.session.add(new_discount) db.session.commit() discounts = Discount.query.all() return jsonify([b.serialize() for b in discounts]) else: err = jsonify({'error': 'Invalid request method'}) err.status_code = 405 return err
def generate_discount(): if request.method == 'POST': discount = Discount(**request.form.to_dict()) shopify.add_discount(discount) db.session.add(discount) db.session.commit() return render_template('index.html', code=discount.code)
def process_discount(request): post = request.POST or None if post: discount_code = post['discount'] discount = Discount(request,discount_code) if discount.is_valid(): discount.use_discount() messages.success( request, "Discount code accepted!") else: messages.error( request, "Invalid discount code.") return HttpResponseRedirect(reverse('checkout'))
def api_product_show(p_id): p = Product.get_or_none(Product.id == p_id) # if p_id does not exist if not p: return jsonify({"message": 'No such product'}) dc_args = request.args.get('dc') if dc_args: dc_row = Discount.get_or_none(Discount.discount_code == dc_args) if dc_row: dc_multiplier = (100 - dc_row.discount_percentage) / 100 return jsonify({ "name": p.name, "description": p.description, "originalPrice": p.price, "discountedPrice": p.price * dc_multiplier }) else: return jsonify({"message": 'Wrong discount code'}) else: return jsonify({ "name": p.name, "description": p.description, "price": p.price })
def get(self): user_id = logic.get_current_userid(self.request.cookies.get('user')) if user_id is None: self.redirect('/') return discount_key_str = self.request.GET.get('id') user, status, errcode = logic.user_get(user_id, None) if status != "OK": self.render("error.html", {'error_code': errcode, 'error_string': status, 'lang': LANG}) return discount, status, errcode = logic.discount_get(discount_key_str, user_id) if status != "OK": self.render("error.html", {'error_code': errcode, 'error_string': status, 'lang': LANG}) return place, status, errcode = logic.place_get(None, discount.place.urlsafe()) if status != "OK": self.render("error.html", {'error_code': errcode, 'error_string': status, 'lang': LANG}) return try: discount = Discount.to_json(discount, None, None) discount['title'] = discount['title_'+LANG_NAME] discount['description'] = discount['description_'+LANG_NAME] if place.owner is not None and place.owner == user.key: owner = True else: owner = False self.render('discount.html', {'discount': discount, 'place_name': place.name, 'owner' : owner, 'user': user, 'lang' : LANG, 'lang_name': LANG_NAME }); except TypeError, e: self.render("error.html", {'error_code': 500, 'error_string': str(e), 'lang': LANG}) return
def status(): if flask_request.method == 'GET': # the below calls create an n+1, unless #discounts = Discount.query.options(joinedload('*')).all() discounts = Discount.query.all() app.logger.info(f"Discounts available: {len(discounts)}") # adding a half sleep to test something time.sleep(2.5) influencer_count = 0 for discount in discounts: if discount.discount_type.influencer: influencer_count += 1 app.logger.info(f"Total of {influencer_count} influencer specific discounts as of this request") return jsonify([b.serialize() for b in discounts]) elif flask_request.method == 'POST': # create a new discount with random name and value discounts_count = len(Discount.query.all()) new_discount = Discount('Discount ' + str(discounts_count + 1), r.get_random_word(), random.randint(10,500)) app.logger.info(f"Adding discount {new_discount}") db.session.add(new_discount) db.session.commit() discounts = Discount.query.all() # adding a half sleep to test something time.sleep(2.5) return jsonify([b.serialize() for b in discounts]) else: err = jsonify({'error': 'Invalid request method'}) err.status_code = 405 return err
def setUp(self): """ TODO """ stadium = Stadium(name="test stadium") stadium.save() self.sector = Sector(stadium=stadium, letter="A", color="#00ff00", rows=10, sits=10, price=Decimal("10.00")) self.sector.save() self.festival = Festival(stadium=stadium, name="test festival", base_price=Decimal("10.00")) self.festival.save() start_night = datetime.now() + timedelta(days=50) self.night = Night(festival=self.festival, datetime=start_night) self.night.save() for i in range(2): band = Band(name="Test band %d" % i) band.save() self.bbn = BandByNight(band=band, night=self.night, price=Decimal("5.00")) self.bbn.save() self.pt = PublicType(name="maxor", price=Decimal("10.00")) self.pt.save() self.discount = Discount(festival=self.festival, limit_days=30, porcent=Decimal("10.00")) self.discount.save() self.ticket1 = Ticket(night=self.night, sector=self.sector, row=1, sit=1, public_type=self.pt) self.ticket1.save() self.ticket2 = Ticket(night=self.night, sector=self.sector, row=1, sit=2, public_type=self.pt) self.ticket2.save() self.sell_center = SellCenter(name="Test sell center") self.sell_center.save() self.sell_point = SellPoint(sell_center=self.sell_center) self.sell_point.save() self.sell = Sell(sell_point=self.sell_point) self.sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=self.ticket1) ticket_sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=self.ticket2) ticket_sell.save()
def coupon_create(discount_key_str, user_id): """ It creates a coupon, letting a user to take advantage of a discount. Parameters: - discount_key_str: the urlsafe key of the discount the user is interested in - user_id: the id of the user who is buying the coupon It returns a tuple: - the created coupon (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.add_coupon( Discount.make_key(None, discount_key_str), user_id) except TypeError, e: return None, str(e), 400
def discount_publish(discount_key_str, requester_id): """ It make a discount public. Parameters: - discount_key_str: a urlsafe key for identifying the discount - requester_id: the id of the user makeing the request It returns a tuple: - the discount with updated information (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: discount = Discount.publish( Discount.make_key(None, discount_key_str), requester_id) except (TypeError, InvalidKeyException), e: return None, str(e), 400
def discount_get(discount_key_str, requester_id): """ It gets the Discount identified by the input key. Parameters: - discount_key_str: the urlsafe key of the Discount to retrieve - requester_id: id of the user which is making the request. Only the place owner can access the past discounts and the ones that have not been published yet. It returns a tuple: - the requested discount (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.get_by_key( Discount.make_key(None, discount_key_str), requester_id) except TypeError, e: return None, str(e), 400
def discount_delete(discount_key_str, requester_id): """ It deletes a discount, removing it from the datastore. Only discounts that have not been published can be deleted. Only the owner of the place the discount refers to can delete a discount. Parameters: - discount_key_str: the urlsafe key of the discount to delete - requester_id: the id of the user that is making the request It returns a tuple: - the deleted discount (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.delete( Discount.make_key(None, discount_key_str), requester_id) except TypeError, e: return None, str(e), 400
def get(self): user_id = logic.get_current_userid(self.request.cookies.get('user')) if user_id is None: self.redirect('/') return rest_key = self.request.GET.get('rest_id') user, status, errcode = logic.user_get(user_id, None) if status != "OK": self.render("error.html", {'error_code': errcode, 'error_string': status, 'lang': LANG}) return discount = Discount() discount.place = Place.make_key(None, rest_key) try: discount = Discount.to_json(discount, None, None) self.render('discount_edit.html', {'is_new': 'True', 'discount': discount, 'user': user, 'lang' : LANG }); except TypeError, e: self.render("error.html", {'error_code': 500, 'error_string': str(e), 'lang': LANG}) return
def coupon_get_by_code(discount_key_str, requester_id, code): """ It retrieves a coupon. The user must have permission to see it. Parameters: - discount_key_str: the urlsafe key of the discount the coupon belongs to - requester_id: the id of the user who is making the request - code: the code identifying the coupon to be marked as deleted It returns a tuple: - the requested coupon (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.get_coupon( Discount.make_key(None, discount_key_str), requester_id, code) except (TypeError, ValueError, InvalidKeyException) as e: return None, str(e), 400 except UnauthorizedException, e: return None, str(e), 403
def coupon_use(discount_key_str, requester_id, code): """ It marks a coupon as used, so it cannot be used again. Only place owners can mark coupons as used. Parameters: - discount_key_str: the urlsafe key of the discount the coupon refers to - requester_id: the id of the user who is making the request - code: the code identifying the coupon to be marked as used It returns a tuple: - the coupon with updated information (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.use_coupon( Discount.make_key(None, discount_key_str), requester_id, code) except (TypeError, ValueError, InvalidKeyException, InvalidCouponException) as e: return None, str(e), 400 except UnauthorizedException, e: return None, str(e), 403
def discount_update(discount, discount_key_str, requester_id): """ It updates an existing Discount. Parameters: - discount: the Discount containing the new information to store. - discount_key_str: the urlsafe key of the Discount to update - requester_id: the string id of the user that is making the request It returns a tuple: - the updated discount (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.store( discount, Discount.make_key(None, discount_key_str), requester_id) except (TypeError, ValueError, InvalidKeyException) as e: return None, str(e), 400 except UnauthorizedException, e: return None, str(e), 403
def post(self): #create discount auth = self.request.headers.get("Authorization") if auth is None or len(auth) < 1: auth = self.request.cookies.get("user") user_id = logic.get_current_userid(auth) body = json.loads(self.request.body) try: discount = Discount.from_json(body) except TypeError, e: self.response.set_status(400) self.response.write(str(e)) return
def status(): if flask_request.method == 'GET': try: discounts = Discount.query.options(joinedload('*')).all() app.logger.info(f"Discounts available: {len(discounts)}") influencer_count = 0 for discount in discounts: if discount.discount_type.influencer: influencer_count += 1 app.logger.info( f"Total of {influencer_count} influencer specific discounts as of this request" ) return jsonify([b.serialize() for b in discounts]) except: app.logger.error("An error occured while getting discounts.") err = jsonify({'error': 'Internal Server Error'}) err.status_code = 500 return err elif flask_request.method == 'POST': try: # create a new discount with random name and value discounts_count = len(Discount.query.all()) new_discount_type = DiscountType('Random Savings', 'price * .9', None) new_discount = Discount('Discount ' + str(discounts_count + 1), r.get_random_word(), random.randint(10, 500), new_discount_type) app.logger.info(f"Adding discount {new_discount}") db.session.add(new_discount) db.session.commit() discounts = Discount.query.all() return jsonify([b.serialize() for b in discounts]) except: app.logger.error("An error occured while creating a new discount.") err = jsonify({'error': 'Internal Server Error'}) err.status_code = 500 return err else: err = jsonify({'error': 'Invalid request method'}) err.status_code = 405 return err
def add_all_discounts(): if os.path.exists('discount_table'): raise FileExistsError('File Already Exists') all_objs = [ Discount(REGULAR_CUSTOMER, 0, 0, 5000), Discount(REGULAR_CUSTOMER, 10, 5000, 10000), Discount(REGULAR_CUSTOMER, 20, 10000), Discount(PREMIUM_CUSTOMER, 10, 0, 4000), Discount(PREMIUM_CUSTOMER, 15, 4000, 8000), Discount(PREMIUM_CUSTOMER, 20, 8000, 12000), Discount(PREMIUM_CUSTOMER, 30, 12000) ] dbfile = open('discount_table', 'ab') for discount_obj in all_objs: pickle.dump(discount_obj, dbfile)
def discount_create(discount, requester_id): """ It stores a new Discount. Parameters: - discount: the Discount containing the new information to store. - requester_id: the string id of the user that is making the request It returns a tuple: - the created Discount (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.store(discount, None, requester_id) except (TypeError, ValueError, InvalidKeyException) as e: return None, str(e), 400 except UnauthorizedException, e: return None, str(e), 403
def create_discounts(): """ Generate a number of discount codes for a brand, insert them into a database and return a list with the codes. """ brand = request.json["brand"] number_to_create = request.json["number_to_create"] discount_codes = create_discount_codes(number_to_create) # Insert into database # Note that this could fail in the event of a (very unlikely) collission # but in this case we can just retry the operation after generating a new # list of codes or just let the client retry the call for discount_code in discount_codes: db.session.add(Discount(code=discount_code, brand=brand)) db.session.commit() return jsonify(discount_codes)
def get(self, key): auth = self.request.headers.get("Authorization") if auth is None or len(auth) < 1: auth = self.request.cookies.get("user") user_id = logic.get_current_userid(auth) if 'publish' in self.request.url: #publish discount discount, status, errcode = logic.discount_publish(key, user_id) else: #get discount discount, status, errcode = logic.discount_get(key, user_id) if status == "OK": try: discount = Discount.to_json(discount, None, None) self.response.headers['Content-Type'] = 'application/json' self.response.write(json.dumps(discount)) except TypeError, e: self.response.set_status(500) self.response.write(str(e))
def get(self): #get list of discounts, with filters auth = self.request.headers.get("Authorization") if auth is None or len(auth) < 1: auth = self.request.cookies.get("user") user_id = logic.get_current_userid(auth) get_values = self.request.GET filters = {} filters['place'] = get_values.get('place') filters['coupon_user'] = get_values.get('coupon_user') filters['published'] = get_values.get('published') filters['passed'] = get_values.get('passed') dlist, status, errcode = logic.discount_list_get(filters, user_id) if status == "OK": try: dlist = [Discount.to_json(d, None, None) for d in dlist] self.response.headers['Content-Type'] = 'application/json' self.response.write(json.dumps(dlist)) except TypeError, e: self.response.set_status(500) self.response.write(str(e))
def status(): if flask_request.method == 'GET': discounts = Discount.query.all() app.logger.info(f"Discounts available: {len(discounts)}") # adding a half sleep to test something time.sleep(2.5) return jsonify([b.serialize() for b in discounts]) elif flask_request.method == 'POST': # create a new discount with random name and value discounts_count = len(Discount.query.all()) new_discount = Discount('Discount ' + str(discounts_count + 1), r.get_random_word(), random.randint(10, 500)) app.logger.info(f"Adding discount {new_discount}") db.session.add(new_discount) db.session.commit() discounts = Discount.query.all() # adding a half sleep to test something time.sleep(2.5) return jsonify([b.serialize() for b in discounts]) else: err = jsonify({'error': 'Invalid request method'}) err.status_code = 405 return err
def discount_list_get(filters, requester_id): """ It gets a list of discounts identified from the filters. Parameters: - filters: dict containing the required characteristics for the discounts to retrieve - requester_id: id of the user which is making the request. Only the place owner can access the past discounts and the ones that have not been published yet. Available filters: - 'place': urlsafe key for the place - 'coupon_user': user key as urlsafe string, returns only discounts for which the user has a coupon - 'published': boolean, retrieves only published (True) or unpublished (False) discounts - 'passed': boolean, retrieves only ended (True) or future (False) discounts It returns a tuple: - the list of discounts satisfying the filters (or None in case of errors in the input), - the status (a string indicating whether an error occurred), - the http code indicating the type of error, if any """ try: res = Discount.get_list(filters, requester_id) except TypeError, e: return None, str(e), 400
def recommend(user_id, filters, purpose='dinner with tourists', n=5): """ It computes the recommendations for the user, according to specified filters and parameters. When possible, the recommendation list is personalized, using the cluster-based algorithm. If the personalized algorithm fails to find the required number of recommended place, an average-based non-personalized recommendation algorithm is used. If still other places are needed, the recommendation list is filled with places ordered by distance from user. Input: - user_id: is of the requester - filters: filters for places of interest for the user - purpose: the purpose the user is interested in - n: number of recommended places requested by the user Available filters: //- 'city': 'city!province!state!country' The 'city' filter contains the full description of the city, with values separated with a '!'. This string is split and used to retrieve only the places that are in the specified city. 'null' is used if part of the full city description is not available [example: 'Trento!TN!null!Italy' or if a bigger reagion is considered [example: 'null!TN!null!Italy' retrieves all places in the province of Trento] - 'lat', 'lon' and 'max_dist': lat and lon indicates the user position, while max_dist is a measure expressed in meters and represnt the radius of the circular region the user is interested in. Returns a list of n places in json format """ logging.info("recommender.recommend START - user_id=" + str(user_id) + ', filters=' + str(filters) + ', purpose=' + str(purpose) + ', n=' + str(n)) # places is already a json list start = datetime.now() user_max_dist = None if filters is not None and 'max_dist' in filters and filters['max_dist'] is not None and filters['max_dist'] > 0: user_max_dist = filters['max_dist'] #get places for a larger area filters['max_dist'] = 2 * user_max_dist places, status, errcode = logic.place_list_get(filters, user_id) logging.info("RECOMMEND places loaded ") if status != "OK" or places is None or len(places) < 1: # the system do not know any place within these filters logging.info("recommender.recommend END - no places") logging.error(str(errcode) + ": " + status) return None logging.warning("Loaded places for double distance: " + str(datetime.now() - start)) start = datetime.now() closest = [] out_distance = [] for p in places: if 'lat' in filters and 'lon' in filters and filters['lat'] is not None and filters['lon'] is not None: # add distance to user for each place p['distance'] = distance( p['address']['lat'], p['address']['lon'], filters['lat'], filters['lon']) if p['distance'] is not None and user_max_dist is not None and p['distance'] <= user_max_dist: closest.append(p) else: out_distance.append(p) if len(closest) >= n: places = closest elif len(closest) == 0: places = out_distance else: #TODO: fill missing spaces with outliers? places = closest logging.warning("removing places that are too far: " + str(datetime.now() - start)) place_ids = [] if places is not None: place_ids = [Place.make_key(None, place['key']).id() for place in places] scores = None purpose_list = ["dinner with tourists", "romantic dinner", "dinner with friends", "best price/quality ratio"] start = datetime.now() # logging.warning("RECOMMEND START get cluster-based predictions for all purposes: " + str(start)) for p in purpose_list: if p == purpose: start2 = datetime.now() scores = cluster_based(user_id, place_ids, p, n, loc_filters=filters) logging.warning("RECOMMEND END get cluster-based predictions: " + str(datetime.now()-start2)) else: q = taskqueue.Queue('recommendations') task = taskqueue.Task(params={'user_id': user_id, 'place_ids': place_ids, 'purpose': p, 'n': n, 'loc_filters': str(filters)}, url='/recommender/compute_cluster_based', method='POST', countdown=10) q.add(task) logging.warning("Getting recommendations from cluster and starting computation for other purposes: " + str(datetime.now() - start)) log_text = "RECOMMEND scores from cluster-based : " if scores is None: log_text += "None" else: log_text += str(len(scores)) logging.info(log_text) start = datetime.now() if scores is None or (len(scores) < n and len(scores) < len(places)): # cluster-based recommendation failed # non-personalized recommendation rating_filters = {} if places is not None: rating_filters['places'] = place_ids rating_filters['purpose'] = purpose ratings = load_data(rating_filters) if ratings is None: logging.info("ratings for places: None") else: logging.info("ratings for places: " + str(len(ratings))) items = {} if ratings is not None: for other in ratings: if other != user_id: for item in ratings[other]: if purpose in ratings[other][item]: if item not in items.keys(): items[item] = [] items[item].append(ratings[other][item][purpose]) avg_scores = [(sum(items[item]) / len(items[item]), item) for item in items] logging.info("avg_scores: " + str(len(avg_scores))) filters = {'purpose': purpose, 'user': user_id} if places is not None: filters['places'] = place_ids user_ratings = Rating.get_list(filters) logging.info("Loaded user ratings: " + str(len(user_ratings))) if scores is None: scores = [] for value, key in avg_scores: toadd = True for ur in user_ratings: if value < 3.0: #skip this place, too low rating toadd = False continue if key == ur.place.urlsafe() and ur.value < 3.0: #skip this place, user doesn't like it toadd = False continue for svalue, skey in scores: if key == skey: #already in list because of cluster toadd = False break if toadd: scores.append((value, key)) logging.info("Appending place with value " + str(value)) if len(scores) >= n: # we have enough recommended places break scores = sorted(scores, key=lambda x: x[0], reverse = True) if len(scores) > n: scores = scores[0:n] # if debug: # log_text = "RECOMMEND scores from average-based : " # if scores is None: # log_text += "None" # else: # log_text += str(len(scores)) # logging.info(log_text) # # if scores is None or (len(scores) < n and len(scores) < len(places)): # # cluster-based and average recommendations both failed to fill the recommendation list # # just add some other places # for p in places: # in_list = False # for score, key in scores: # if key == p['key']: # in_list = True # break # if not in_list: # scores.append((0, p['key'])) # if len(scores) >= n: # # we have enough recommended places # break # # if debug: # log_text = "RECOMMEND final scores : " # if scores is None: # log_text += "None" # else: # log_text += str(len(scores)) # logging.info(log_text) logging.warning("Filling empty space with full average predictions: " + str(datetime.now() - start)) start = datetime.now() places_scores = [] for p in places: # found = False for (score, item) in scores: if item == p['key']: places_scores.append((score, p)) # found = True # if not found: # places_scores.append((0, p)) logging.info('places_scores: ' + str(len(places_scores))) places_scores = sorted(places_scores, key=lambda x: x[0], reverse = True) logging.warning("Moving mapping from place ids to full place data: " + str(datetime.now() - start)) if len(places_scores) > n: places_scores = places_scores[0:n] # logging.info('recommender.recommend - places_scores: ' + str(places_scores)) items = [] start = datetime.now() for (score, place) in places_scores: #TODO: make discount loading asynchronous in javascript page, after visualization of places!!! disc_filters = {'place': place['key'], 'published': 'True', 'passed': 'False'} discounts, status, errcode = logic.discount_list_get(disc_filters, user_id) logging.info("discounts loaded: " + str(errcode) + " - " + status) if discounts is not None and status == "OK": try: json_discounts = [Discount.to_json(d, None, None) for d in discounts] place['discounts'] = json_discounts except (TypeError, ValueError) as e: #do nothing logging.error('Discounts not loaded: ' + str(e)) pass place['predicted'] = score items.append(place) logging.warning("Time for loading discounts: " + str(datetime.now() - start)) # logging.info("Recommended items: " + str(items)) logging.info("recommender.recommend END ")#- items: " + str(items)) return items
body = json.loads(self.request.body) try: discount = Discount.from_json(body) except TypeError, e: self.response.set_status(400) self.response.write(str(e)) return except Exception, e: self.response.set_status(400) self.response.write(str(e)) return discount, status, errcode = logic.discount_create(discount, user_id) if status == "OK": try: discount = Discount.to_json(discount, None, None) self.response.headers['Content-Type'] = 'application/json' self.response.write(json.dumps(discount)) except TypeError, e: self.response.set_status(500) self.response.write(str(e)) else: self.response.set_status(errcode) self.response.write(status) class DiscountHandler(webapp2.RequestHandler): def get(self, key): auth = self.request.headers.get("Authorization")
class TicketTestCase(TestCase): """ TODO """ def setUp(self): """ TODO """ stadium = Stadium(name="test stadium") stadium.save() self.sector = Sector(stadium=stadium, letter="A", color="#00ff00", rows=10, sits=10, price=Decimal("10.00")) self.sector.save() self.festival = Festival(stadium=stadium, name="test festival", base_price=Decimal("10.00")) self.festival.save() start_night = datetime.now() + timedelta(days=50) self.night = Night(festival=self.festival, datetime=start_night) self.night.save() for i in range(2): band = Band(name="Test band %d" % i) band.save() self.bbn = BandByNight(band=band, night=self.night, price=Decimal("5.00")) self.bbn.save() self.pt = PublicType(name="maxor", price=Decimal("10.00")) self.pt.save() self.discount = Discount(festival=self.festival, limit_days=30, porcent=Decimal("10.00")) self.discount.save() self.ticket = Ticket(night=self.night, sector=self.sector, row=1, sit=1, public_type=self.pt) self.ticket.save() def testPriceWithDiscount(self): """ TODO """ price = self.sector.price + self.night.price() + self.pt.price price -= price * (self.discount.porcent / Decimal("100.00")) self.assertEquals(price, self.ticket.price()) def testPriceWithoutDiscount(self): """ TODO """ self.night.datetime = datetime.now() + timedelta(days=1) self.night.save() price = self.sector.price + self.night.price() + self.pt.price self.assertEquals(price, self.ticket.price()) def testInvalidPosition(self): """ TODO """ with self.assertRaises(ValidationError): ticket = Ticket(night=self.night, sector=self.sector, row=100, sit=1, public_type=self.pt) ticket.clean() with self.assertRaises(ValidationError): ticket = Ticket(night=self.night, sector=self.sector, row=1, sit=100, public_type=self.pt) ticket.clean() def testUniqueTicket(self): """ TODO """ with self.assertRaises(IntegrityError): self.ticket = Ticket(night=self.night, sector=self.sector, row=1, sit=1, public_type=self.pt) self.ticket.save()
class CancellationTestCase(TestCase): """ TODO """ def setUp(self): """ TODO """ stadium = Stadium(name="test stadium") stadium.save() self.sector = Sector(stadium=stadium, letter="A", color="#00ff00", rows=10, sits=10, price=Decimal("10.00")) self.sector.save() self.festival = Festival(stadium=stadium, name="test festival", base_price=Decimal("10.00")) self.festival.save() start_night = datetime.now() + timedelta(days=50) self.night = Night(festival=self.festival, datetime=start_night) self.night.save() for i in range(2): band = Band(name="Test band %d" % i) band.save() self.bbn = BandByNight(band=band, night=self.night, price=Decimal("5.00")) self.bbn.save() self.pt = PublicType(name="maxor", price=Decimal("10.00")) self.pt.save() self.discount = Discount(festival=self.festival, limit_days=30, porcent=Decimal("10.00")) self.discount.save() self.ticket1 = Ticket(night=self.night, sector=self.sector, row=1, sit=1, public_type=self.pt) self.ticket1.save() self.ticket2 = Ticket(night=self.night, sector=self.sector, row=1, sit=2, public_type=self.pt) self.ticket2.save() self.sell_center = SellCenter(name="Test sell center") self.sell_center.save() self.sell_point = SellPoint(sell_center=self.sell_center) self.sell_point.save() self.sell = Sell(sell_point=self.sell_point) self.sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=self.ticket1) ticket_sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=self.ticket2) ticket_sell.save() def testMarkWasNotSelled(self): """ TODO """ self.assertEquals(True, self.ticket1.was_selled) cancellation = Cancellation(ticket=self.ticket1) cancellation.save() self.assertEquals(False, self.ticket1.was_selled) def testReSellCancelledTicket(self): """ TODO """ ticket = Ticket(night=self.night, sector=self.sector, row=1, sit=5, public_type=self.pt) ticket.save() sell = Sell(sell_point=self.sell_point) sell.save() ticket_sell = TicketSell(sell=sell, ticket=ticket) ticket_sell.save() self.assertEquals(True, ticket.was_selled) cancellation = Cancellation(ticket=ticket) cancellation.save() self.assertEquals(False, ticket.was_selled) sell = Sell(sell_point=self.sell_point) sell.save() ticket_sell = TicketSell(sell=sell, ticket=ticket) ticket_sell.save() self.assertEquals(True, ticket.was_selled) def testReturnValue(self): """ TODO """ cancellation = Cancellation(ticket=self.ticket1) cancellation.save() return_value = self.ticket1.price() - self.ticket1.price() * \ (Cancellation.RETURN_PORCENT / Decimal("100.00")) self.assertEquals(return_value, cancellation.return_value()) def testReSellSelledTicket(self): """ TODO """ ticket = Ticket(night=self.night, sector=self.sector, row=1, sit=5, public_type=self.pt) ticket.save() sell = Sell(sell_point=self.sell_point) sell.save() ticket_sell = TicketSell(sell=sell, ticket=ticket) ticket_sell.save() self.assertEquals(True, ticket.was_selled) sell = Sell(sell_point=self.sell_point) sell.save() with self.assertRaises(ValidationError): ticket_sell = TicketSell(sell=sell, ticket=ticket) ticket_sell.save()
class SellTestCase(TestCase): """ TODO """ def setUp(self): """ TODO """ stadium = Stadium(name="test stadium") stadium.save() self.sector = Sector(stadium=stadium, letter="A", color="#00ff00", rows=10, sits=10, price=Decimal("10.00")) self.sector.save() self.festival = Festival(stadium=stadium, name="test festival", base_price=Decimal("10.00")) self.festival.save() start_night = datetime.now() + timedelta(days=50) self.night = Night(festival=self.festival, datetime=start_night) self.night.save() for i in range(2): band = Band(name="Test band %d" % i) band.save() self.bbn = BandByNight(band=band, night=self.night, price=Decimal("5.00")) self.bbn.save() self.pt = PublicType(name="maxor", price=Decimal("10.00")) self.pt.save() self.discount = Discount(festival=self.festival, limit_days=30, porcent=Decimal("10.00")) self.discount.save() ticket1 = Ticket(night=self.night, sector=self.sector, row=1, sit=1, public_type=self.pt) ticket1.save() ticket2 = Ticket(night=self.night, sector=self.sector, row=1, sit=2, public_type=self.pt) ticket2.save() self.sell_center = SellCenter(name="Test sell center") self.sell_center.save() self.sell_point = SellPoint(sell_center=self.sell_center) self.sell_point.save() self.sell = Sell(sell_point=self.sell_point) self.sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=ticket1) ticket_sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=ticket2) ticket_sell.save() def testPrice(self): """ TODO """ price = sum([ts.ticket.price() for ts in TicketSell.objects.filter(sell=self.sell)]) self.assertEquals(price, self.sell.price()) def testChangeWasSelled(self): """ TODO """ ticket = Ticket(night=self.night, sector=self.sector, row=1, sit=3, public_type=self.pt) ticket.save() self.assertEquals(False, ticket.was_selled) self.sell = Sell(sell_point=self.sell_point) self.sell.save() ticket_sell = TicketSell(sell=self.sell, ticket=ticket) ticket_sell.save() self.assertEquals(True, ticket.was_selled)