Skip to content

Commit

Permalink
added applaud (like) feature
Browse files Browse the repository at this point in the history
  • Loading branch information
dannydenenberg committed Oct 30, 2021
1 parent 15c0030 commit ed4fe13
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 179 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ The `@click.command("init-db")` decorator makes a function call when you type: `

The `url_for("auth.login")` is for the "auth" blueprint and the `login` function.

To read in the database and interact with it:
- Run `sqlite3 database.sqlite`.
- Run `.mode column` and `.headers on`
- Then run your query: `select * from users;` etc..

Make sure when running JavaScript inside of a .html file, it gets put inside a block. It won't get run otherwise.

### Running

1. `cd` into the main directory.
Expand Down
10 changes: 5 additions & 5 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ def hello():
db.init_app(app)

# apply the blueprints to the app
import auth, blog
import auth, roar

app.register_blueprint(auth.bp)
app.register_blueprint(blog.bp)
app.register_blueprint(roar.bp)

# make url_for('index') == url_for('blog.index')
# make url_for('index') == url_for('roar.index')
# in another app, you might define a separate main index here with
# app.route, while giving the blog blueprint a url_prefix, but for
# the tutorial the blog will be the main index
# app.route, while giving the roar blueprint a url_prefix, but for
# the tutorial the roar will be the main index
app.add_url_rule("/", endpoint="index")

return app
Expand Down
122 changes: 0 additions & 122 deletions blog.py

This file was deleted.

Binary file removed instance/password_manager.sqlite
Binary file not shown.
170 changes: 170 additions & 0 deletions roar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
from flask import Blueprint
from flask import flash
from flask import g
from flask import redirect
from flask import render_template
from flask import request
from flask import url_for
from werkzeug.exceptions import abort

from auth import login_required
from db import get_db

bp = Blueprint("roar", __name__)


@bp.route("/")
def index():
"""Show all the posts, most recent first."""
db = get_db()
posts = db.execute(
"""
select
p.id,
roar,
p.created,
author_id,
(select count(*) from applaud a WHERE a.post_id = p.id) applauds,
username
from post p join user u on p.author_id = u.id
order by p.created desc;
"""
).fetchall()

applauds = [] # dic with {post_number: True/False} whether the post has been liked by the person.
if g.user is not None: # if the person is signed in.
applauds_list = db.execute(
"SELECT post_id FROM applaud WHERE user_id = ?",
(g.user["id"],),
).fetchall()
[applauds.append(a["post_id"]) for a in applauds_list] # make a list of only the ID numbers.

print(applauds)


return render_template("roar/index.html", posts=posts, applauds=applauds)


def get_post(id, check_author=True):
"""Get a post and its author by id.
Checks that the id exists and optionally that the current user is
the author.
:param id: id of post to get
:param check_author: require the current user to be the author
:return: the post with author information
:raise 404: if a post with the given id doesn't exist
:raise 403: if the current user isn't the author
"""
post = (
get_db()
.execute(
"SELECT p.id, roar, created, author_id, username"
" FROM post p JOIN user u ON p.author_id = u.id"
" WHERE p.id = ?",
(id,),
)
.fetchone()
)

if post is None:
abort(404, f"Post id {id} doesn't exist.")

if check_author and post["author_id"] != g.user["id"]:
abort(403)

return post


@bp.route("/create", methods=("GET", "POST"))
@login_required
def create():
"""Create a new post for the current user."""
if request.method == "POST":
roar = request.form["roar"]
error = None

if not roar:
error = "Put some VOLUME in your ROAR."

if error is not None:
flash(error)
else:
db = get_db()
db.execute(
"INSERT INTO post (roar, author_id) VALUES (?, ?)",
(roar, g.user["id"]),
)
db.commit()
return redirect(url_for("roar.index"))

return render_template("roar/create.html")


@bp.route("/<int:id>/update", methods=("GET", "POST"))
@login_required
def update(id):
"""Update a post if the current user is the author."""
post = get_post(id)

if request.method == "POST":
roar = request.form["roar"]
error = None

if not title:
error = "Put some SOUND in your ROAR."

if error is not None:
flash(error)
else:
db = get_db()
db.execute(
"UPDATE post SET roar = ? WHERE id = ?", (roar, id)
)
db.commit()
return redirect(url_for("roar.index"))

return render_template("roar/update.html", post=post)


@bp.route("/<int:id>/delete", methods=("POST",))
@login_required
def delete(id):
"""Delete a post.
Ensures that the post exists and that the logged in user is the
author of the post.
"""
get_post(id)
db = get_db()
db.execute("DELETE FROM post WHERE id = ?", (id,))
db.commit()
return redirect(url_for("roar.index"))

@bp.route("/applaud", methods=("GET",))
@login_required
def applaud():
post_id = request.args.get('post_id', 0, type=int)
user_id = g.user["id"]

previous_applauds = get_db().execute(
"SELECT * FROM applaud WHERE post_id = ? AND user_id = ?",
(post_id, user_id),
).fetchall()


db = get_db()
if len(previous_applauds) == 0:
# not previously liked.
# add the person to the posts likers
db.execute(
"INSERT INTO applaud (user_id, post_id) VALUES (?, ?)",
(user_id, post_id),
)
db.commit()
else:
# UNlike this post for the person
# delete this person from the post's likes
db.execute("DELETE FROM applaud WHERE user_id = ? AND post_id = ?", (user_id, post_id))
db.commit()


return {}
21 changes: 17 additions & 4 deletions schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,31 @@

DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;
DROP TABLE IF EXISTS applaud;

CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
password TEXT NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

-- The thing is called 'post' but the content is called 'roar'.
CREATE TABLE post (
id INTEGER PRIMARY KEY AUTOINCREMENT,
author_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL,
body TEXT NOT NULL,
-- title TEXT NOT NULL,
roar TEXT NOT NULL,
FOREIGN KEY (author_id) REFERENCES user (id)
);
);

CREATE TABLE applaud (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
post_id INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES user (id),
FOREIGN KEY (post_id) REFERENCES post (id)
);

2 changes: 2 additions & 0 deletions static/jquery-3.6.0.min.js

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<!doctype html>
<head>
<script src="{{ url_for('static', filename='jquery-3.6.0.min.js') }}"></script>
<script>
$SCRIPT_ROOT = {{ request.script_root | tojson }}; // get the root of the website from the clientk side
console.log(`hey22: ${$SCRIPT_ROOT}`)
</script>
</head>
<title>{% block title %}{% endblock %} - Roar</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<nav>
Expand Down
15 changes: 0 additions & 15 deletions templates/blog/create.html

This file was deleted.

Loading

0 comments on commit ed4fe13

Please sign in to comment.