def edit_wishlist(id): """изменение данных желания""" id = int(id) form = EditWishListForm() # без choices SelectMultipleField не работает // желания, которые можно добавить в список conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT item_id, title ' \ 'FROM item ' \ 'WHERE giver_id IS NULL AND item_id NOT IN (SELECT item_id FROM item_list WHERE id = %s);' curs.execute(sql, (id,)) result2 = curs.fetchall() if len(result2) > 0: form.wishes.choices = result2 if form.validate_on_submit(): # если изменили информацию и она прошла валидацию, то данные записываются в БД conn = cn.get_connection() curs = conn.cursor() sql = 'UPDATE wishlist ' \ 'SET title = %s, about = %s, access_level = %s ' \ 'WHERE id = %s;' curs.execute(sql, (form.title.data, form.about.data, form.access_level.data, id,)) # удалим неактуальную информацию о желаниях в списке sql = 'DELETE FROM item_list ' \ 'WHERE id = %s' curs.execute(sql, (id,)) if len(form.wishes.choices) > 0: # связываем список и желания в нем (если в списке есть желания) sql = 'INSERT INTO item_list(id, item_id) VALUES (%s, %s);' for item_id in form.wishes.data: curs.execute(sql, (id, item_id,)) conn.commit() conn.close() flash('Your changes have been saved.') return render_template('edit_wishlist.html', form=form, title=form.title.data) elif request.method == 'GET': conn = cn.get_connection() curs = conn.cursor() # информация о списке sql = 'SELECT title, about, access_level ' \ 'FROM wishlist ' \ 'WHERE id = %s;' curs.execute(sql, (id,)) result = curs.fetchone() conn.close() # если метод GET, то в формы записываем данные пользователя form.title.data = result["title"] form.about.data = result["about"] form.access_level.data = result["access_level"] return render_template('edit_wishlist.html', form=form, title=form.title.data)
def all_item(nickname): """отображение всех желаний и списков пользователя""" conn = cn.get_connection() curs = conn.cursor() id = None result = None if current_user.nickname == nickname: id = current_user.id sql = '''SELECT id AS id, title, id, 'list' AS types, 0 AS giver_id, NULL AS picture ''' \ 'FROM wishlist ' \ 'WHERE id = %s ' \ 'UNION ' \ '''SELECT item_id AS id, title, id, 'wish' AS types, giver_id, picture ''' \ 'FROM item JOIN user_item USING (item_id) ' \ 'WHERE id = %s AND item_id NOT IN (SELECT item_id FROM item_list);' curs.execute(sql, (id, id,)) result = curs.fetchall() else: # только открытые списки sql = 'SELECT id ' \ 'FROM users ' \ 'WHERE nickname = %s;' curs.execute(sql, (nickname,)) id = curs.fetchone() sql = '''SELECT id AS id, title, id, 'list' AS types, 0 AS giver_id, NULL AS picture ''' \ 'FROM wishlist ' \ 'WHERE id = %s AND access_level = %s ' \ 'UNION ' \ '''SELECT item_id AS id, title, id, 'wish' AS types, giver_id, picture ''' \ 'FROM item JOIN user_item USING (item_id) ' \ 'WHERE id = %s AND access_level = %s AND giver_id IS NULL AND item_id NOT IN (SELECT item_id FROM item_list);' curs.execute(sql, (id["id"], True, id["id"], True,)) result = curs.fetchall() conn.close() return render_template('fullwish.html', wishes=result, nickname=nickname)
def login(): """функция авторизации""" if current_user.is_authenticated: return redirect(url_for('index')) # во избежание повторной авторизации form = LoginForm() if form.validate_on_submit(): conn = cn.get_connection() curs = conn.cursor() sql = "SELECT * FROM users WHERE nickname = %s;" curs.execute(sql, (form.nickname.data,)) result = curs.fetchone() conn.close() if result is None: user = None else: user = User(result['user_id'], result['phone_number'], result['user_name'], result['surname'], result['userpic'], result['about'], result['birthday'], result['password_hash'], result['nickname'], result['email'], result["last_seen"]) if user is None or not user.check_password(form.password.data): flash('Invalid username or password') return redirect(url_for('login')) login_user(user, remember=form.remember_me.data) next_page = request.args.get('next') if not next_page or url_parse( next_page).netloc != '': # перенаправление на след страницу, если не был авторизован next_page = url_for('index') return redirect(next_page) return render_template('login.html', title='Sign In', form=form)
def get_friends(user_id): """Возвращает друзей конкретного пользователя""" conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT * FROM users WHERE id = %s' curs.execute(sql, (user_id, )) user = curs.fetchone() if user is None: return bad_request("User wasn't found") sql = 'SELECT user_id_2 ' \ 'FROM friendship ' \ 'WHERE user_id_1 = %s;' curs.execute(sql, (user_id, )) result = curs.fetchall() friends = result["user_id_2"] page = request.args.get('page', 1, type=int) per_page = min(request.args.get('per_page', 10, type=int), 100) data = User.to_collection_dict('users', friends, page, per_page, 'api.get_friends', id=id) conn.close() return jsonify(data)
def add_wishlist(nickname): """создать список желаний""" form = AddWishListForm() '''желание может состоять только в одном списке, или не состоять вообще''' conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT item_id , title ' \ 'FROM (item JOIN user_item USING (item_id)) AS o ' \ 'WHERE id = %s AND giver_id IS NULL AND NOT EXISTS (SELECT * FROM item_list WHERE item_id = o.item_id);' curs.execute(sql, (current_user.id,)) form.wishes.choices = [(i["item_id"], i["title"]) for i in curs.fetchall()] if form.validate_on_submit(): # заливаем список sql = 'INSERT INTO wishlist (title, about, access_level, id) VALUES (%s, %s, %s, %s) RETURNING id;' curs.execute(sql, (form.title.data, form.about.data, form.access_level.data, current_user.id,)) result = curs.fetchone() if len(form.wishes.data) > 0: # связываем список и желания в нем (если в список были добавлены желания) sql = 'INSERT INTO item_list(id, item_id) VALUES (%s, %s);' for item_id in form.wishes.data: curs.execute(sql, (result["id"], item_id,)) conn.commit() conn.close() flash('New wish was added!') return redirect(url_for('all_item', nickname=nickname)) conn.close() return render_template('add_wishlist.html', form=form)
def register(): """функция регистрации""" if current_user.is_authenticated: return redirect(url_for('index')) form = RegistrationForm() if form.validate_on_submit(): user = User(phone_number=form.phone_number.data, name=form.name.data, surname=form.surname.data, birthday=form.birthday.data, nickname=form.nickname.data, email=form.email.data) user.set_password(form.password.data) conn = cn.get_connection() curs = conn.cursor() sql = "INSERT INTO users (phone_number, username, surname, birthday, \ password_hash, nickname, email) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING id;" curs.execute(sql, (form.phone_number.data, form.name.data, form.surname.data, datetime.datetime.strptime(form.birthday.data, '%d/%m/%Y'), generate_password_hash(form.password.data), form.nickname.data, form.email.data,)) result = curs.fetchone() image_path = 'static/images/users/userpic.png' # фото по умолчанию sql = 'UPDATE users ' \ 'SET userpic = %s ' \ 'WHERE user_id = %s;' curs.execute(sql, (image_path, result["user_id"])) conn.commit() conn.close() flash('Congratulations, you are now a registered user!') return redirect(url_for('login')) return render_template('register.html', title='Register', form=form)
def wish_item(item_id): """отображение конкретного желания""" conn = cn.get_connection() curs = conn.cursor() # все о wish sql = 'SELECT * ' \ 'FROM item ' \ 'WHERE id = %s;' curs.execute(sql, (item_id,)) result = curs.fetchone() sql = 'SELECT degree ' \ 'FROM degree_of_desire ' \ 'WHERE degree_id IN (' \ ' SELECT degree_id ' \ ' FROM item_degree ' \ ' WHERE id = %s);' curs.execute(sql, (result["item_id"],)) result3 = curs.fetchone() # защита от несанкционированного доступа sql = 'SELECT nickname ' \ 'FROM users ' \ 'WHERE id IN (' \ ' SELECT id ' \ ' FROM user_item ' \ ' WHERE id = %s);' curs.execute(sql, (item_id,)) result2 = curs.fetchone() conn.close() if (result["access_level"] and result["giver_id"] is None) or current_user.nickname == result2["nickname"]: return render_template('show_wish.html', wish=result, nickname=result2["nickname"], degree=result3["degree"]) else: return render_template('show_wish.html', wish=None, nickname=None, degree=None)
def before_request(): # выполняется непосредственно перед функцией просмотра """при каждом запросе авторизованного пользователя записывается его последнее время активности""" if current_user.is_authenticated: current_user.last_seen = datetime.datetime.utcnow() conn = cn.get_connection() curs = conn.cursor() sql = 'UPDATE users SET last_seen = %s WHERE nickname = %s;' curs.execute(sql, (current_user.last_seen, current_user.nickname,)) conn.commit() conn.close()
def is_friend(self, user_2): """проверка на дружбу""" conn = cn.get_connection() curs = conn.cursor() argum = [self.user_id, user_2] sql = 'SELECT COUNT(*) FROM friendship WHERE (user_id_1 = %s and user_id_2 = %s);' curs.execute(sql, argum) result = curs.fetchone() conn.close() return result[0] == 1
def validate_email(self, email): """проверка действительности email""" conn = cn.get_connection() curs = conn.cursor() sql = "SELECT * FROM users WHERE email = %s;" curs.execute(sql, (email.data, )) result = curs.fetchone() conn.close() if result is not None: raise ValidationError( 'User with this email is already registered.')
def validate_nickname(self, nickname): """проверка nickname на повтор""" conn = cn.get_connection() curs = conn.cursor() sql = "SELECT * FROM users WHERE nickname = %s;" curs.execute(sql, (nickname.data, )) result = curs.fetchone() conn.close() #user = User.query.filter_by(username=username.data).first() if result is not None: raise ValidationError('This nickname is occupied.')
def delete_wish(item_id): """удалить желание""" item_id = int(item_id) conn = cn.get_connection() curs = conn.cursor() sql = 'DELETE FROM item WHERE item_id = %s AND ' \ 'item_id IN (SELECT item_id FROM user_item WHERE id = %s);' curs.execute(sql, (item_id, current_user.id)) result = curs.fetchall() conn.close() return render_template('add_wish.html', wish=result)
def send_request(self, user_to): """отправить запрос на дружбу на входе id пользователей""" conn = cn.get_connection() curs = conn.cursor() sql = 'INSERT INTO friend_requests VALUES (%s, %s);' curs.execute(sql, ( self.user_id, user_to, )) conn.commit() conn.close()
def validate_nickname(self, nickname): """проверка nickname на повтор""" if current_user.nickname == nickname.data: return conn = cn.get_connection() curs = conn.cursor() sql = "SELECT * FROM users WHERE nickname = %s;" curs.execute(sql, (nickname.data, )) result = curs.fetchone() conn.close() if result is not None: raise ValidationError('This nickname is occupied.')
def is_request(self, user_2): """проверка на запрос дружбы""" conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT COUNT(*) FROM friend_requests WHERE (user_id_from = %s and user_id_to = %s);' curs.execute(sql, ( self.user_id, user_2, )) result = curs.fetchone() conn.close() return result[0] == 1
def make_wish(item_id): """исполнить (зарезервировать) желание""" item_id = int(item_id) conn = cn.get_connection() curs = conn.cursor() sql = 'UPDATE item ' \ 'SET giver_id = %s ' \ 'WHERE item_id = %s;' curs.execute(sql, (current_user.id, item_id,)) conn.commit() flash('You select a wish!') conn.close() return redirect(url_for('presents'))
def wish_fullfiled(item_id): """пользователь-владелец отмечает, что зарезервированное ранее желание исполнено. то есть зарезервированное желание удаляется""" '''на самом деле нужно присвоить данному предмету статус исполнено. для этого нужно проверить всю остальнюю логику и отображение - слишком много времени, пока не до этого''' item_id = int(item_id) conn = cn.get_connection() curs = conn.cursor() sql = 'DELETE FROM item WHERE item_id = %s;' curs.execute(sql, (item_id,)) conn.commit() conn.close()
def validate_email(self, email): """проверка существования ящика""" if current_user.email == email.data: return conn = cn.get_connection() curs = conn.cursor() sql = "SELECT * FROM users WHERE email = %s;" curs.execute(sql, (email.data, )) result = curs.fetchone() conn.close() if result is not None: raise ValidationError( 'User with this email is already registered.')
def cancel_request(nickname): """отменить запрос в друзья""" conn = cn.get_connection() curs = conn.cursor() sql = "SELECT id FROM users WHERE nickname = %s;" curs.execute(sql, (nickname,)) result = curs.fetchone() conn.close() if result is None: flash('User {} not found.'.format(nickname)) return redirect(url_for('index')) current_user.reject_request(result['id']) flash('You canceled friend request to {} .'.format(nickname)) return redirect(url_for('user_profile', nickname=nickname))
def remove_friend(self, user_2): """удалить из друзей на входе id друга""" conn = cn.get_connection() curs = conn.cursor() sql = 'DELETE FROM friendship WHERE (user_id_1 = %s and user_id_2 = %s) OR (user_id_1 = %s and user_id_2 = %s);' curs.execute(sql, ( self.user_id, user_2, user_2, self.user_id, )) conn.commit() conn.close()
def add_friend(nickname): """добавить пользователя в друзья (отправить запрос на дружбу)""" conn = cn.get_connection() curs = conn.cursor() sql = "SELECT id FROM users WHERE nickname = %s;" curs.execute(sql, (nickname,)) result = curs.fetchone() conn.close() if result is None: # если пользователь не найден flash('User {} not found.'.format(nickname)) return redirect(url_for('index')) current_user.send_request(result['id']) flash('You have send friend request to {}!'.format(nickname)) return redirect(url_for('user_profile', nickname=nickname))
def delete_friend(nickname): """удалить пользователя из друзей""" conn = cn.get_connection() curs = conn.cursor() sql = "SELECT id FROM users WHERE nickname = %s;" curs.execute(sql, (nickname,)) result = curs.fetchone() conn.close() if result is None: flash('User {} not found.'.format(nickname)) return redirect(url_for('index')) current_user.remove_friend(result['id']) flash('You and {} are not friends .'.format(nickname)) return redirect(url_for('user_profile', nickname=nickname))
def accept_request(nickname): """принять запрос в друзья""" conn = cn.get_connection() curs = conn.cursor() sql = "SELECT id FROM users WHERE nickname = %s;" curs.execute(sql, (nickname,)) result = curs.fetchone() conn.close() if result is None: flash('User {} not found.'.format(nickname)) return redirect(url_for('index')) current_user.accept_request(result['id']) flash('You and {} are friends now.'.format(nickname)) return redirect(url_for('user_profile', nickname=nickname))
def edit_wish(item_id): """изменение желания""" form = EditWishForm() if form.validate_on_submit(): # если изменили информацию и она прошла валидацию, то данные записываются в БД conn = cn.get_connection() curs = conn.cursor() sql = 'UPDATE item ' \ 'SET title = %s, about = %s, access_level = %s, picture = %s ' \ 'WHERE item_id = %s;' \ 'UPDATE item_degree ' \ 'SET degree_id = %s ' \ 'WHERE item_id = %s;' curs.execute(sql, (form.title.data, form.about.data, form.access_level.data, form.picture.data, item_id, form.degree.data, item_id,)) conn.commit() conn.close() flash('Your changes have been saved.') return render_template('edit_wish.html', form=form, title=form.title.data) elif request.method == 'GET': conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT title, about, access_level, picture, degree_id ' \ 'FROM item JOIN item_degree USING (item_id) ' \ 'WHERE item_id = %s;' curs.execute(sql, (item_id,)) result = curs.fetchone() conn.commit() conn.close() # если метод GET, то в формы записываем данные пользователя form.title.data = result["title"] form.about.data = result["about"] form.access_level.data = result["access_level"] form.picture.data = result["picture"] form.degree.data = result["degree_id"] return render_template('edit_wish.html', form=form, title=form.title.data)
def presents(): """отображение желаний, который будет исполнять пользователь""" conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT id ' \ 'FROM users ' \ 'WHERE nickname = %s;' curs.execute(sql, (current_user.nickname,)) id = curs.fetchone() sql = 'SELECT item_id, title ' \ 'FROM item ' \ 'WHERE giver_id = %s;' curs.execute(sql, (id["id"],)) result = curs.fetchall() conn.close() return render_template('my_presents.html', presents=result, nickname=current_user.nickname)
def reject_request(self, user_2): """отклонить запрос на дружбу / отменить запрос на дружбу""" conn = cn.get_connection() curs = conn.cursor() # удаляем запрос на дружбу sql = 'DELETE FROM friend_requests WHERE (user_id_from = %s and user_id_to = %s) \ OR (user_id_from = %s and user_id_to = %s);' curs.execute(sql, ( self.user_id, user_2, user_2, self.user_id, )) conn.commit() conn.close()
def revoke_token(self): """ отзыв действующего токена :return: """ self.token_expiration = datetime.utcnow() - timedelta(seconds=1) conn = cn.get_connection() curs = conn.cursor() sql = 'UPDATE users ' \ 'SET token_expiration = %s ' \ 'WHERE id = %s;' curs.execute(sql, ( self.token_expiration, self.user_id, )) conn.commit() conn.close()
def get_user(user_id): """Возвращает конкретного пользователя""" conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT * FROM users WHERE id = %s' curs.execute(sql, (user_id, )) result = curs.fetchone() conn.close() if result is None: return bad_request("User wasn't found") else: user = User(result['id'], result['phone_number'], result['username'], result['surname'], result['userpic'], result['about'], result['birthday'], result['password_hash'], result['nickname'], result['email'], result['token'], result['token_expiration'], result["last_seen"]) return jsonify(user.to_dict())
def to_collection_dict(required_object, condition, page, per_page, endpoint, **kwargs): """ создает словарь с представлением коллекции (пользователей, желаний, списков) :param required_object: str:требуемый объект или SQL запрос? :param condition: условие в WHERE :param page: номер страницы :param per_page: кол-во объектов на странице :param endpoint: - путь :param kwargs: :return: """ # TODO как реализовать универсальное постраничное представление conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT * ' \ 'FROM %s ' \ 'WHERE id IN %s ' \ 'ORDER BY id ' \ 'OFFSET %s ROWS ' \ 'FETCH NEXT %s ROW ONLY;' curs.execute(sql, (required_object, condition, page * per_page, per_page)) resources = curs.fetchall() # resources = query.paginate(page, per_page, False) data = { 'items': [item.to_dict() for item in resources.items], '_meta': { 'page': page, 'per_page': per_page, 'total_pages': resources.pages, 'total_items': resources.total }, '_links': { 'self': url_for(endpoint, page=page, per_page=per_page, **kwargs), 'next': url_for(endpoint, page=page + 1, per_page=per_page, **kwargs) if resources.has_next else None, 'prev': url_for(endpoint, page=page - 1, per_page=per_page, **kwargs) if resources.has_prev else None } } return data
def user_profile(nickname): """показ профиля пользователя""" conn = cn.get_connection() curs = conn.cursor() sql = 'SELECT * FROM users WHERE nickname = %s;' curs.execute(sql, (nickname,)) result = curs.fetchone() conn.close() if result is None: user = None flash('User {} not found.'.format(nickname)) return redirect(url_for('index')) else: user = User(result['id'], result['phone_number'], result['username'], result['surname'], result['userpic'], result['about'], result['birthday'], result['password_hash'], result['nickname'], result['email']) return render_template('user_profile.html', user=user)