def notify_repetition(): logger.info('Start notify_repetition') if not can_run_task(): logger.info('End (time) notify_repetition') return now = get_datetime_now() users = User.objects.filter( status=User.Status.FREE, learned_words__start_repetition_time__lt=now, learningstatus__repetition_notified__isnull=True, ).select_related('learningstatus').distinct() logger.info('get users %d', users.count()) for user in users.iterator(): safe_send_message( user, 'Hello, my friend! Do you want to repeat new words?', markup=generate_markup(constants.Handlers.repetition.path), ) user.learningstatus.update_notification_time(get_datetime_now()) logger.info('End notify_repetition')
def set_learn_word(self, message_text: str) -> bool: word = self.user.learning_status.next_learn_word if not word: logger.info('for user %s, end words', self.user.username) return True if message_text == constants.Commands.learn: # Устанавливаем слово ws = WordStatus.objects.create( user_id=self.user.id, word=word, start_repetition_time=get_datetime_now(), ) self.user.learning_status.repeat_words.add(ws) self.user.learning_status.set_next_learn_word() return True elif message_text == constants.Commands.miss: self.user.learning_status.set_next_learn_word() return True else: send_message( self.user, 'Не понятное сообщение. Вы хотите выучить слово?', markup=generate_markup( constants.Commands.learn, constants.Commands.miss, constants.Handlers.stop.path, ), ) return False
def save(self, update_fields=None, **kwargs): if update_fields: update_fields = set(update_fields) self.date_updated = get_datetime_now() update_fields.add('date_updated') update_fields = tuple(update_fields) super().save(update_fields=update_fields, **kwargs)
def add_words_for_repetition(self): repetition_words = ( WordStatus.objects .filter(user=self.user, start_repetition_time__lt=get_datetime_now()) .exclude(id__in=[ # исключаем добавленные слова status_word.id for status_word in self.user.learning_status.repeat_words.all() ]) ) self.repeat_words.add(*repetition_words)
def can_run_task(): now = get_datetime_now() logger.info('Current time %s', now) hours_from, hours_to = 10, 22 if hours_from <= now.hour <= hours_to: return True logger.info('My time is not got! %s', now) return False
def update_repetition_time_for_repeated_words(self): if self.is_words_were_repeated: next_repeat_id = float('Inf') elif self.repetition_word_status_id: next_repeat_id = self.repetition_word_status_id else: next_repeat_id = 0 # делаем ручную фильтрацию вместо sql, т.k. до этого был выполнен prefetch_related, # который вытащил все repeat_words repeat_words = filter(lambda w: w.id < next_repeat_id, self.repeat_words.all()) now = get_datetime_now() for word_status in repeat_words: word_status.set_next_repetition_time(now)
def login(): """ This is controller of the login api Requests Body: Returns: Examples:: """ params = { 'username': FieldString(), 'password': FieldString() } try: json_data = parse_req(params) username = json_data.get('username', None).strip() password = json_data.get('password') except Exception as ex: logger.error('{} Parameters error: '.format(get_datetime_now().strftime('%Y-%b-%d %H:%M:%S')) + str(ex)) return send_error(message='Invalid username or password.\nPlease try again') user = client.db.users.find_one({'username': username}) if user is None: return send_error(message='Invalid username or password.\nPlease try again') if not check_password_hash(user["password_hash"], password): return send_error(message='Invalid username or password.\nPlease try again') access_token = create_access_token(identity=user["_id"], expires_delta=ACCESS_EXPIRES) refresh_token = create_refresh_token(identity=user["_id"], expires_delta=REFRESH_EXPIRES) # Store the tokens in our store with a status of not currently revoked. add_token_to_database(access_token, user["_id"]) add_token_to_database(refresh_token, user["_id"]) data = { 'access_token': access_token, 'refresh_token': refresh_token, 'username': user["username"], 'is_admin': user["is_admin"], 'user_id': user["_id"], 'name': user["name"], } return send_result(data=data, message="Logged in successfully!")
def create_user(): """ This is api for the user management registers user. Request Body: Returns: Examples:: """ try: json_data = request.get_json() # Check valid params validate(instance=json_data, schema=user_validator) username = json_data.get('username', None).strip() password = json_data.get('password', None) except Exception as ex: logger.error('{} Parameters error: '.format(get_datetime_now().strftime('%Y-%b-%d %H:%M:%S')) + str(ex)) return send_error(message="Parameters error: " + str(ex)) user_duplicated = client.db.users.find_one({"username": username}) if user_duplicated: return send_error(message="The username has existed!") if is_password_contain_space(password): return send_error(message='Password cannot contain spaces') keys = ["username", "name", "gender", "phone", "email", "is_admin"] user_id = str(ObjectId()) new_user = { "_id": user_id, 'password_hash': hash_password(password) } for key in keys: if key in json_data: new_user[key] = json_data.get(key) try: client.db.users.insert_one(new_user) except Exception as ex: return send_error(message="Insert to database error: " + str(ex)) return send_result(data=new_user, message="Create user successfully!")
def change_password(): """ This api for all user change their password. Request Body: Returns: Examples:: """ user_id = get_jwt_identity() current_user = client.db.users.find_one({"_id": user_id}) try: json_data = request.get_json() # Check valid params validate(instance=json_data, schema=password_validator) current_password = json_data.get('current_password', None) new_password = json_data.get('new_password', None) except Exception as ex: logger.error('{} Parameters error: '.format(get_datetime_now().strftime('%Y-%b-%d %H:%M:%S')) + str(ex)) return send_error(message='Parse error ' + str(ex)) if not check_password_hash(current_user["password_hash"], current_password): return send_error(message="Current password incorrect!") if is_password_contain_space(new_password): return send_error(message='Password cannot contain spaces') new_value = { '$set': { 'password_hash': hash_password(new_password) } } try: client.db.users.update_many({'_id': user_id}, new_value) except Exception as ex: return send_error(message='Database error: ' + str(ex)) # revoke all token of current user from database except current token revoke_all_token2(user_id) return send_result(message="Change password successfully!")
def update_repeated_words(self): next_repeat_word_status = self.get_next_repeat_word_status() # если нету следующего слова для повторения -> все слова были повторены # значит устанавливаем float(inf) - бесконечно большое число next_repeat_id = next_repeat_word_status and next_repeat_word_status.id or float('Inf') def check_words_were_repeated(w: WordStatus): """ Проверка, что слово было повторено id слова, которое нужно повторять больше id, повторенного слова """ return next_repeat_id > w.id # делаем ручную фильтрацию вместо sql, т.k. до этого был выполнен prefetch_related, # который вытащил все repeat_words repeat_words = filter(check_words_were_repeated, self.repeat_words.all()) now = get_datetime_now() for word_status in repeat_words: word_status.set_next_repetition_time(now)
def reset_password(user_id): """ This api for the user management resets the users password. Request Body: Returns: Examples:: """ user = client.db.users.find_one({"_id": user_id}) if user is None: return send_error(message="Not found user!") try: json_data = request.get_json() # Check valid params validate(instance=json_data, schema=password_validator) new_password = json_data.get('new_password', None) except Exception as ex: logger.error('{} Parameters error: '.format(get_datetime_now().strftime('%Y-%b-%d %H:%M:%S')) + str(ex)) return send_error(message='Parse error ' + str(ex)) if is_password_contain_space(new_password): return send_error(message='Password cannot contain spaces') new_value = { '$set': { 'password_hash': hash_password(new_password) } } try: client.db.users.update_many({'_id': user_id}, new_value) except Exception as ex: return send_error(message='Database error: ' + str(ex)) # revoke all token of reset user from database revoke_all_token(user_id) return send_result(data=None, message="Reset password successfully!")