def get_set_brand(self, name): """ Step 1: Check if name is None or not. Step 2: Set name to lower(name), for ease of caching. Step 3: If name is in correction, set name to lower(correct name). Step 4: If name brands is in cache, get the cached Brand object. Step 5: Else, create a Brand object with title = original name (correct but not lower cased). Then store it into the cache it with name (correct and lower cased) as the key. Step 6: Return the Brand object. """ if not name: return None name_original = name name = name_original.lower() if name in self.brand_corrections: name_original = self.brand_corrections[name] name = name_original.lower() if name in Pipeline.brands: return Pipeline.brands[name] brand = models.Brand(title=name_original) Pipeline.brands[name] = brand Pipeline.db.add(brand) return brand
def resolve_acquisition(): game_id = request.json['game_id'] id_token = request.json['id_token'] sell_count = int(request.json['sell_count']) trade_count = int(request.json['trade_count']) user_id = firebase_admin.auth.verify_id_token(id_token)['uid'] state = persistance.get_game_state(game_id) if state.current_action_player != user_id: raise models.RuleViolation( "Stop trying to take other player's turns! You cheat!") if state.current_action_type != models.ActionType.RESOLVE_ACQUISITION: raise models.RuleViolation( 'It is your turn, but it is not time to resolve an acquisition!') if not state.is_started: raise models.RuleViolation('Cannot take turn until game has begun!') acquiree = models.Brand(state.current_action_details['acquiree']) player_acquiree_stock_count = state.stock_by_player[user_id][acquiree] if sell_count + trade_count > player_acquiree_stock_count: raise models.RuleViolation( 'Cannot trade and sell more stock than you current have!') acquirer = models.Brand(state.current_action_details['acquirer']) cost_at_acquisition_time = state.current_action_details[ 'acquiree_cost_at_acquisition_time'] stock.sell_stock(state, user_id, acquiree, cost_at_acquisition_time, sell_count) stock.trade_stock(state, user_id, acquiree, acquirer, trade_count) turns.transition_from_resolve(state, game_id) persistance.update_game_state(game_id, state.to_dict()) return 'OK'
def place_tile(): game_id = request.json['game_id'] id_token = request.json['id_token'] x = int(request.json['x']) y = int(request.json['y']) raw_brand = request.json['brand'] brand = None if raw_brand == '' else models.Brand(raw_brand) player_id = firebase_admin.auth.verify_id_token(id_token)['uid'] state = persistance.get_game_state(game_id) if state.current_action_player != player_id: raise models.RuleViolation( "Stop trying to take other player's turns! You cheat!") if state.current_action_type != models.ActionType.PLACE_TILE: raise models.RuleViolation( 'It is your turn, but it is not time to place a tile!') player_tiles = persistance.get_player_tiles(game_id, player_id) if not any(tile.x == x and tile.y == y for tile in player_tiles): raise models.RuleViolation( 'You do not have that tile! Stop trying to cheat!') if not state.is_started: raise models.RuleViolation('Cannot take turn until game has begun!') tile = models.Tile(x, y) place_tile_result = grid.place_tile(state, tile, brand) stock.apply_majority_bonuses(state, place_tile_result.acquired_chains) stock.award_founder_share(state, player_id, place_tile_result.new_brand) grid.set_brand_lists(state) stock.set_price_table(state) turns.transition_from_place(state, place_tile_result, game_id) persistance.delete_player_tile(game_id, player_id, models.Tile(x, y)) # this should all happen atomically, but as a stopgap make sure this happens last persistance.update_game_state(game_id, state.to_dict()) return 'OK'
def add_brand(): form = Add_Brand() # form submitted to the server by a user if form.validate_on_submit(): new_brand = models.Brand() # set brand name and description from form data new_brand.name = form.name.data new_brand.desc = form.desc.data if form.photo.data: photo_file = save_photo(form.photo.data) new_brand.photo = photo_file new_brand.deletable = True # flash message to let user know that the brand has been created flash('{} brand successfully created.'.format(new_brand.name)) db.session.add(new_brand) db.session.commit() return redirect(url_for('brand', id=new_brand.id)) # request to see the page return render_template('add_edit_brand.html', form=form, title="Add Brand", legend="Add")
def buy_stock(): max_purchase_amount = int(os.environ['MAX_STOCK_PURCHASE_AMOUNT']) game_id = request.json['game_id'] id_token = request.json['id_token'] purchase_order = request.json['purchase_order'] user_id = firebase_admin.auth.verify_id_token(id_token)['uid'] state = persistance.get_game_state(game_id) if state.current_action_player != user_id: raise models.RuleViolation( "Stop trying to take other player's turns! You cheat!") if state.current_action_type != models.ActionType.BUY_STOCK: raise models.RuleViolation( 'It is your turn, but it is not time to buy stock!') if not state.is_started: raise models.RuleViolation('Cannot take turn until game has begun!') total_stock_purchased = 0 for raw_brand, raw_amount in purchase_order.items(): parsed_amount = int(raw_amount) total_stock_purchased += parsed_amount brand = models.Brand(raw_brand) stock.buy_stock(state, user_id, brand, parsed_amount) if total_stock_purchased > max_purchase_amount: raise models.RuleViolation('Too many stock in purchase order!') turn_transitioned_state = turns.transition_from_buy(state, game_id) persistance.update_game_state(game_id, turn_transitioned_state.to_dict()) return 'OK'
def process_entry(entry, website_pk): """Process entry data. params: - entry: parsed dataset line - website_pk: website Mongo <ObjectId> reference The function will process the entry data based on the "page type: product_detail or product_listing". A boolean value will be returned to mark the process ended successful or failed. The process can also raise exception for unrecoverable failures. """ if not entry['extract_ok']: return False extracted_data = entry['extracted_data'] if entry['page_type'] == 'product_detail': item = extracted_data['item'] brand = item['brand_name'] if brand: try: brand = models.Brand(brand=brand).ensure() except: raise props = { "brand": brand, "crawled_at": parse_datetime(entry['crawled_at']), "discount_percentage": item['discount_percentage'], "name": item['article_name'], "on_sale": item['on_sale'], "price": item['sale_price'], "product_type": item['article_type'], "properties": item['extra_props'], "sku": item['sku'], "url": entry['page_url'], "website": website_pk, # path=None, # listings=[], } # print(props) ## Clean None values props = utils.removeNoneValuesFromDict(props) # print(props) p = models.Product(**props) try: # p.save() p.ensure() except models.DuplicateKeyError as error: logger.debug("Item already exists: %s - %s - %s [%s]" % ( props.get("sku"), props.get("name"), props.get("url"), props.get("crawled_at"), )) return False except Exception as e: writeErrorFile('detail-%s' % (website_pk), entry['body']) raise e elif entry['page_type'] == 'product_listing': status = True number_of_items = extracted_data['number_of_items'] # number_of_items = len(extracted_data['items']) props = { "page_number": entry['page_number'], "page_listing_size": number_of_items, "category": entry['product_category'], "sorted_by": entry['ordering'], "url": entry['page_url'], "crawled_at": parse_datetime(entry['crawled_at']), "website": website_pk, } props = utils.removeNoneValuesFromDict(props) pl = models.ProductListingPage(**props) try: pl.ensure() pl_pk = pl.pk except models.DuplicateKeyError as error: pl = models.ProductListingPage.objects.get( dict([(k, v) for k, v in props.items() if k in ('url', 'crawled_at')])) pl_pk = pl.pk except: raise # ------------------------------------------------------------------------- # Assign Items # ------------------------------------------------------------------------- total_items = 0 not_found_products = 0 listing_added_total = 0 insufficent_data = 0 for i, item in enumerate(extracted_data['items']): # ------------------------------------------------------------------------- # Find Item first # ------------------------------------------------------------------------- detail_page_url = item.get('detail_page_url') if not detail_page_url: continue total_items = total_items + 1 # ------------------------------------------------------------------------- # Find matching Product based on detail_page_url # ------------------------------------------------------------------------- try: product = models.Product.objects.get({'path': detail_page_url}) except models.Product.DoesNotExist: logger.debug("No Product match found for %s" % (detail_page_url)) not_found_products = not_found_products + 1 continue try: li_props = { "position": i + 1, "price": item['sale_price'], "on_sale": item['on_sale'], "discount_percentage": item['discount_percentage'], "listing_props": item['listing_props'], "listing": pl_pk, } # ------------------------------------------------------------------------- # Create Listing Item # ------------------------------------------------------------------------- li = models.ProductListingItem(**li_props) except Exception as e: writeErrorFile('listing-%s' % (pl_pk), entry['body']) logger.error(e) insufficent_data = insufficent_data + 1 continue if any([True for l in product.listings if l.listing._id == pl_pk]): # print("Listing already added to product") listing_added_total = listing_added_total + 1 continue # ------------------------------------------------------------------------- # Add New Listing ot Product listings # ------------------------------------------------------------------------- product.listings.append(li) try: product.save() listing_added_total = listing_added_total + 1 except Exception as e: logger.error(e) writeErrorFile('listing-%s-%s' % (pl_pk, i), entry['body']) # ------------------------------------------------------------------------- # Debug stats # ------------------------------------------------------------------------- logger.debug("""%s: stats (ok:%s/missing:%s/nodata:%s/total:%s)""" % ( utils.get_url_path(entry['page_url']), listing_added_total, not_found_products, insufficent_data, total_items, )) return True else: logger.error("Unknown page_type") return False return True