def import_prices(): click.echo("Importing Prices...", nl=False) prices = [] fname = "data/prices.json" if os.path.isfile(fname): with open("data/prices.json") as data_file: prices = json.load(data_file) if not prices: click.echo("Fetching Prices...", nl=False) resp = requests.get(API_URL).json() click.echo("Adding Prices...", nl=False) series = resp["data"] for se in series: date = parser.parse(se["time"]) price = se["PriceUSD"] new_price = Price( date=date, price=price, ) db.session.add(new_price) else: for price in prices: new_price = Price( date=parser.parse(price["date"]), price=price["price"], ) db.session.add(new_price) db.session.commit() click.echo(DONE)
def parse_prices(db_ticker): ticker = db_ticker.symbol log.info(f'Price parsing for {ticker}') data = f'{PERIOD}|false|{ticker}' resp = requests.post( url=f'https://www.nasdaq.com/symbol/{ticker.lower()}/historical', data=data, headers={'content-type': 'application/json'}, ) soup = bs4.BeautifulSoup(resp.text, 'html.parser') trs = soup.find_all('tr')[2:] for tr in trs: tds = tr.find_all("td") price_date = tds[0].text.strip() if ':' in price_date: log.debug('Specified time. Using the current date.') price_date = date.today() else: price_date = datetime.strptime(price_date, '%m/%d/%Y').date() Price.get_or_create( date=price_date, open=to_float(tds[1].text), high=to_float(tds[2].text), low=to_float(tds[3].text), close=to_float(tds[4].text), volume=to_float(tds[5].text), ticker=db_ticker, )
def evemarketer(self, type_ids=[]): db_types = self.outdated(type_ids, 'evemarketer') if len(db_types) > 0: ids = ','.join([str(x.id) for x in db_types]) all_prices = requests.get( url='https://api.evemarketer.com/ec/marketstat/json?typeid=' + ids + '®ionlimit=10000002') all_prices_hash = {} for r in all_prices.json(): type_id = r['sell']['forQuery']['types'][0] all_prices_hash[type_id] = r ts = datetime.now().isoformat() for db_type in db_types: db_price = Price.query.filter( Price.source == 'evemarketer', Price.type_id == db_type.id).order_by( Price.id.desc()).first() if not db_price: db_price = Price(source='evemarketer', type_id=db_type.id) db_price.buy = all_prices_hash[ db_type.id]['buy']['fivePercent'] db_price.sell = all_prices_hash[ db_type.id]['sell']['fivePercent'] db_price.updated_at = ts db.session.begin_nested() try: db.session.add(db_price) db.session.commit() except IntegrityError: db.session.rollback() db.session.commit()
def supported_currencies(exchange=None): if exchange: currencies = Price.objects(exchange=exchange).distinct(field="currency") else: currencies = Price.objects().distinct(field="currency") if not currencies: currencies = [currency for currency in constants.CURRENCIES] return sorted(currencies)
def getStations(): if request.args.get('lat') == None or request.args.get( 'lng') == None or request.args.get('dst') == None: abort(400) # get query string params lat = float(request.args.get('lat')) lng = float(request.args.get('lng')) dst = float(request.args.get('dst')) places_id = list() stations = list() places_tree = ET.parse( '/home/gasway/Gasway-WebService-Python-Flask-/app/static/places.xml') places = places_tree.getroot() for place in places: data = place.find('location') #for data in place.findall('location'): x = float(data.find('x').text) y = float(data.find('y').text) formula = (6371 * acos( cos(radians(y)) * cos(radians(lat)) * cos(radians(lng) - radians(x)) + sin(radians(y)) * sin(radians(lat)))) if (formula < dst): s = Station() s.place_id = place.get('place_id') s.name = place.find('name').text s.brand = place.find('brand').text s.cre_id = place.find('cre_id').text s.category = place.find('category').text s.address = data.find('address_street').text s.lat = y s.lng = x stations.append(s) places_id.append(place.attrib) prices_tree = ET.parse( '/home/gasway/Gasway-WebService-Python-Flask-/app/static/prices.xml') prices = prices_tree.getroot() for price in prices: if price.attrib in places_id: s_i = places_id.index(price.attrib) for p in price.findall('gas_price'): po = Price() po.type = p.get('type') po.price = p.text stations[s_i].prices.append(po) response = app.response_class(response=jsonpickle.encode( stations, unpicklable=False), status=200, mimetype='application/json') return response
def update_price(exchange, currency, cryptocurrency, current_price): price = Price.objects(exchange=exchange, currency=currency, cryptocurrency=cryptocurrency).first() if price: price.current_price = current_price price.save() else: price = Price( exchange = exchange, currency = currency, cryptocurrency = cryptocurrency, current_price = current_price, ).save()
def update(): """Fetch price data and update skeptics.""" prices = Price.query.all() url = API_URL if prices: latest = prices[-1] start_date = latest.date + timedelta(days=1) url += f"&start_time={start_date}" click.echo("Fetching prices...", nl=False) resp = requests.get(url).json() series = resp["data"] click.echo(DONE) click.echo("Importing prices...", nl=False) for se in series: date = parser.parse(se["time"]) price = se["PriceUSD"] new_price = Price( date=date, price=price, ) db.session.add(new_price) db.session.commit() click.echo(DONE) update_skeptics() click.echo(color_text("Finished updating!"))
def index(): """ Index page. """ cursor = Price.find({}, sort=[('date', pymongo.ASCENDING)]) prices = [[c.date, c.open, c.close, c.lowest, c.highest] for c in cursor] current_app.logger.info('Found %s prices' % len(prices)) return render_template('public/index.html', prices=prices)
async def get_available_dates(db_manager, ticker): ticker = await db_manager.get(Ticker, symbol=ticker) dates = await db_manager.execute( Price.select(Price.date).where(Price.ticker_id == ticker).order_by( Price.date.desc())) dates = [date.date for date in dates] return dates
def esi(self, type_ids=[]): db_types = self.outdated(type_ids, 'esi') if len(db_types) > 0: all_prices = esiclient.markets.prices() all_prices_hash = {} for r in all_prices: all_prices_hash[r['type_id']] = r['adjusted_price'] ts = datetime.now().isoformat() for db_type in db_types: db_price = Price.query.filter( Price.source == 'esi', Price.type_id == db_type.id).first() if not db_price: db_price = Price(source='esi', type_id=db_type.id) db_price.buy = all_prices_hash[db_price.type_id] db_price.sell = all_prices_hash[db_price.type_id] db_price.updated_at = ts db.session.add(db_price) db.session.commit()
async def get_prices(db_manager, ticker): three_month_ago = datetime.today() - timedelta(days=90) ticker_db = await db_manager.get(Ticker, symbol=ticker) result = await db_manager.execute(Price.select().where( Price.ticker == ticker_db, Price.date >= three_month_ago).order_by(Price.date.desc())) result = [price.as_json() for price in result] log.debug(f'Prices for {ticker}: {result}.') return result
def test_transform_fiat(data, expected, mocker): mock_price = mocker.patch( "sqlalchemy.orm.query.Query.first", return_value=Price( ts=datetime(2020, 5, 14), buy_currency="EUR", sell_currency="USD", rate=0.9266123054, ), ) result = transform_fiat(data, "EUR") assert_frame_equal(result, expected)
def price(): form = TicketForm(current_user.username) if form.validate_on_submit(): prices = Price(p_role=form.u_person.data, p_person=form.p_person.data, p_date=form.t_date.data, p_price=form.p_price.data) db.session.add(prices) db.session.commit() return redirect(url_for('main.user')) elif request.method == 'GET': form.p_role.data = current_user.u_person return render_template('ticket.html', title=_('Ticket'), form=form)
def test_seed(): user_list = [User(email='*****@*****.**'), User(email='*****@*****.**')] transaction_list = [ Transaction(date=date(2019, 1, 12), buy_currency='BTC', buy_amount=1.1, sell_currency='USD', sell_amount=1000, user_id=1), Transaction(date=date(2019, 3, 12), buy_currency='USD', buy_amount=600.0, sell_currency='BTC', sell_amount=0.7, user_id=1), Transaction(date=date(2019, 5, 20), buy_currency='ETH', buy_amount=5.0, sell_currency='USD', sell_amount=1200.0, user_id=1), Transaction(date=date(2019, 5, 20), buy_currency='ETH', buy_amount=5.0, sell_currency='USD', sell_amount=1200.0, user_id=2) ] currency_list = [ Currency(cd='USD', name='United States Dollar', asset_type='fiat'), Currency(cd='GBP', name='British Pound', asset_type='fiat'), Currency(cd='BTC', name='Bitcoin', asset_type='crypto'), Currency(cd='LTC', name='Litecoin', asset_type='crypto'), Currency(cd='ETH', name='Ethereum', asset_type='crypto') ] curr_dt = datetime.today() last_month = curr_dt + timedelta(days=-30) price_list = [ Price(ts=last_month, buy_currency='BTC', sell_currency='USD', rate=10000), Price(ts=curr_dt, buy_currency='BTC', sell_currency='USD', rate=15000), Price(ts=last_month, buy_currency='ETH', sell_currency='USD', rate=100), Price(ts=curr_dt, buy_currency='ETH', sell_currency='USD', rate=200), Price(ts=last_month, buy_currency='USD', sell_currency='USD', rate=1), Price(ts=curr_dt, buy_currency='USD', sell_currency='USD', rate=1) ] drop_create_tables(3, 5) add_records(user_list, transaction_list, currency_list, price_list)
def get_current_price(exchange, currency, cryptocurrency): price = Price.objects(exchange=exchange, currency=currency, cryptocurrency=cryptocurrency).first() return price.current_price
def search(): for user in User.query.all(): time.sleep(2) print("User: "******"(" + user.email + ")") """ GET STORED PRODUCTS """ search_data = Search.query.filter_by(user_id=user.id).all() search_terms = [s.name for s in search_data ] # List of search terms for current user product_data = Product.query.filter( Product.search.in_(search_terms)).all() d = {} if product_data != []: for product in product_data: prices = Price.query.filter_by(asin=product.asin).all() if product.search not in d: d[product.search] = {product.asin: prices[-1].price} else: d[product.search][product.asin] = prices[-1].price """ GET STORED SEARCH TERMS """ search_list = [] for search in search_data: search_list.append((search.name, search.category, search.max_price, search.min_price, search.black_list)) """ SCRAPE DATA """ products = {} while products == {} or len(products[list(products.keys())[0]]) <= 1: products = scraper(d, search_list) #print("ERROR scraping data:") #print("User: "******"(" + user.email + ")") #print("Exception: " + str(e)) #print("--------------------- Restarting ---------------------") time.sleep(2) print(products) print("SCRAPED") """ UPDATE DATABASE """ dropped_prices = {} # { "search" : [( prod , preu), (prod , preu)] } for search in products: for product in products[search][:-1]: asin = product.asin print("----------------") print(asin) if asin != "": exists = Product.query.filter_by( asin=asin).first() is not None if not exists: # PRODUCT NOT IN DATABASE if product.rating != "": new_product = Product(search, product.asin, product.link, product.name, product.prev_price, product.last_price, product.rating) else: new_product = Product(search, product.asin, product.link, product.name, product.prev_price, product.last_price) print(product) db.session.add(new_product) db.session.commit() print("Added!") else: # PRODUCT ALREADY IN DATABASE update_data_product = Product.query.filter_by( asin=asin).first() update_data_product.link = product.link update_data_product.name = product.name update_data_product.rating = product.rating if product.last_price < update_data_product.last_price: print("Price drop") if search not in dropped_prices: dropped_prices[search] = [ (product, update_data_product.last_price) ] else: dropped_prices[search].append( (product, update_data_product.last_price)) update_data_product.last_price = product.last_price new_price = Price( asin, product.last_price, datetime.now(pytz.timezone("Europe/Madrid")).replace( tzinfo=None)) db.session.add(new_price) db.session.commit() if dropped_prices != {}: print( user.email + " should receive a mail with the products that just drpped their price." ) send_last_hour_mail(dropped_prices, mail=user.email)
for headline in news_headlines: print(headline['text'] + '\n' + headline['time_stamp']) headline_exist = NewsHeadline.objects.filter(text=headline['text']) if(len(headline_exist) == 0): headline_entry = NewsHeadline() headline_entry.text = headline['text'] headline_entry.time_stamp = headline['time_stamp'] headline_entry.save() d.csvNewsFileName = '.\\crawler\\news\\news_' + str(datetime.datetime.now().day) +'_' + str(datetime.datetime.now().month) +'_' + str(datetime.datetime.now().year) +'_' + str(datetime.datetime.now().hour) +'_' + str(datetime.datetime.now().minute) + '_' + str(datetime.datetime.now().second) +'.csv' d.DumpNewsCSV(news_headlines) prices = d.ParsePricesURL(priceStartDate) for price in prices: print(price['value'] + '\n' + price['time_stamp']) price_exist = Price.objects.filter(time_stamp=price['time_stamp']) if(len(price_exist) == 0): price_entry = Price() price_entry.value = price['value'] price_entry.time_stamp = price['time_stamp'] price_entry.save() d.csvPricesFileName = '.\\crawler\\prices\\prices_'+ str(datetime.datetime.now().day) +'_' + str(datetime.datetime.now().month) +'_' + str(datetime.datetime.now().year) +'_' + str(datetime.datetime.now().hour) +'_' + str(datetime.datetime.now().minute) + '_' + str(datetime.datetime.now().second) +'.csv' d.DumpPricesCSV(prices) # Crawl every hour time.sleep(3600)
def update_market(game): """Get market prices""" supremacy = Supremacy(game.game_id, game.game_host) result = supremacy.market() orders = result["asks"][1] + result["bids"][1] market = Market() market.game_id = game.id market.datetime = datetime.now() db.session.add(market) prices = {} for resource in orders: if resource[1]: lowest_order = resource[1][0] price = Price() price.value = lowest_order["limit"] price.buy = lowest_order["buy"] price.resource_id = lowest_order["resourceType"] market.prices.append(price) prices[price.resource_id] = price for order_json in resource[1]: player = game.players.filter( Player.player_id == order_json["playerID"]).first() order = Order() order.order_id = order_json["orderID"] order.amount = order_json["amount"] order.buy = order_json["buy"] order.limit = order_json["limit"] order.resource_id = order_json["resourceType"] market.orders.append(order) if player is not None: player.orders.append(order) db.session.add(order) db.session.commit() prev_market = market.previous if prev_market: prev_prices = prev_market.price_list if prev_prices: for resource, price in prices.items(): if prev_prices[resource]: price.previous_id = prev_prices[resource].id for resource, price in prices.items(): prev_price = price.previous if prev_price: prev_prev_price = prev_price.previous if prev_prev_price: if prev_prev_price.value == prev_price.value and \ prev_price.value == price.value: price.previous_id = prev_prev_price.id db.session.commit() db.session.delete(prev_price) db.session.commit()
def reset_db(): flash( "Resetting database: deleting old data and repopulating with dummy data" ) # clear all data from all tables meta = db.metadata for table in reversed(meta.sorted_tables): print('Clear table {}'.format(table)) db.session.execute(table.delete()) db.session.commit() # adding dummy data-- c1 = Category(name="Toys") c2 = Category(name="Electronics") db.session.add(c1) db.session.add(c2) db.session.commit() a1 = Product( name="Nintendo Switch with Neon Blue and Neon Red Joy‑Con", description= "Play your way with the Nintendo Switch gaming system. Whether you’re at home or on the " "go, solo or with friends, the Nintendo Switch system is designed to fit your life. Dock " "your Nintendo Switch to enjoy HD gaming on your TV. Heading out? Just undock your console and " "keep playing in handheld mode.", url= "https://www.amazon.com/dp/B07VGRJDFY/ref=cm_gf_atz_iaaa_d_p0_c0_qd0coEtwouCW5V9Zr4M2HQ8", favorite=False, category=c1, image= "https://images-na.ssl-images-amazon.com/images/I/71Qk2M1CIgL._AC_SL1500_.jpg" ) a2 = Product( name="Echo Dot Kids Edition", description= "Designed with kids in mind - They can ask Alexa to play music, hear stories, call " "approved friends and family, and explore a world of kid-friendly skills.", url= "https://www.amazon.com/dp/B07Q2MXPH6/ref=cm_gf_atz_iaaa_d_p0_c0_qd0O2FWT6ajLcfkyxyUA27t", favorite=True, category=c2, image= "https://images-na.ssl-images-amazon.com/images/I/619hTFl4%2BIL._AC_SL1000_.jpg" ) a3 = Product( name="Really RAD Robots - Turbo Bot", description= "Turbo Bot is built for speed! With a full function remote control including a turbo " "Boost switch!", url= "https://www.amazon.com/dp/B07NSTW6FT/ref=cm_gf_atz_iaaa_d_p0_c0_qd01g4cV1qjOSc2nnti4MzZ", favorite=False, category=c1, image= "https://images-na.ssl-images-amazon.com/images/I/61QEo-fe1JL._AC_SL1418_.jpg" ) a4 = Product( name="Hot Wheels Toy Story 4 Bundle Vehicles, 6 Pack", description= "The beloved cast becomes a 5-pack of unique and highly coveted Character Cars.", url= "https://www.amazon.com/gp/product/B07L8YMFH8/ref=cg_htl-lcat_3a2_w?pf_rd_m=ATVPDKIKX0DER&pf_rd_" "s=desktop-top-slot-6&pf_rd_r=YDW1WMNXF1Y3FFJY0KH5&pf_rd_t=0&pf_rd_p=b4c22792-984a-4880-8b60-" "44dfcac63ee9&pf_rd_i=gf-events--holiday-toy-list", favorite=True, category=c1, image= "https://images-na.ssl-images-amazon.com/images/I/81ytG6lfGTL._AC_SL1500_.jpg" ) a5 = Product( name="Beats Solo3 Wireless On-Ear Headphones - Matte Black", description= "With up to 40 hours of battery life, Beats Solo3 wireless is your perfect everyday " "headphone.", url= "https://www.amazon.com/dp/B01LWWY3E2/ref=cm_gf_aaam_iaaa_d_p0_c0_qd0PoZ3uEKKhZA1d0qZjrgk", favorite=False, category=c2, image= "https://images-na.ssl-images-amazon.com/images/I/71sBjbHYbKL._AC_SL1500_.jpg" ) db.session.add(a1) db.session.add(a2) db.session.add(a3) db.session.add(a4) db.session.add(a5) v1 = Price(price=299.00, datetime=datetime(2019, 10, 14), productID=1) v2 = Price(price=289.00, datetime=datetime(2019, 10, 16), productID=1) v3 = Price(price=249.00, datetime=datetime(2019, 10, 18), productID=1) v4 = Price(price=299.00, datetime=datetime(2019, 10, 20), productID=1) v5 = Price(price=309.00, datetime=datetime(2019, 10, 22), productID=1) v6 = Price(price=34.99, datetime=datetime(2019, 10, 14), productID=2) v7 = Price(price=39.99, datetime=datetime(2019, 10, 16), productID=2) v8 = Price(price=44.99, datetime=datetime(2019, 10, 18), productID=2) v9 = Price(price=34.99, datetime=datetime(2019, 10, 20), productID=2) v10 = Price(price=39.99, datetime=datetime(2019, 10, 22), productID=2) v11 = Price(price=39.99, datetime=datetime(2019, 10, 14), productID=3) v12 = Price(price=37.99, datetime=datetime(2019, 10, 16), productID=3) v13 = Price(price=41.99, datetime=datetime(2019, 10, 18), productID=3) v14 = Price(price=38.99, datetime=datetime(2019, 10, 20), productID=3) v15 = Price(price=43.99, datetime=datetime(2019, 10, 22), productID=3) v16 = Price(price=24.99, datetime=datetime(2019, 10, 14), productID=4) v17 = Price(price=26.99, datetime=datetime(2019, 10, 16), productID=4) v18 = Price(price=28.99, datetime=datetime(2019, 10, 18), productID=4) v19 = Price(price=23.99, datetime=datetime(2019, 10, 20), productID=4) v20 = Price(price=24.99, datetime=datetime(2019, 10, 22), productID=4) v21 = Price(price=249.00, datetime=datetime(2019, 10, 14), productID=5) v22 = Price(price=199.00, datetime=datetime(2019, 10, 16), productID=5) v23 = Price(price=179.00, datetime=datetime(2019, 10, 18), productID=5) v24 = Price(price=239.00, datetime=datetime(2019, 10, 20), productID=5) v25 = Price(price=219.00, datetime=datetime(2019, 10, 22), productID=5) db.session.add(v1) db.session.add(v2) db.session.add(v3) db.session.add(v4) db.session.add(v5) db.session.add(v6) db.session.add(v7) db.session.add(v8) db.session.add(v9) db.session.add(v10) db.session.add(v11) db.session.add(v12) db.session.add(v13) db.session.add(v14) db.session.add(v15) db.session.add(v16) db.session.add(v17) db.session.add(v18) db.session.add(v19) db.session.add(v20) db.session.add(v21) db.session.add(v22) db.session.add(v23) db.session.add(v24) db.session.add(v25) pu1 = ProductToUser(userID=1, productID=1) pu2 = ProductToUser(userID=1, productID=2) pu3 = ProductToUser(userID=1, productID=4) pu4 = ProductToUser(userID=2, productID=1) pu5 = ProductToUser(userID=2, productID=3) pu6 = ProductToUser(userID=2, productID=4) pu7 = ProductToUser(userID=2, productID=5) db.session.add(pu1) db.session.add(pu2) db.session.add(pu3) db.session.add(pu4) db.session.add(pu5) db.session.add(pu6) db.session.add(pu7) u1 = User(username="******", email="*****@*****.**") u2 = User(username="******", email="*****@*****.**") db.session.add(u1) db.session.add(u2) db.session.commit() u1.set_password("firewater") u2.set_password("earthair") db.session.commit() return redirect(url_for('index'))
def setUp(self): self.assertTrue(settings.FAKE_SMS_SERVER) # 创建老师 teacher_user = User.objects.create(username=self.teacher_name) teacher_user.password = make_password(self.teacher_password, self.teacher_salt) teacher_user.email = self.teacher_email teacher_user.save() profile = Profile(user=teacher_user, phone=self.teacher_phone) profile.save() teacher = Teacher(user=teacher_user) teacher.save() teacher_group = Group.objects.get(name="老师") teacher_user.groups.add(teacher_group) teacher_user.save() profile.save() teacher.save() teacher_account = Account(user=teacher_user) teacher_account.save() # 为老师创建能力 grade = Grade.objects.get(name="高三") subject = Subject.objects.get(name="英语") ability = Ability.objects.get(grade=grade, subject=subject) teacher.abilities.add(ability) # 设置面试记录 teacher.status = Teacher.INTERVIEW_OK teacher.status_confirm = True # 设置性别 profile.gender = "f" profile.save() # 设置区域 other_region = Region.objects.get(name="其他") teacher.region = other_region # 设置老师级别 teacher_level = Level.objects.all()[0] teacher.level = teacher_level # 为老师创建对应价格 price = Price(region=other_region, ability=ability, level=teacher_level, price=1, salary=2, commission_percentage=3) price.save() # 设置老师名称 teacher.name = self.teacher_name teacher.save() # 创建家长 parent_user = User.objects.create(username=self.parent_name) parent_user.password = make_password(self.parent_password, self.parent_salt) parent_user.email = self.parent_email parent_user.save() parent_profile = Profile(user=parent_user, phone=self.parent_phone) parent_profile.save() parent_group = Group.objects.get(name="家长") parent_user.groups.add(parent_group) parent_user.save() parent_profile.save() parent = Parent(user=parent_user) parent.save() # 创建订单 school = School(name="逗比中学", address="逗比路", region=Region.objects.get(name="其他"), center=True, longitude=0, latitude=0, opened=False) school.save() school.init_prices() # 为老师添加学校 teacher.schools.add(school) order = Order(parent=parent, teacher=teacher, school=school, grade=Grade.objects.get(name="一年级"), subject=Subject.objects.get(name="数学"), coupon=None, price=200, hours=50, total=100, paid_at=make_aware(datetime.datetime.now()), status=Order.PAID) order.save() # 创建订单里的课程 one_time_slot = TimeSlot( order=order, start=make_aware(datetime.datetime(2016, 1, 1, 8, 0, 0)), end=make_aware(datetime.datetime(2016, 1, 1, 10, 0, 0))) one_time_slot.save() one_time_slot = TimeSlot( order=order, start=make_aware(datetime.datetime(2015, 12, 30, 15, 0, 0)), end=make_aware(datetime.datetime(2015, 12, 30, 17, 0, 0))) one_time_slot.save() one_time_slot = TimeSlot( order=order, start=make_aware(datetime.datetime(2015, 12, 20, 11, 0, 0)), end=make_aware(datetime.datetime(2015, 12, 20, 12, 0, 0))) one_time_slot.save() # 检查订单的数目是否正确 order = Order.objects.get(teacher=teacher) self.assertEqual(3, len(order.timeslot_set.filter(deleted=False)))