diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$" vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index e2bf359..bab8019 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,13 +2,16 @@ <project version="4"> <component name="ChangeListManager"> <list default="true" id="3add042d-22c9-4d47-8fa0-3f0b07cdef7b" name="Default Changelist" comment=""> + <change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" /> + <change afterPath="$PROJECT_DIR$/website/application/templates/history.html" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/website/application/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/__init__.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/website/application/database.py" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/database.py" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/website/application/filters.py" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/filters.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/website/application/static/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/static/index.js" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/website/application/templates/base.html" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/templates/base.html" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/website/application/templates/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/templates/index.html" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/website/application/templates/login.html" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/templates/login.html" afterDir="false" /> <change beforePath="$PROJECT_DIR$/website/application/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/website/application/views.py" afterDir="false" /> - <change beforePath="$PROJECT_DIR$/website/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/website/main.py" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/website/messages.db" beforeDir="false" /> </list> <option name="SHOW_DIALOG" value="false" /> <option name="HIGHLIGHT_CONFLICTS" value="true" /> @@ -18,8 +21,8 @@ <component name="FileTemplateManagerImpl"> <option name="RECENT_TEMPLATES"> <list> - <option value="HTML File" /> <option value="Python Script" /> + <option value="HTML File" /> </list> </option> </component> @@ -35,6 +38,7 @@ <component name="PropertiesComponent"> <property name="DefaultHtmlFileTemplate" value="HTML File" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> + <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> <property name="last_opened_file_path" value="$PROJECT_DIR$/website/main.py" /> <property name="settings.editor.selected.configurable" value="editor.preferences.fonts.default" /> </component> @@ -185,22 +189,22 @@ <screen x="0" y="0" width="1920" height="1040" /> </state> <state x="691" y="218" key="FileChooserDialogImpl/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580858581994" /> - <state width="1893" height="292" key="GridCell.Tab.0.bottom" timestamp="1580863168118"> + <state width="947" height="68" key="GridCell.Tab.0.bottom" timestamp="1580916190984"> <screen x="0" y="0" width="1920" height="1040" /> </state> - <state width="1893" height="292" key="GridCell.Tab.0.bottom/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580863168118" /> - <state width="1893" height="292" key="GridCell.Tab.0.center" timestamp="1580863168118"> + <state width="947" height="68" key="GridCell.Tab.0.bottom/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580916190984" /> + <state width="947" height="68" key="GridCell.Tab.0.center" timestamp="1580916190984"> <screen x="0" y="0" width="1920" height="1040" /> </state> - <state width="1893" height="292" key="GridCell.Tab.0.center/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580863168118" /> - <state width="1893" height="292" key="GridCell.Tab.0.left" timestamp="1580863168118"> + <state width="947" height="68" key="GridCell.Tab.0.center/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580916190984" /> + <state width="947" height="68" key="GridCell.Tab.0.left" timestamp="1580916190984"> <screen x="0" y="0" width="1920" height="1040" /> </state> - <state width="1893" height="292" key="GridCell.Tab.0.left/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580863168118" /> - <state width="1893" height="292" key="GridCell.Tab.0.right" timestamp="1580863168118"> + <state width="947" height="68" key="GridCell.Tab.0.left/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580916190984" /> + <state width="947" height="68" key="GridCell.Tab.0.right" timestamp="1580916190984"> <screen x="0" y="0" width="1920" height="1040" /> </state> - <state width="1893" height="292" key="GridCell.Tab.0.right/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580863168118" /> + <state width="947" height="68" key="GridCell.Tab.0.right/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580916190984" /> <state width="1894" height="196" key="GridCell.Tab.1.bottom" timestamp="1580804479402"> <screen x="0" y="0" width="1920" height="1040" /> </state> @@ -225,13 +229,13 @@ <screen x="0" y="0" width="1920" height="1040" /> </state> <state x="453" y="188" key="Vcs.Push.Dialog.v2/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580862044628" /> - <state x="592" y="303" key="com.intellij.ide.util.TipDialog" timestamp="1580843827808"> + <state x="592" y="303" key="com.intellij.ide.util.TipDialog" timestamp="1580914722843"> <screen x="0" y="0" width="1920" height="1040" /> </state> - <state x="592" y="303" key="com.intellij.ide.util.TipDialog/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580843827808" /> - <state width="375" height="218" key="javadoc.popup.new" timestamp="1580863743931"> + <state x="592" y="303" key="com.intellij.ide.util.TipDialog/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580914722843" /> + <state width="375" height="218" key="javadoc.popup.new" timestamp="1580915567851"> <screen x="0" y="0" width="1920" height="1040" /> </state> - <state width="375" height="218" key="javadoc.popup.new/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580863743931" /> + <state width="375" height="218" key="javadoc.popup.new/-1920.505.1536.800/0.0.1920.1040@0.0.1920.1040" timestamp="1580915567851" /> </component> </project> \ No newline at end of file diff --git a/website/application/database.py b/website/application/database.py index d00ae22..ebcf942 100644 --- a/website/application/database.py +++ b/website/application/database.py @@ -3,7 +3,6 @@ from datetime import datetime import time - # CONSTANTS FILE = "messages.db" @@ -44,14 +43,19 @@ def _create_table(self): self.cursor.execute(query) self.conn.commit() - def get_all_messages(self, limit=100): + def get_all_messages(self, limit=100, name=None): """ returns all messages :param limit: int :return: list[dict] """ - query = f"SELECT * FROM {PLAYLIST_TABLE}" - self.cursor.execute(query) + if not name: + query = f"SELECT * FROM {PLAYLIST_TABLE}" + self.cursor.execute(query) + else: + query = f"SELECT * FROM {PLAYLIST_TABLE} WHERE NAME = ?" + self.cursor.execute(query, (name,)) + result = self.cursor.fetchall() # return messages in sorted order by date @@ -63,6 +67,14 @@ def get_all_messages(self, limit=100): return list(reversed(results)) + def get_messages_by_name(self, name, limit=100): + """ + Gets a list of messages by user name + :param name: str + :return: list + """ + return self.get_all_messages(limit, name) + def save_message(self, name, msg): """ saves the given message in the table diff --git a/website/application/static/index.js b/website/application/static/index.js index c3f0030..38522ec 100644 --- a/website/application/static/index.js +++ b/website/application/static/index.js @@ -47,10 +47,10 @@ async function load_messages() { $(function() { - $('#messages') .css({'height': (($(window).height()) * 0.8)+'px'}); + $('.msgs') .css({'height': (($(window).height()) * 0.7)+'px'}); $(window).bind('resize', function(){ - $('#messages') .css({'height': (($(window).height()) - 200)+'px'}); + $('.msgs') .css({'height': (($(window).height()) * 0.7)+'px'}); }); }); @@ -121,13 +121,12 @@ var socket = io.connect('http://' + document.domain + ':' + location.port); } ) } ) } ) - socket.on( 'disconnect', async function( msg ) { + /*socket.on( 'disconnect', async function( msg ) { var usr_name = await load_name() socket.emit( 'event', { message: usr_name + ' just left the server...', - name: usr_name } ) - }) + })*/ socket.on( 'message response', function( msg ) { add_messages(msg, true) }) @@ -139,5 +138,12 @@ window.onload = async function() { if (i == msgs.length-1) {scroll = true} add_messages(msgs[i], scroll) } - + + let name = await load_name() + if (name != ""){ + $("#login").hide(); + }else{ + $("#logout").hide(); + } + } \ No newline at end of file diff --git a/website/application/templates/base.html b/website/application/templates/base.html index bf11bbc..729a8af 100644 --- a/website/application/templates/base.html +++ b/website/application/templates/base.html @@ -53,6 +53,7 @@ float: left; color: #999; } + </style> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> @@ -70,9 +71,10 @@ <h1 class="navbar-brand" href="#">CHAT APP</h1> </button> <div class="collapse navbar-collapse" id="navbarNavAltMarkup"> <div class="navbar-nav"> - <a class="nav-item nav-link active" href="/home">Chat <span class="sr-only">(current)</span></a> - <a class="nav-item nav-link" href="/login">Login</a> - <a class="nav-item nav-link" href="/logout">Logout</a> + <a class="nav-item nav-link" href="/home">Chat <span class="sr-only">(current)</span></a> + <a class="nav-item nav-link" href="/history">History</a> + <a class="nav-item nav-link" id="login" href="/login">Login</a> + <a class="nav-item nav-link" id="logout" href="/logout">Logout</a> </div> </div> </nav> @@ -88,10 +90,8 @@ <h1 class="navbar-brand" href="#">CHAT APP</h1> {% endwith %} {% endblock %} - <div class="container"> - {% block content %} - {% endblock %} - </div> + {% block content %} + {% endblock %} <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> diff --git a/website/application/templates/history.html b/website/application/templates/history.html new file mode 100644 index 0000000..319e4b8 --- /dev/null +++ b/website/application/templates/history.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% block title %}Message History{% endblock %} + +{% block content %} + +<div class="row" style="padding-top:10px;" > + <div class="col"><hr></div> + <div class="col-auto"><p class="h3" align="center">View Message History</p></div> + <div class="col"><hr></div> +</div> +<div class="container"> + <div class="overflow-auto" class="msgs" id="messagesHistory" style="overflow-y: scroll; height:500px;"> + {% for msg in history %} + <div class="container darker"><b style="color:#000" class="left">{{msg["name"]}}</b><p> {{msg["message"]}}</p><span class="time-left">{{msg["time"]}}</span></div> + {% endfor %} + </div> +</div> +{% endblock %} \ No newline at end of file diff --git a/website/application/templates/index.html b/website/application/templates/index.html index fa0b922..3c55eb4 100644 --- a/website/application/templates/index.html +++ b/website/application/templates/index.html @@ -18,14 +18,26 @@ {% endblock %} {% block content %} -<div id="messages" class="overflow-auto" style="overflow-y: scroll; height:500px;"> +<style> + .form button:hover,.form button:active,.form button:focus { + background: #43A047; + } +</style> +<div class="row" style="padding-top:10px;" > + <div class="col"><hr></div> + <div class="col-auto"><p class="h3" align="center">Start Chatting</p></div> + <div class="col"><hr></div> </div> -<form id="msgForm" action="" method="POST" style="bottom:0; margin: 0% 0% 0% 0%;"> - <div class="input-group mb-3"> - <input type="text" class="form-control" placeholder="Message" aria-label="Message" id="msg"> - <div class="input-group-append"> - <button class="btn btn-outline-secondary" type="submit" id="sendBtn">Send</button> - </div> +<div class="container"> + <div id="messages" class="overflow-auto msgs" style="overflow-y: scroll; height:500px;"> </div> -</form> + <form id="msgForm" action="" method="POST" style="bottom:0; margin: 0% 0% 0% 0%;"> + <div class="input-group mb-3"> + <input type="text" class="form-control" placeholder="Message" aria-label="Message" id="msg"> + <div class="input-group-append"> + <button class="btn btn-success" type="submit" id="sendBtn">Send</button> + </div> + </div> + </form> +</div> {% endblock %} \ No newline at end of file diff --git a/website/application/templates/login.html b/website/application/templates/login.html index d6c0ef1..1bade41 100644 --- a/website/application/templates/login.html +++ b/website/application/templates/login.html @@ -22,19 +22,78 @@ {% endwith %} {% endblock %} - {% block content %} -<form class="form-inline" action="#" method="POST"> - <div class="form-group mb-2"> - <label for="staticName2" class="sr-only">Name</label> - <input type="text" readonly class="form-control-plaintext" id="staticName2" value="Enter Your Name"> - </div> - <div class="form-group mx-sm-3 mb-2"> - <label for="inputName" class="sr-only">Name</label> - <input type="text" class="form-control" name="inputName" id="inputName" placeholder="First Name"> +<style type="text/css"> +@import url(https://fonts.googleapis.com/css?family=Roboto:300); + +.login-page { + width: 360px; + padding: 8% 0 0; + margin: auto; +} +.form { + position: relative; + z-index: 1; + background: #FFFFFF; + max-width: 360px; + margin: 0 auto 100px; + padding: 45px; + text-align: center; + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); +} +.form input { + font-family: "Roboto", sans-serif; + outline: 0; + background: #f2f2f2; + width: 100%; + border: 0; + margin: 0 0 15px; + padding: 15px; + box-sizing: border-box; + font-size: 14px; +} +.form button { + text-transform: uppercase; + outline: 0; + width: 100%; + border: 0; + padding: 15px; + color: #FFFFFF; + font-size: 14px; + -webkit-transition: all 0.3 ease; + transition: all 0.3 ease; + cursor: pointer; +} +.form button:hover,.form button:active,.form button:focus { + background: #43A047; +} +.form .message { + margin: 15px 0 0; + color: #b3b3b3; + font-size: 12px; +} +.container { + position: relative; + z-index: 1; + max-width: 300px; + margin: 0 auto; +} +.container:before, .container:after { + content: ""; + display: block; + clear: both; +} + +</style> + +<div class="login-page"> + <div class="form"> + <form class="login-form" action="#" method="POST"> + <input type="text" name="inputName" id="inputName" placeholder="Your Name"/> + <button type="submit" class="btn btn-success mb-2">Submit</button> + </form> </div> - <button type="submit" class="btn btn-primary mb-2">Submit</button> -</form> +</div> <script type="text/javascript" src="{{ url_for('static', filename='index.js') }}"></script> {% endblock %} \ No newline at end of file diff --git a/website/application/views.py b/website/application/views.py index 5377765..4be054d 100644 --- a/website/application/views.py +++ b/website/application/views.py @@ -9,13 +9,9 @@ NAME_KEY = 'name' MSG_LIMIT = 20 - -# GLOBAL VARS -client = None - - # VIEWS + @view.route("/login", methods=["POST","GET"]) def login(): """ @@ -53,14 +49,23 @@ def home(): displays home page if logged in :return: None """ - global client - if NAME_KEY not in session: return redirect(url_for("views.login")) return render_template("index.html", **{"session": session}) +@view.route("/history") +def history(): + if NAME_KEY not in session: + flash("0Please login before viewing message history") + return redirect(url_for("views.login")) + + json_messages = get_history(session[NAME_KEY]) + print(json_messages) + return render_template("history.html", **{"history":json_messages}) + + @view.route("/get_name") def get_name(): """ @@ -79,17 +84,40 @@ def get_messages(): """ db = DataBase() msgs = db.get_all_messages(MSG_LIMIT) + messages = remove_seconds_from_messages(msgs) + + return jsonify(messages) + + +@view.route("/get_history") +def get_history(name): + """ + :param name: str + :return: all messages by name of user + """ + db = DataBase() + msgs = db.get_messages_by_name(name) + messages = remove_seconds_from_messages(msgs) + + return messages + + +# UTILITIES +def remove_seconds_from_messages(msgs): + """ + removes the seconds from all messages + :param msgs: list + :return: list + """ messages = [] for msg in msgs: message = msg message["time"] = remove_seconds(message["time"]) messages.append(message) - return jsonify(msgs) + return messages -# UTILITIES - def remove_seconds(msg): """ :return: string with seconds trimmed off diff --git a/website/messages.db b/website/messages.db deleted file mode 100644 index 7f9c753..0000000 Binary files a/website/messages.db and /dev/null differ