예제 #1
0
def api_user_unfollow():
    try:
        data = json.loads(request.data,
                          object_hook=lambda x: defaultdict(lambda: None, x))
    except JSONDecodeError:
        return error_response(["Invalid request."])

    if "id" not in data:
        return error_response(["User ID required"])

    current_id = int(current_user.get_id())
    user_to_unfollow = User.query.get(int(data["id"]))

    if user_to_unfollow is None:
        return error_response(["User cannot be found"])

    if user_to_unfollow.followers.filter_by(id=current_id).count() < 1:
        return error_response(["You aren't following that user"])

    query = (follows.delete().where(follows.c.follower_id == current_id).where(
        follows.c.following_id == int(data["id"])))
    db.session.execute(query)
    db.session.commit()

    user = User.query.get(current_id)

    ids = user.following.with_entities(User.id).all()

    return success_response([item for sublist in ids for item in sublist])
예제 #2
0
def api_tweet():
    try:
        data = json.loads(
            request.data, object_hook=lambda x: defaultdict(lambda: None, x)
        )
    except JSONDecodeError:
        return error_response(["Invalid request."])

    tweet_text = data["text"] or ""
    tweet_text = tweet_text.strip().replace("\r\n", "\n")
    tweet_len = len(tweet_text)

    if tweet_len < 1:
        return error_response(["Your tweet must be at least one character."])

    if tweet_len > 120:
        return error_response(["Your tweet must be at most 120 characters."])

    image_id = data["imageId"]

    if image_id is not None:
        image_exists = Image.query.filter_by(id=image_id).count() > 0

        if not image_exists:
            return error_response(["Image not found"])

    tweet = Tweet(
        text=tweet_text, poster_id=int(current_user.get_id()), image_id=image_id
    )

    db.session.add(tweet)
    db.session.commit()

    return success_response(tweet.to_dict())
예제 #3
0
def api_file_info(name: str):
    file = Image.query.filter_by(name=name).first()

    if file is None:
        return error_response(["File not found"])

    return success_response(file.to_dict())
예제 #4
0
def api_login():
    try:
        data = json.loads(request.data,
                          object_hook=lambda x: defaultdict(lambda: None, x))
    except JSONDecodeError:
        return error_response(["Invalid request."])

    user = User.query.filter_by(username=data["username"]).first() or User(
        password="")

    # Password is checked irregardless of whether
    # the user was found to avoid exposing a timing oracle
    valid_credentials = User.check_password(user.password, data["password"])

    if not valid_credentials:
        return error_response(["Invalid credentials."])

    login_user(user=user, remember=data["rememberMe"])

    return success_response(user.to_dict())
예제 #5
0
def api_file_upload():
    if "file" not in request.files:
        return error_response(["File must be provided"])

    file: FileStorage = request.files["file"]

    if not file or file.filename == "":
        return error_response(["File must be provided"])

    if file.mimetype not in {"image/jpeg", "image/gif"}:
        return error_response(
            ["Invalid image format. Must be a .jpg, .jpeg or .gif file."])

    user_id = int(current_user.get_id())

    filename_len = 10
    filename = "".join(
        random.choices(string.ascii_letters + string.digits, k=filename_len))
    ts = calendar.timegm(time.gmtime())

    filename = "%s-%d-%s.jpg" % (user_id, ts, filename)
    fs_path = os.path.join(app.config["UPLOAD_DIR"], filename)

    file.save(fs_path)

    file_hash = hash_file(fs_path)

    image = Image(
        name=filename,
        original_name=file.filename,
        fs_path=fs_path,
        hash=file_hash,
        mime_type=file.mimetype,
        uploader_id=user_id,
    )

    db.session.add(image)
    db.session.commit()

    return success_response(image.to_dict())
예제 #6
0
def api_delete_tweet(tweet_id: int):
    tweet = Tweet.query.get(tweet_id)

    if not tweet or tweet.poster_id != int(current_user.get_id()):
        return error_response(["You don't have permission to do that."])

    db.session.delete(tweet)

    if tweet.image:
        db.session.delete(tweet.image)

    db.session.commit()

    return success_response(None)
예제 #7
0
def api_register():
    try:
        data = json.loads(request.data)
    except JSONDecodeError:
        return error_response(["Invalid request."])

    required_fields = ["username", "password", "passwordRepeat"]

    has_required = all(field in data for field in required_fields)

    if not has_required:
        return error_response(["Please fill in all required fields."])

    password_too_short = len(data["password"]) < 8

    if password_too_short:
        return error_response(["Your password is too short."])

    passwords_match = data["password"] == data["passwordRepeat"]

    if not passwords_match:
        return error_response(["Passwords must match."])

    username_taken = User.query.filter_by(
        username=data["username"]).first() is not None

    if username_taken:
        return error_response(["Username is already taken"])

    user = User(username=data["username"]).set_password(data["password"])

    db.session.add(user)
    db.session.commit()

    login_user(user=user)

    return success_response(user.to_dict())
예제 #8
0
def api_user_search():
    try:
        data = json.loads(request.data,
                          object_hook=lambda x: defaultdict(lambda: None, x))
    except JSONDecodeError:
        return error_response(["Invalid request."])

    page = data["page"] or 1
    try:
        page = int(page)
    except ValueError:
        page = 1

    query = data["query"] or ""
    query = "%{}%".format(query)

    users = User.query.filter(User.username.ilike(query))

    return paginated_query(query=users, page=page)