diff --git a/README.md b/README.md index 09a2229a10312ad283fc0330b78edec339880a99..fce355056ca257f64d069749331e5ed0eb84a058 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# cwblog +#cwblog TO RUN IT USING DOCKER SERVICES, MAKE SURE ALL .ENV FILES IN SERVICES ARE AS CONFIGURATION_SETUP="config.ProductionConfig" THEN YOU CAN RUN PROJECT "sudo bash run.sh" -IF YOU WOULD LIKE TO USE DEVELOPMENT SERVER AND RUN APPLICATION IN LOCALHOST -GO INTO ALL SERVICES, CHANGE .ENV FILES AND CHANGE THEM AS +IF YOU WOULD LIKE TO USE DEVELOPMENT SERVER AND RUN APPLICATION WITHOUT DOCKER SERVICES +GO INTO ALL SERVICE FOLDERS, CHANGE .ENV FILES AS CONFIGURATION_SETUP="config.DevelopmentConfig" -THEN RUN SERVICES USING "python3 run.py" command for each services. +THEN RUN SERVICES USING TERMINAL "python3 run.py" IN EACH SERVICE FOLDER. diff --git a/frontend/application/frontend/api/PostClient.py b/frontend/application/frontend/api/PostClient.py index d73e2b465cb12ba64944610b5ce37593e8e0d9ed..737a48af6e9f7b4ee6b56515415d4d4e4e012378 100644 --- a/frontend/application/frontend/api/PostClient.py +++ b/frontend/application/frontend/api/PostClient.py @@ -19,6 +19,17 @@ class PostClient: return response + def get_hot_posts(per_page,offset): + url = 'http://' + PostClient.post_service + '/api/hotposts/' + str(per_page) + '/' + str(offset) + response = requests.request(method="GET", url=url) + + if response.status_code == 404: + return response.status_code + + response = response.json() + + return response + def get_category_posts(category,per_page,offset): url = 'http://' + PostClient.post_service + '/api/posts/'+ str(category) + '/' + str(per_page) + '/' + str(offset) response = requests.request(method="GET", url=url) diff --git a/frontend/application/frontend/api/UserClient.py b/frontend/application/frontend/api/UserClient.py index ff7d8f9780ec0887c6f146ce8651acb6b4a0d0b3..2fdb58c4a4e688ff974e668c47c1ce2c42c3cfd3 100644 --- a/frontend/application/frontend/api/UserClient.py +++ b/frontend/application/frontend/api/UserClient.py @@ -95,7 +95,7 @@ class UserClient: if response: d = response.json() - print("This is response from user api: " + str(d)) + # print("This is response from user api: " + str(d)) if d['api_key'] is not None: api_key = d['api_key'] return api_key diff --git a/frontend/application/frontend/views.py b/frontend/application/frontend/views.py index dc957e4225926f698900049a58f9e2a18fed0e55..201bb5f8e7ea6bbc7228061bb6d3ff88f25536d4 100644 --- a/frontend/application/frontend/views.py +++ b/frontend/application/frontend/views.py @@ -118,7 +118,6 @@ def login_route(): @frontend_blueprint.route('/', methods=['GET']) @frontend_blueprint.route('/page/<int:page>', methods=['GET']) def get_posts(page=1): - print(session) if len(session)<4: return redirect(url_for('frontend.login_route')) @@ -222,9 +221,40 @@ def search(page=1): image_urls.append(user['image_url']) categories = ['activities','courses&modules','societies', - 'student_union','accommodation','transportation','lost&found','sale&rental','other'] + 'student_union','accommodation','transportation','lost&found','sale&rental','other'] return render_template('forum/search.html', + data=zip(posts,image_urls), words=words, categories=categories,page=page, page_limit=page_limit) + + +@frontend_blueprint.route('/weeklyhots/', methods=['GET','POST']) +@frontend_blueprint.route('/weeklyhots/<int:page>', methods=['GET','POST']) +def get_hot_posts(page=1): + image_urls = [] + per_page = 4 + offset = (page - 1) * per_page + posts = PostClient.get_hot_posts(per_page,offset) + + if posts == 404: + flash('No post in last 7 days', 'fail') + return redirect(url_for('frontend.get_posts')) + + page_limit = True + offset_ = (page) * per_page + next_posts = PostClient.get_hot_posts(per_page,offset_) + if next_posts == 404: + page_limit = False + if len(posts) < per_page: + page_limit = False + + for post in posts: + user = UserClient.get_otheruser(post['user_id']) + image_urls.append(user['image_url']) + + categories = ['activities','courses&modules','societies', + 'student_union','accommodation','transportation','lost&found','sale&rental','other'] + + return render_template('forum/hotposts.html', data=zip(posts,image_urls), categories=categories,page=page, page_limit=page_limit) @@ -257,6 +287,7 @@ def save_user_image(image_file): @frontend_blueprint.route('/post/images/users/<image_id>' , methods=['GET']) +@frontend_blueprint.route('/weeklyhots/images/users/<image_id>' , methods=['GET']) @frontend_blueprint.route('/search/images/users/<image_id>' , methods=['GET']) @frontend_blueprint.route('/page/images/users/<image_id>' , methods=['GET']) @frontend_blueprint.route('/user/images/users/<image_id>' , methods=['GET']) @@ -264,17 +295,18 @@ def save_user_image(image_file): def get_user_image(image_id): picture_path = path.join(current_app.root_path, 'static/images/users', image_id) - print(picture_path) + return send_file(picture_path, mimetype='image/gif') @frontend_blueprint.route('/post/images/<image_id>' , methods=['GET']) +@frontend_blueprint.route('/weeklyhots/static/images/<image_id>' , methods=['GET']) @frontend_blueprint.route('/page/static/images/<image_id>' , methods=['GET']) @frontend_blueprint.route('/search/static/images/<image_id>' , methods=['GET']) def get_post_image(image_id): picture_path = path.join(current_app.root_path, 'static/images', image_id) - print(picture_path) + return send_file(picture_path, mimetype='image/gif') @@ -310,7 +342,11 @@ def create_post(): 'form': form, 'post': None } - return render_template('forum/create_post.html', **content) + + categories = ['activities','courses&modules','societies', + 'student_union','accommodation','transportation','lost&found','sale&rental','other'] + + return render_template('forum/create_post.html', **content, categories=categories) @frontend_blueprint.route('/post/<int:post_id>', methods=['GET','POST']) diff --git a/frontend/application/static/images/0bf48bdfa114d912.jpg b/frontend/application/static/images/0bf48bdfa114d912.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b7f5716ea81e9977059833080a716ed0a84e799d Binary files /dev/null and b/frontend/application/static/images/0bf48bdfa114d912.jpg differ diff --git a/frontend/application/static/images/users/a51fa503f5e95bb9.jpg b/frontend/application/static/images/users/a51fa503f5e95bb9.jpg new file mode 100644 index 0000000000000000000000000000000000000000..88138f054c3dceabede0508508a813d15cc1bcb5 Binary files /dev/null and b/frontend/application/static/images/users/a51fa503f5e95bb9.jpg differ diff --git a/frontend/application/static/images/users/b6490c982e8a116e.jpg b/frontend/application/static/images/users/b6490c982e8a116e.jpg new file mode 100644 index 0000000000000000000000000000000000000000..88138f054c3dceabede0508508a813d15cc1bcb5 Binary files /dev/null and b/frontend/application/static/images/users/b6490c982e8a116e.jpg differ diff --git a/frontend/application/templates/forum/category.html b/frontend/application/templates/forum/category.html index bdd075538e981f60eb511f3ae44ff215847f1f48..97e61255a143756bccb8942b35d6030aef19dd3e 100644 --- a/frontend/application/templates/forum/category.html +++ b/frontend/application/templates/forum/category.html @@ -60,6 +60,8 @@ </div> </div> + <h2 style="text-align: center; font-size: medium; color: orange; font-weight: bold;margin-top: -27px">Posts in {{ category }} category</h2> + {% if page > 1 %} <a class="btn btn-outline-success my-2 my-sm-0" href="{{ url_for('frontend.categories',category=category, page=page-1) }}">Previous</a> {% endif %} diff --git a/frontend/application/templates/forum/hotposts.html b/frontend/application/templates/forum/hotposts.html new file mode 100644 index 0000000000000000000000000000000000000000..4cad9bcd0795590186b7b1ea72c417bf31cac73a --- /dev/null +++ b/frontend/application/templates/forum/hotposts.html @@ -0,0 +1,119 @@ +{% extends "base_col_1.html" %} +{% block title %} HOT POSTS OF THE WEEK {% endblock %} + +{% block pageContent%} + +<style> + body { + background-color: #f8f9fa; + color: #212529; + } + + .card-header { + background-color: #c6e2ff; + color: white; + } + + .nav-link.active { + background-color: #6c757d; + color: white; + } + + .btn-outline-success:hover { + background-color: #218838; + border-color: #1e7e34; + } + .profile-image { + width: 60px; + height: 60px; + object-fit: ; + border-radius: 50%; + } + .post-image { + width: 100px; + height: 100px; + object-fit: contain; + } +</style> + +<div> + +</div> + +<div class="col-md-6 gedf-main"> + <div class="card gedf-card"> + <div class="card-header"> + <ul class="nav nav-tabs card-header-tabs" id="myTab" role="tablist"> + <li class="nav-item"> + <a class="nav-link active" id="posts-tab" data-toggle="tab" href="#posts" role="tab" aria-controls="posts" aria-selected="true">Start a discussion</a> + </li> + </ul> + </div> + <div class="card-body"> + <div class="tab-content" id="myTabContent"> + <div class="tab-pane fade show active" id="posts" role="tabpanel" aria-labelledby="posts-tab"> + <div class="form-group"> + <label class="sr-only" for="message">post</label> + <a class="btn btn--link" href="{{ url_for('frontend.create_post') }}">New Post</a> + </div> + </div> + </div> + </div> + </div> + + <h2 style="text-align: center; font-size: medium; color: orange; font-weight: bold;margin-top: -27px">Weekly Hot Posts</h2> + + {% if page > 1 %} + <a class="btn btn-outline-success my-2 my-sm-0" href="{{ url_for('frontend.get_hot_posts', page=page-1) }}">Previous</a> + {% endif %} + + {% if page_limit == True %} + <a class="btn btn-outline-success my-2 my-sm-0" href="{{ url_for('frontend.get_hot_posts', page=page+1) }}">Next</a> + {% endif %} + + {% for post,image in data %} + <div class="card gedf-card"> + <div class="card-header"> + <div class="d-flex justify-content-between align-items-center"> + <div class="d-flex justify-content-between align-items-center"> + <div class="mr-2"> + <img class="profile-image" src="images/users/{{ image }}"> + </div> + <div class="ml-2"> + <div class="h5 m-0"><a href="{{ url_for('frontend.display_user', user_id=post.user_id) }}">{{ post['user_name'] }}</a></div> + </div> + </div> + <div> + <div class="dropdown"> + </div> + </div> + </div> + </div> + <div class="card-body"> + <div class="text-muted h7 mb-2"> <i class="fa fa-clock-o"></i>{{ post['date_added']}}</div> + <a class="card-link" href="{{ url_for('frontend.display_post', post_id=post.id) }}"> + <h5 class="card-title">{{ post['title'] }}</h5> + </a> + <p class="card-text">{{ post.content[:40] | safe }}{% if post.content|length > 30 %}...{% endif %}</p> + + {% if post['image_url'] != '' %} + <img class="post-image" src="static/images/{{ post['image_url'] }}"> + {% endif %} + </div> + <div class="card-footer"> + <a href="{{ url_for('frontend.display_post', post_id=post.id) }}" class="card-link"><i class="fa fa-comment"></i> Comment</a> + </div> + </div> +{% endfor %} + +{% if page > 1 %} +<a class="btn btn-outline-success my-2 my-sm-0" href="{{ url_for('frontend.get_hot_posts', page=page-1) }}">Previous</a> +{% endif %} + +{% if page_limit == True %} +<a class="btn btn-outline-success my-2 my-sm-0" href="{{ url_for('frontend.get_hot_posts', page=page+1) }}">Next</a> +{% endif %} + +</div> + +{% endblock %} diff --git a/frontend/application/templates/forum/post.html b/frontend/application/templates/forum/post.html index f845e1802fa8421abbc7c7f148b9549740826415..a55cadc7705a00e698cbcb5e8736198ac588b17b 100644 --- a/frontend/application/templates/forum/post.html +++ b/frontend/application/templates/forum/post.html @@ -158,7 +158,7 @@ <!-- START posts --> <div class="col-md-8"> - <div class="post-container" style="height: 400px; width: 100%; overflow: auto; + <div class="post-container" style="height: 40%; width: 100%; overflow-y: auto; word-wrap: break-word; white-space: normal"> <div class="tile__author"> <img class="profile-image" src="images/users/{{ owner_image }}"> @@ -185,7 +185,7 @@ <!-- START comments --> - <div class="comment-container" style="overflow-y: auto; height: 600px; width: 100%"> + <div class="comment-container" style="overflow-y: auto; height: 60%; width: 100%"> <h3 class="comment__title">COMMENTS</h3> {% if comments %} {% for comment, image in comments %} diff --git a/frontend/application/templates/forum/profile.html b/frontend/application/templates/forum/profile.html index 90cd7e326cbe8b9843aee2f1fefd476089070137..e26a7adbea397e315a075eb493b93cd3230353da 100644 --- a/frontend/application/templates/forum/profile.html +++ b/frontend/application/templates/forum/profile.html @@ -243,7 +243,7 @@ <input class="form-submit" type="submit" value="Update"> </form> </div> - <div class="posts"> + <div class="posts" style="word-wrap: break-word; white-space: normal"> <h2>Your Posts</h2> {% for post in posts %} <div class="post"> diff --git a/frontend/application/templates/forum/search.html b/frontend/application/templates/forum/search.html index 6134bfba84db47eac0e9f640775ff1f958fe0a23..9312f920d798c0cc014781f2ae3391f18ecce1a6 100644 --- a/frontend/application/templates/forum/search.html +++ b/frontend/application/templates/forum/search.html @@ -61,6 +61,8 @@ </div> </div> + <h2 style="text-align: center; font-size: medium; color: orange; font-weight: bold; margin-top: -27px;">Search Results for "{{ words }}"</h2> + {% if page > 1 %} <a class="btn btn-outline-success my-2 my-sm-0" href="{{ url_for('frontend.search', page=page-1) }}">Previous</a> {% endif %} diff --git a/frontend/application/templates/forum/user.html b/frontend/application/templates/forum/user.html index f4e6fe25a82e6d7a8d5678f89d6428e83f493437..89cf0c758dcf6f336e4b2eaeed6a13f184dd0206 100644 --- a/frontend/application/templates/forum/user.html +++ b/frontend/application/templates/forum/user.html @@ -79,7 +79,7 @@ align-items: center; </div> <div class="col-md-8 offset-md-4" style="margin-top: 50px;"> <h2>POSTS OF THE USER</h2> - <div style="height: 1500px; overflow-y: scroll;"> + <div style="word-wrap: break-word; white-space: normal"> {% for post in posts %} <div class="post-card"> <h4><a href="{{ url_for('frontend.display_post', post_id=post.id) }}">{{ post['title'] }}</a></h4> diff --git a/frontend/application/templates/navbar.html b/frontend/application/templates/navbar.html index f8b63003bfbaa6f62b291752e67cf8fee12549b2..88d782a40ed16a59da3ce6925791a31408442d05 100644 --- a/frontend/application/templates/navbar.html +++ b/frontend/application/templates/navbar.html @@ -96,7 +96,7 @@ <div class="collapse navbar-collapse justify-content-end" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item"> - <div class="nav-link" style="color: #007bff;"><a href="{{ url_for('frontend.display_currentuser') }}" style="text-decoration:none;">{{ session['user'].full_name }}</a></div> + <div class="nav-link" style="color: #007bff;"><a href="{{ url_for('frontend.get_hot_posts') }}" style="text-decoration:none; color:red">Hot Posts</a></div> <li class="nav-item"> <a class="nav-link" href="{{ url_for('frontend.logout') }}">Logout</a> </li> diff --git a/frontend/application/templates/sidebar.html b/frontend/application/templates/sidebar.html index 790b9ef1f19c05605cfaed811a3f05a5399df83a..31a90de34b4e50312cf59a8bab0effbd113c9ec4 100644 --- a/frontend/application/templates/sidebar.html +++ b/frontend/application/templates/sidebar.html @@ -44,7 +44,6 @@ <li class="list-group-item"> <div class="h6 text-muted">Categories</div> <ul class="category-menu"> - <p class="title__category" >{{category}}</p> {% for category in categories %} <li class="tile__category"> <a class="btn btn--link" href="{{ url_for('frontend.categories', category=category) }}" >{{category}}</a> diff --git a/post-service/application/post_api/routes.py b/post-service/application/post_api/routes.py index 695e7fbbeee2bf3d670fecead7ca0ed3a96ffd98..4f4d0bcdf3e3e644ead948570b1d5a03ac243d61 100644 --- a/post-service/application/post_api/routes.py +++ b/post-service/application/post_api/routes.py @@ -4,7 +4,8 @@ from . import post_api_blueprint from .. import db from ..models import Post, Comment from .api.UserClient import UserClient - +from datetime import datetime, timedelta +from sqlalchemy import desc, func @post_api_blueprint.route('/api/posts/<int:per_page>/<int:offset>', methods=['GET']) def get_posts(per_page,offset): @@ -18,6 +19,28 @@ def get_posts(per_page,offset): response = jsonify(data) return response +@post_api_blueprint.route('/api/hotposts/<int:per_page>/<int:offset>', methods=['GET']) +def get_hot_posts(per_page,offset): + data = [] + + today = datetime.utcnow() + one_week_ago = today - timedelta(days=7) + + if offset == 8: + for row in Post.query.join(Post.comments).filter(Post.date_added >= one_week_ago).group_by(Post.id).order_by(desc(func.count(Comment.id))).offset(offset).limit(per_page)[:2]: + data.append(row.to_json()) + else: + for row in Post.query.join(Post.comments).filter(Post.date_added >= one_week_ago).group_by(Post.id).order_by(desc(func.count(Comment.id))).offset(offset).limit(per_page).all(): + data.append(row.to_json()) + + if data == []: + abort(404) + + print(data) + + response = jsonify(data) + return response + @post_api_blueprint.route('/api/posts/<int:user_id>', methods=['GET']) def get_user_posts(user_id): data = [] @@ -35,7 +58,6 @@ def get_category_posts(category,per_page,offset): for row in Post.query.filter_by(category=category).order_by(Post.date_added.desc()).offset(offset).limit(per_page).all(): data.append(row.to_json()) - print(data) if data == []: abort(404) diff --git a/post-service/instance/posts-service.db b/post-service/instance/posts-service.db index 4093f5fde0bcab101216b089f66979fefc2e5cba..93d2a302ab0f4ce54d8d3a21b7a1543a1dd476d3 100644 Binary files a/post-service/instance/posts-service.db and b/post-service/instance/posts-service.db differ diff --git a/user-service/instance/users-service.db b/user-service/instance/users-service.db index b2df22b256e888cef75d66e164d4116dac58be42..7de2750c041cca19b8b8c3c77797a80f0f70c58d 100644 Binary files a/user-service/instance/users-service.db and b/user-service/instance/users-service.db differ