def backref_listings(self): start_from = self.request.get("start_from") if not start_from: good = storage.Goods.all().order("__key__").get() start_from = good.key() else: start_from = db.Key(start_from) limit = 50 items = storage.Goods.all().filter("__key__ >=", start_from).fetch(limit) if len(items) > 1: next_url = "/magic/backref_listings?start_from=%s" % urllib.quote(str(items[-1].key())) items = items[:limit-1] current_status = items[-1].name else: next_url = None current_status = "finished" updates = [] for item in items: if item.listing: listing = db.get(item.listing.key()) listing.good = item updates.append(listing) db.put(updates) data = dict(activity_name = "blah", current_status = current_status, next_url = next_url) return appetsy.get_template("/magic.html").render(**data)
def empty_listings(self): start_from = self.request.get("start_from") if not start_from: listing = storage.EtsyListings.all().order("__key__").get() start_from = listing.key() else: start_from = db.Key(start_from) limit = 50 items = storage.EtsyListings.all().filter("__key__ >=", start_from).fetch(limit) if len(items) > 1: next_url = "/magic/empty_listings?start_from=%s" % urllib.quote(str(items[-1].key())) items = items[:limit-1] current_status = items[-1].title else: next_url = None current_status = "finished" for item in items: item.in_goods = item.good is not None item.good = None db.put(items) data = dict(activity_name = "Setting null in listings", current_status = current_status, next_url = next_url) return appetsy.get_template("/magic.html").render(**data)
def edit(self, key): item_key = db.Key(key) if not item_key: return "need key" item = db.get(item_key) template = appetsy.get_template("expenses/edit.html") return template.render(item = item)
def show(self, id): key = db.Key(id) if not key: return "need key" data = {} item = db.get(key) data["details"] = self.details(item).decode("utf-8") return appetsy.get_template("fans/info.html").render(**data)
def index(self): data = {} data["user"] = self.user data["logout_url"] = users.create_logout_url("/") data["current_shop"] = self.shop # check if all the cache is gone, do the loading in the page # to avoid timing out if not memcache.get_multi(["fan_list", "income_progress", "active_goods_icon_list"], namespace = str(self.shop.id)): # all the memories are gone!" data.update({"fans_today": "", "progress_box": "", "sold_featured": "", "recent_views_json": {}, "active_goods": "", "active_expenses": "", "balance": "", "instant_refresh": True}) return appetsy.get_template("index.html").render(**data) data["instant_refresh"] = False # preloading ajax data["fans_today"] = self.fans_today().decode("utf-8") data["progress_box"] = self.progress_box().decode("utf-8") data["sold_featured"] = self.sold_and_featured_today().decode("utf-8") data["recent_views_json"] = self.recent_views() goods_controller = goods.GoodsController() goods_controller.initialize(self.request, self.response) data["active_goods"] = goods_controller.active().decode("utf-8") expenses_controller = expenses.ExpensesController() expenses_controller.initialize(self.request, self.response) data["active_expenses"] = expenses_controller.active().decode("utf-8") data["balance"] = expenses_controller.balance().decode("utf-8") return appetsy.get_template("index.html").render(**data)
def show(self, id): listing_key = db.Key(id) if not listing_key: return "need key" d = {} d["listing"] = db.get(listing_key) d["fans"] = storage.ItemFans.all().filter("listing =", d["listing"]) \ .order("-favored_on").fetch(1000) return appetsy.get_template("goods/info.html").render(**d)
def details(self, key): if isinstance(key, db.Model): item = key else: key = db.Key(key) if not key: return "need key" item = db.get(key) if item.kind() == "Fans": item.title = item.user_name return appetsy.get_template("/fans/details.html").render(item = item)
def progress_box(self): income_progress = memcache.get("income_progress", namespace = str(self.shop.id)) plan = memcache.get("week_%s_plans" % appetsy.monday(self.shop).strftime("%U"), namespace = str(self.shop.id)) if not income_progress or not plan: # total income for the progress box data = {} totals = storage.Totals.all().filter("shop =", self.shop) \ .filter("name =", "shop_income").fetch(1000) data["total_money"] = sum([total.total for total in totals]) monday = appetsy.monday(self.shop) goods_week = storage.Goods.all().filter("shop =", self.shop) \ .filter("created >=", monday).fetch(100) goods_week = [good for good in goods_week if good.status in ("in_stock", "sold")] days = {} plan = storage.Counters.get_or_insert("%s:week_%s_plans" % (self.shop.id, appetsy.monday(self.shop).strftime("%U")), shop = self.shop, name = "weeks_plan", count = 10, timestamp = dt.datetime.combine(appetsy.monday(self.shop), dt.time())) planned = plan.count for good in goods_week: days.setdefault(good.created.weekday(), []).append(good) day_max = max(2, max([len(goods) for goods in days.values()] or [0])) weekday_count = max(4, max(days.keys() or [0])) data["planned"] = planned data["days"], data["day_max"], data["weekday_count"] = days, day_max, weekday_count data["goods_week"] = goods_week if planned > 0: weekday = appetsy.today(self.shop).weekday() data["percentage_complete"] = "%d" % (len(goods_week) / ((planned / float(max(5.0, weekday + 1))) * (weekday + 1)) * 100) else: data["percentage_complete"] = None income_progress = appetsy.get_template("index/progress_box.html").render(**data) memcache.set("income_progress", income_progress, namespace = str(self.shop.id)) return income_progress
def sold_and_featured_today(self): # TODO - should maybe add memcache but then have to check age # of the oldest item whole_day = appetsy.time(self.shop) - dt.timedelta(days=1) data = {} data["sold_today"] = storage.EtsyListings.all() \ .filter("shop =", self.shop) \ .filter("sold_on >", whole_day).fetch(100) data["frontpaged_today"] = storage.Frontpaged.all() \ .filter("shop =", self.shop) \ .filter("exposure_time >", whole_day).fetch(100) return appetsy.get_template("index/sold_and_featured_today.html").render(**data)
def index(self): goods = storage.Goods.all().order("created").fetch(500) listings = storage.EtsyListings.all().filter("shop =", self.shop).order("title").fetch(500) dates = [] for group in itertools.groupby(goods, lambda entry: entry.created.month): dates.append ({"month": group[0], "goods": [z for z in group[1]] }) dates.reverse() template = appetsy.get_template("goods/index.html") return template.render(listings = listings, dates = dates)
def active(self): active_list = memcache.get("active_expense_list", namespace = str(self.shop.id)) if not active_list: expenses = storage.Expenses.all() \ .filter("shop =", self.shop) \ .order("-purchase_date").fetch(5) active_list = appetsy.get_template("expenses/active.html").render(expenses = expenses) memcache.set("active_expense_list", active_list, namespace = str(self.shop.id)) spotlight = self.request.get("spotlight") if spotlight: active_list = active_list.decode("utf-8").replace("expenses_spotlight = null", "expenses_spotlight = \"%s\"" % spotlight).encode("utf-8") return active_list
def edit(self, key): item_key = db.Key(key) if not item_key: return "need key" item = storage.Goods.get(item_key) listings = memcache.get("available_listings", namespace = str(self.shop.id)) if not listings: listings = storage.EtsyListings.all().filter("shop =", self.shop) \ .filter("in_goods =", False) \ .order("state") \ .order("-ending").fetch(500) memcache.set("available_listings", listings, namespace = str(self.shop.id)) return appetsy.get_template("goods/edit.html").render(item = item, listings=listings)
def get(self): data = {} storage.Params.get_param("etsy_key") # trigger creation of etsy_key data["users"] = storage.Users.load(cache = False).values() data["shops"] = storage.EtsyShops.all().fetch(500) data["params"] = storage.Params.all().fetch(500) today = dt.date.today() etsy_request_count = [] for days in range(10): date = today - dt.timedelta(days = days) request_count = memcache.get("etsy_requests_%s" % date) if request_count: etsy_request_count.append(dict(date=date, count = request_count)) data["etsy_request_count"] = etsy_request_count data["memcache_stats"] = memcache.get_stats() self.write(appetsy.get_template("admin.html").render(**data))
def active(self): active_list = memcache.get("active_goods_icon_list", namespace = str(self.shop.id)) if not active_list: goods = storage.Goods.all().filter("shop =", self.shop) \ .filter("status IN", ("ordered", "in_stock"))\ .order("shop").order("-status").order("-created").fetch(500) etsy_count = len([good for good in goods if good.listing]) unlisted_count = len([good for good in goods if good.status != "ordered"]) - etsy_count active_list = appetsy.get_template("goods/active_icons.html").render(goods = goods, etsy_count = etsy_count, unlisted_count = unlisted_count) memcache.set("active_goods_icon_list", active_list, namespace = str(self.shop.id)) spotlight = self.request.get("spotlight") if spotlight: active_list = active_list.decode("utf-8").replace("goods_spotlight = null", "goods_spotlight = \"%s\"" % spotlight).encode("utf-8") return active_list
def index(self): """ fan_list = memcache.get("500fans") # TODO we are relying on index.py resetting memcache on day change here if fan_list: return fan_list """ fans = db.Query(storage.ShopFans).filter("shop =", self.shop) \ .order("-favored_on").fetch(limit=500) fan_counter = storage.Counters.get_by_key_name("%d:fans" % self.shop.id) if not fan_counter or not fans or fans[0].favored_on > fan_counter.timestamp: fan_counter = self._count_fans(fan_counter) fan_count = fan_counter.count dates = [] for group in itertools.groupby(fans, lambda entry: appetsy.to_local_time(self.shop, entry.favored_on).date()): fans = list(group[1]) fans.reverse() dates.append ({"cur_date": group[0], "fans": fans }) #filter out expired and sold listings data = { "dates": dates, "now": appetsy.time(self.shop), "fan_count": fan_count, "today": appetsy.today(self.shop), "yesterday": appetsy.today(self.shop) - dt.timedelta(days=1), } fan_list = appetsy.get_template("etsy.html").render(**data) memcache.set("500fans", fan_list) return fan_list
def balance(self): balance_month = self.request.get("month") if balance_month: this_month = dt.datetime.strptime(balance_month, "%d-%b-%Y").date() else: this_month = appetsy.today(self.shop).replace(day = 1).date() # timedelta doesn't do month, so we just add maximum possible days and roll back to first one next_month = (this_month + dt.timedelta(days=31)).replace(day=1) balance_cache = memcache.get("balance", namespace = str(self.shop.id)) or {} if this_month not in balance_cache: expenses = storage.Expenses.all().filter("shop =", self.shop) \ .filter("purchase_date >=", this_month) \ .filter("purchase_date <", next_month) \ .order("purchase_date") for expense in expenses: expense.price = -expense.price goods = storage.Goods.all().filter("status =", "sold") \ .filter("shop =", self.shop) \ .filter("sold >", this_month) \ .filter("sold <", next_month) \ .order("sold") \ .order("status") moneys = [] for expense in expenses: moneys.append({"date": expense.purchase_date, "price": -(expense.price or 0), "name": expense.name, "creation_date": None, "key": expense.key() }) for good in goods: moneys.append({"date": good.sold.date(), "price": good.price or 0, "name": good.name, "creation_date": good.created, "key": good.key(), "listing": good.listing }) moneys.sort(key = lambda x: x["date"]) dates = [] for group in itertools.groupby(moneys, lambda entry: entry["date"].month): dates.append ({"month": group[0], "moneys": [z for z in group[1]] }) dates.reverse() prev_totals = storage.Totals.all().filter("shop =", self.shop) \ .filter("name in", ["shop_income"]) \ .fetch(500) prev_totals = appetsy.totals(prev_totals, lambda x: x.date.date().replace(day=1), lambda x: x.total) balance_cache[this_month] = appetsy.get_template("expenses/index.html").render(dates = dates, prev = prev_totals) memcache.set("balance", balance_cache, namespace = str(self.shop.id)) spotlight = self.request.get("spotlight") balance = balance_cache[this_month] if spotlight: balance = balance.decode("utf-8").replace("balance_spotlight = null", "balance_spotlight = \"%s\"" % spotlight).encode("utf-8") return balance
def statistics(self): goods = storage.Goods.all().filter("shop =", self.shop) \ .order("created").order("sold").fetch(500) template = appetsy.get_template("goods_statistics.html") return template.render(goods = goods)
def fans_today(self): today = appetsy.today(self.shop) #- dt.timedelta(days=2) if today.date() != memcache.get("today", namespace = str(self.shop.id)): appetsy.invalidate_memcache("fans", namespace = str(self.shop.id)) page = self.request.get("page") or "persons" fan_list = memcache.get("fan_list", namespace = str(self.shop.id)) if not fan_list: #use cache whenever data = {} by_fan = {} shopfaves = storage.ShopFans.all().filter("shop =", self.shop) \ .filter("favored_on >=", today) \ .fetch(500) itemfaves = storage.ItemFans.all().filter("shop =", self.shop) \ .filter("favored_on >=", today) \ .fetch(500) data["shopfave_count"] = len(shopfaves) for fave in shopfaves: fan = dict(user_name = fave.fan.user_name, image_url = fave.fan.image_url, favored_on = fave.favored_on, key = str(fave.fan.key()), count = 0) by_fan[fave.fan.user_name] = fan data["itemfave_count"] = len(itemfaves) by_listing = {} for fave in itemfaves: listing = dict(title = fave.listing.title, key = str(fave.listing.key()), image_url = fave.listing.image_url, count = 0, favored_on = fave.favored_on) by_listing.setdefault(fave.listing.id, listing) by_listing[fave.listing.id]["count"] += 1 by_listing[fave.listing.id]["favored_on"] = min(by_listing[fave.listing.id]["favored_on"], fave.favored_on) fan = dict(user_name = fave.fan.user_name, image_url = fave.fan.image_url, key = str(fave.fan.key()), favored_on = fave.favored_on, count = 0) by_fan.setdefault(fave.fan.user_name, fan) by_fan[fave.fan.user_name]["favored_on"] = min (by_fan[fave.fan.user_name]["favored_on"], fave.favored_on) by_fan[fave.fan.user_name]["count"] += 1 data["shopfaves"] = sorted(by_fan.values(), key = lambda x: x["favored_on"]) data["listingfaves"] = sorted(by_listing.values(), key = lambda x: x["favored_on"]) fan_list = appetsy.get_template("index/fans_today.html").render(**data) memcache.set("fan_list", fan_list, namespace = str(self.shop.id)) memcache.set("today", today.date(), namespace = str(self.shop.id)) #lame current page hack to avoid breaking the cache if page == "persons": fan_list = fan_list.replace('<div id="person_box" style="display: none">', '<div id="person_box">') else: fan_list = fan_list.replace('<div id="item_box" style="display: none">', '<div id="item_box">') return fan_list
def faves(self, key): if isinstance(key, db.Model): item = key else: key = db.Key(key) if not key: return "need key" item = db.get(key) data = dict(today = [], other_days = []) data['shop'] = self.shop today = appetsy.today(self.shop) if item.kind() == "Fans": faves = storage.ItemFans.all() \ .filter("fan =", item) \ .order("-favored_on").fetch(500) for fave in faves: fave.image_url = fave.listing.image_url fave.str_key = fave.listing.key() fave.user_name = "" if appetsy.zero_timezone(fave.favored_on) >= today: data["today"].append(fave) else: data["other_days"].append(fave) shopfave = storage.ShopFans.all() \ .filter("fan =", item) \ .filter("shop =", self.shop).get() if shopfave: shopfave.image_url = "veikals" shopfave.str_key = "" shopfave.user_name = "" if appetsy.zero_timezone(shopfave.favored_on) >= today: data["today"].append(shopfave) data["today"] = sorted(data["today"], key=lambda x:x.favored_on, reverse = True) else: data["other_days"].append(shopfave) data["other_days"] = sorted(data["other_days"], key=lambda x:x.favored_on, reverse = True) else: itemfans = storage.ItemFans.all() \ .filter("listing =", item) \ .filter("shop =", item.shop) \ .order("-favored_on").fetch(500) for item in itemfans: fave = item.fan fave.str_key = item.fan.key() fave.user_name = item.fan.user_name if appetsy.zero_timezone(item.favored_on) >= today: data["today"].append(fave) else: data["other_days"].append(fave) return appetsy.get_template("/fans/faves.html").render(**data)
def dummy(self): start_from = request.get("start_from") data = dict(activity_name = "blah", current_status = "testing", next_url = "/magic/dummy") return appetsy.get_template("/magic.html").render(**data)