def get(self, beneficiary_id: str): try: if beneficiary_id: beneficiary = Beneficiary.objects( id=beneficiary_id).get().clean_data() return jsonify(Beneficiary) else: beneficiaries = [ v.clean_data() for v in Beneficiary.objects(is_active=True).all() ] return jsonify({"list": beneficiaries}) except Exception as error: return jsonify({"error": str(error)}), 400
def run(self): headers = [ self.FIELD_TITLE[f] if f in self.FIELD_TITLE else f for f in self.FIELDS ] rows = [headers] for user in Beneficiary.objects().order_by('+last_name', '+first_name', '-age'): row = [] for field in self.FIELDS: value = getattr(user, field) if field in self.tag2v.keys(): if ObjectId.is_valid(value): tg = Tags.objects(id=value) if tg: row.append(tg.get().clean_data()['ro']) else: row.append(value) else: row.append(value) elif isinstance(value, bool): row.append(1 if value else 0) else: row.append(value) rows.append(row) return rows
def save_receive(beneficiary_id, data): """Uploads and saves images of shopping receipts from telegram bot api :param beneficiary_id: str, Beneficiary ID for whom was done the request :param data: bytearray, raw data corresponding to the image of shopping receipt :return: if the response is success then will return a json as {"response": "success"}, otherwise - {"error": "error message"} """ try: image = Image.open(io.BytesIO(base64.b64decode(data.encode()))) save_path = f'{AJUBOT_RECEIPT_PATH}/{beneficiary_id}_{"{:%Y%m%d_%H%M%S}".format(datetime.now())}.{image.format.lower()}' image.save(save_path) Beneficiary.objects(id=beneficiary_id).update(sent_foto=True, path_receipt=save_path) return jsonify({"response": "success"}) except Exception as error: return jsonify({"error": str(error)}), 400
def put(self, beneficiary_id, delete=False): """update a single user by id""" update = {} if not delete: for key, value in request.json: if key == "password": value = PassHash.hash(value) update[f"set__{key}"] = value else: update["set__is_active"] = False try: Beneficiary.objects(id=beneficiary_id).get().update(**update) return jsonify({"response": "success"}) except Exception as error: return jsonify({"error": str(error)}), 400
def post(self): """create a new user""" new_Beneficiary = request.json # TODO: get authenticated Beneficiary and assignee to new Beneficiary # new_Beneficiary["created_by"] = authenticated_oprator try: assert len( new_Beneficiary["password"] ) >= MIN_PASSWORD_LEN, f"Password is to short, min length is {MIN_PASSWORD_LEN}" new_Beneficiary["password"] = PassHash.hash( new_Beneficiary["password"]) comment = Beneficiary(**new_Beneficiary) comment.save() return jsonify({"response": "success"}) except Exception as error: return jsonify({"error": str(error)}), 400
def makejson(v, user): u = {'distance': calc_distance(v, user), '_id': str(v['_id'])} for k in ['first_name','last_name','phone','email','activity_types', 'telegram_chat_id', 'latitude','longitude']: if k in v: u[k] =v[k] u['accepted_offer'] = False for it in v['offer_list']: if it['id'] == user['_id']: u['availability_day'] = utc_short_to_user_short(it['offer']) u['accepted_offer'] = True u['count'] = Beneficiary.objects(volunteer=str(v['_id']),created_at__lte=dt.now() - timedelta(days=1)).count() return u
def get_beneficiaries_by_filters(filters, pages=0, per_page=10000): try: item_per_age = int(per_page) offset = (int(pages) - 1) * item_per_age if len(filters) > 0: flt = {} to_bool = {'true': True, 'false': False} cases = ['first_name', 'last_name'] if 'phone_name' in filters.keys(): phone_name = filters.get('phone_name') if phone_name.isdigit(): nr = len(phone_name) phone_name = int(phone_name) % 10000000 phone_name_ = phone_name + 1 #return jsonify({"error": phone_name*10**(8-nr), 'd':phone_name_*10**(8-nr)}), 400 obj = Beneficiary.objects( phone__gt=phone_name * 10**(8 - nr), phone__lt=phone_name_ * 10**(8 - nr)).order_by('-created_at') else: obj = Beneficiary.objects( Q(first_name__istartswith=phone_name) | Q(last_name__istartswith=phone_name))\ .order_by('-created_at') else: for k, v in filters.items(): flt[k + '__iexact' if k in cases else k] = to_bool[ v.lower()] if v.lower() in to_bool else v obj = Beneficiary.objects(**flt).order_by('-created_at') beneficiaries = [ v.clean_data() for v in obj.skip(offset).limit(item_per_age) ] return jsonify({"list": beneficiaries, 'count': obj.count()}) else: obj = Beneficiary.objects().order_by('-created_at') beneficiaries = [ v.clean_data() for v in obj.skip(offset).limit(item_per_age) ] return jsonify({"list": beneficiaries, 'count': obj.count()}) except Exception as error: return jsonify({"error": str(error)}), 400
def getBeneficiary(args): try: id = args.get('id') if id: beneficiary = Beneficiary.objects(id=id).get().clean_data() return jsonify(beneficiary) else: try: is_active = bool(args.get('is_active', None, bool)) first_name = args.get('first_name', None, str) phone = args.get('phone', None, int) created_date_start = args.get('created_date_start', None, dt) created_date_end = args.get('created_date_end', None, dt) item_start = args.get('item_start', None, int) item_end = args.get('item_end', None, int) except Exception as _: return jsonify({"error": "Incorrect arg(s)."}) ben_objs = Beneficiary.objects() if (is_active): ben_objs.filter(is_active=is_active) if (first_name): ben_objs.filter(first_name=first_name) if (phone): ben_objs.filter(phone=phone) if (created_date_start and created_date_end): ben_objs.filter((Q(created_at__gte=created_date_start) & Q(created_at__lte=created_date_end))) count = ben_objs.all().count() if (item_start and item_end): ben_objs.skip(item_start).limit(item_end) beneficiaries = [v.clean_data() for v in ben_objs.all()] return jsonify({"list": beneficiaries}, {"pagination": { "count_of_records": count }}) except Exception as error: return jsonify({"error": str(error)}), 400
def get_volunteers_by_filters(filters, pages=0, per_page=10000): try: item_per_age = int(per_page) offset = (int(pages) - 1) * item_per_age if len(filters) > 0: flt = {} toBool = {'true':True, 'false': False} caseS = ['first_name', 'last_name'] for v,k in filters.items(): flt[v+'__iexact' if v in caseS else v] = toBool[k.lower()] if k.lower() in toBool else k obj = Volunteer.objects(**flt) volunteers = [v.clean_data() for v in obj.order_by('-created_at').skip(offset).limit(item_per_age)] for i,volunteer in enumerate(volunteers): volunteers[i]['cases_solved'] = Beneficiary.objects(volunteer=volunteer['_id']).count() return jsonify({"list": volunteers, 'count':obj.count()}) else: obj = Volunteer.objects().order_by('-created_at') volunteers = [v.clean_data() for v in obj.skip(offset).limit(item_per_age)] for i,volunteer in enumerate(volunteers): volunteers[i]['cases_solved'] = Beneficiary.objects(volunteer=volunteer['_id']).count() return jsonify({"list": volunteers, 'count':obj.count()}) except Exception as error: return jsonify({"error": str(error)}), 400
def registerBeneficiary(requestjson, created_by, fixer_id): """create a new user""" new_beneficiary = requestjson if len(created_by) > 30: user = Operator.verify_auth_token(created_by) created_by = user.get().clean_data()['email'] try: new_beneficiary['password'] = '******' new_beneficiary['email'] = '*****@*****.**' assert len( new_beneficiary["password"] ) >= MIN_PASSWORD_LEN, f"Password is to short, min length is {MIN_PASSWORD_LEN}" new_beneficiary["password"] = PassHash.hash( new_beneficiary["password"]) new_beneficiary['created_by'] = created_by new_beneficiary['fixer'] = str(fixer_id) comment = Beneficiary(**new_beneficiary) comment.save() if 'is_active' in new_beneficiary and new_beneficiary['is_active']: #sent the request to the volunteer via telegram telegrambot.send_request(comment) return jsonify({"response": "success", 'user': comment.clean_data()}) except Exception as error: return jsonify({"error": str(error)}), 400
def updateBeneficiary(requestjson, beneficiary_id, delete=False): """update a single user by id""" print(beneficiary_id, '---') update = {} if not delete: for key, value in requestjson.items(): if key == '_id': continue if key == "password": value = PassHash.hash(value) update[f"set__{key}"] = value else: update["set__is_active"] = False try: obj = Beneficiary.objects(id=beneficiary_id).get() data = obj.clean_data() #and not data['is_active'] if ('set__is_active' in update and update['set__is_active'] and not data['is_active']) \ or ('set__offer' in update and update['set__offer'] != data['offer']) \ or ('set__address' in update and update['set__address'] != data['address']): #change to active or different volunteer category or different address #return jsonify(telegrambot.send_request(obj)) telegrambot.send_request(obj) elif 'set__volunteer' in update and requestjson[ 'volunteer'] != '' and requestjson[ 'volunteer'] is not None and ( 'volunteer' not in data or update['set__volunteer'] != data['volunteer']): telegrambot.send_assign(beneficiary_id, requestjson['volunteer']) elif 'set__status' in update and update['set__status'].lower( ) == 'cancelled': #if the volunteer refused the request, delete the link volunteer_updates = { "push__offer_list": { "id": beneficiary_id, "offer": data['offer'], "cancelled": True } } volunteer.update_volunteer(requestjson['volunteer'], volunteer_updates) update['set__volunteer'] = '' update['set__status'] = update['set__status'].lower() obj.update(**update) return jsonify({"response": "success"}) except Exception as error: return jsonify({"error": str(error)}), 400
def updateBeneficiaryTG(requestjson): beneficiary_id = requestjson['request_id'] print(beneficiary_id, '---') update = { 'push__questions': 'pretul:' + str(requestjson['amount']) + ', simptome:' + ','.join(requestjson['symptoms']), 'push__comments': requestjson['further_comments'], 'curator': requestjson['would_return'] == 1 } try: obj = Beneficiary.objects(id=beneficiary_id).get() data = obj.clean_data() obj.update(**update) return jsonify({"response": "success"}) except Exception as error: return jsonify({"error": str(error)}), 400
def sort_closest(id, topk, category): topk = int(topk) user = Beneficiary.objects(id=id).get().clean_data() filters = {} #get active volunteer with same activity type, with availability>0 and not bussy with other requests if 'offer' in user and user['offer']!='': category = user['offer'] volunteers = sorted([makejson(v.clean_data(), user) for v in Volunteer.objects(is_active=True, #availability__gt=0, offer=category).all()\ # if not Beneficiary.objects(volunteer=str(v.clean_data()['_id']),status__ne='done') ], key=lambda x: x['distance']) else: volunteers = sorted([makejson(v.clean_data(), user) for v in Volunteer.objects(is_active=True, #availability__gt=0, activity_types__in=user['activity_types']).all()\ ], key=lambda x: x['distance']) volunteers = [i for i in volunteers if i['distance']<100000] #todo: find the best threshhold!!! if 'volunteer' in user and user['volunteer']!='': volunteers = [makejson(Volunteer.objects(id=user['volunteer']).get().clean_data(), user)] + [i for i in volunteers if i['_id'] != user['volunteer']] return jsonify({'list':volunteers[:topk]})
def get_active_operator(days=2): days_diff = dt.now() - timedelta(days=days) pipeline_used_fixers = [{ '$match': { 'status': 'done', 'created_at': { '$gte': days_diff } } }, { '$sort': { 'created_at': 1 } }, { '$group': { '_id': '$fixer', 'count': { '$sum': 1 } } }] fixers = [] for f in Beneficiary.objects().aggregate(pipeline_used_fixers): fixers.append(f) available_fixers = [ v.clean_data() for v in Operator.objects( is_active=True, role='fixer', created_at__gte=days_diff) ] available_fixers = [{'_id': af.get('_id')} for af in available_fixers] if len(fixers) is not 0 and len(fixers) == len(available_fixers): return fixers[0].get('_id') else: fixers_ids = [val['_id'] for val in fixers] fixer_id = None for af in available_fixers: fixer_id = af.get('_id') if fixer_id not in fixers_ids: break return fixer_id
def getVolunteers(filters): try: if len(filters.getlist('id')) == 1 : volunteer_id = filters.get('id') volunteer = Volunteer.objects(id=volunteer_id).get().clean_data() return jsonify(volunteer) elif len(filters.getlist("telegram_chat_id")) == 1: telegram_id = filters.get("telegram_chat_id") if len(Volunteer.objects(telegram_chat_id=telegram_id)) == 0: return jsonify({"exists": False}) else: return jsonify({"exists": True}) elif len(filters.getlist('id')) > 1: volunteers = [Volunteer.objects(id=volunteer_id).get().clean_data() for volunteer_id in filters.getlist('id')] return jsonify({"list": volunteers}) else: volunteers = [v.clean_data() for v in Volunteer.objects(is_active=True).order_by('-created_at').all()] for i,volunteer in enumerate(volunteers): volunteers[i]['cases_solved'] = Beneficiary.objects(volunteer=volunteer['_id']).count() return jsonify({"list": volunteers}) except Exception as error: return jsonify({"error": str(error)}), 400
def test_get_active_operator_none_result(self): # Setup beneficiary = Beneficiary() beneficiary.first_name = 'John' beneficiary.last_name = 'Travolta' beneficiary.phone = '12345678' beneficiary.email = '*****@*****.**' beneficiary.address = 'address' beneficiary.zone_address = 'zone' beneficiary.status = 'done' beneficiary.fixer = '123456' beneficiary.password = '******' beneficiary.secret = 'secret' beneficiary.save() # Execute result = operator.get_active_operator() # Validate assert result is None