diff --git a/DirectReport/browserview/app.py b/DirectReport/browserview/app.py index d725fe9d..78aedc66 100644 --- a/DirectReport/browserview/app.py +++ b/DirectReport/browserview/app.py @@ -1,41 +1,22 @@ #!/usr/bin/env python3 - +import flask # Flask - -from flask import Flask, render_template, request, redirect, jsonify, json - -# OpenAI - +from flask import Flask, render_template, request, redirect, jsonify, json, url_for +from werkzeug.security import generate_password_hash, check_password_hash +from DirectReport.models.user_model import User, UserModel +from flask_login import LoginManager, login_user, login_required, current_user +# OpenAI import openai -import secrets +import appsecrets import prompts -# -# from transformers import AutoModelForCausalLM -# from transformers import pipeline -# import torch -# from transformers import AutoModelForCausalLM, AutoTokenizer -# - -# def test(): -# access_token = "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" -# -# # torch.set_default_device('cuda') -# model = AutoModelForCausalLM.from_pretrained("microsoft/phi-1_5", trust_remote_code=True, torch_dtype="auto") -# tokenizer = AutoTokenizer.from_pretrained("microsoft/phi-1_5", trust_remote_code=True, torch_dtype="auto") -# inputs = tokenizer('''```python -# def print_prime(n): -# """ -# Print all primes between 1 and n -# """''', return_tensors="pt", return_attention_mask=False) -# -# outputs = model.generate(**inputs, max_length=200) -# text = tokenizer.batch_decode(outputs)[0] -# print(text) - - -openai.api_key = secrets.SECRET_KEY +openai.api_key = appsecrets.SECRET_KEY +login_manager = LoginManager() app = Flask(__name__, template_folder="templates") +app.secret_key = appsecrets.SECRET_KEY +login_manager.init_app(app) +login_manager.login_view = "login" +user_model = UserModel() @app.route("/") def home(): @@ -43,7 +24,6 @@ def home(): Renders the homepage of the web application. :return: Rendered HTML template for the homepage. """ - #test() return render_template('index.html', title='Home') @app.errorhandler(404) @@ -56,10 +36,62 @@ def page_not_found(e): """ return render_template('404.html', error=e), 404 +@app.route('/signup') +def signup(): + return render_template('signup.html') + +@app.route('/signup', methods=['POST']) +def signup_post(): + # code to validate and add user to database goes here + email = request.form.get('email') + name = request.form.get('name') + passwordtext = request.form.get('password') + password = generate_password_hash(passwordtext) + user_model.insert_user(name, email, password) + return redirect(url_for('login')) + +@app.route('/login', methods=['POST', 'GET']) +def login(): + email = request.form.get('email') + password = request.form.get('password') + # remember = True if request.form.get('remember') else False + user = user_loader(email) + if request.method == 'POST': + login_user(user, remember=True, force=True) + if current_user.is_authenticated(): + return redirect(url_for('account')) + return render_template('login.html') + +@login_manager.user_loader +def user_loader(email): + user = user_model.get_user_by_email(email) + return user + + +@login_manager.request_loader +def request_loader(request): + email = request.form.get('email') + user = user_model.get_user_by_email(email) + user.id = email + return user + @app.route("/account", methods=['GET', 'POST']) +@login_required def account(): + print(current_user.is_authenticated()) return render_template('account.html', title='Account') +@login_manager.unauthorized_handler +def unauthorized_handler(): + print("unauthorized_handler") + if request.headers.get("X-Requested-With") == "XMLHttpRequest": + return redirect(url_for('login')) + else: + if current_user.is_authenticated: + return redirect(url_for('account')) + else: + return redirect(url_for('login')) + @app.route("/teamreport", methods=['GET', 'POST']) def team_report(): if request.method == "POST": @@ -169,7 +201,6 @@ def generate_email(data): max_tokens=1000, frequency_penalty=0.0 ) - print(response) return response diff --git a/DirectReport/browserview/templates/login.html b/DirectReport/browserview/templates/login.html new file mode 100644 index 00000000..1b1359de --- /dev/null +++ b/DirectReport/browserview/templates/login.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block content %} +
+

Login

+
+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+{% endblock %} \ No newline at end of file diff --git a/DirectReport/browserview/templates/signup.html b/DirectReport/browserview/templates/signup.html new file mode 100644 index 00000000..dd3d5fb0 --- /dev/null +++ b/DirectReport/browserview/templates/signup.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} + +{% block content %} +
+

Sign Up

+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+{% endblock %} \ No newline at end of file diff --git a/DirectReport/models/user_model.py b/DirectReport/models/user_model.py new file mode 100644 index 00000000..14ab1d83 --- /dev/null +++ b/DirectReport/models/user_model.py @@ -0,0 +1,70 @@ +import sqlite3 +import uuid +from flask_login import UserMixin + +class User(UserMixin): + def __init__(self, id, user_name, email, password): + self.id = email + self.user_name = user_name + self.email = email + self.password = password + self.authenticated = True + + def is_active(self): + return True + + def is_anonymous(self): + return False + + def is_authenticated(self): + return self.authenticated + + def is_active(self): + return True + + def get_id(self): + return self.id + +class UserModel: + def __init__(self, db_name="users.db"): + self.conn = sqlite3.connect(db_name, check_same_thread=False) + self.create_table() + + def create_table(self): + c = self.conn.cursor() + c.execute(""" + CREATE TABLE IF NOT EXISTS users ( + id TEXT NOT NULL, + user_name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL PRIMARY KEY, + password TEXT NOT NULL + ) + """) + self.conn.commit() + + def insert_user(self, user_name, email, password): + cursor = self.conn.cursor() + uuid_str = str(uuid.uuid4()) + try: + cursor.execute("INSERT INTO users (id, user_name, email, password) VALUES (?, ?, ?, ?)", (uuid_str, user_name, email, password)) + self.conn.commit() + print("User added successfully!") + except sqlite3.IntegrityError: + print("Error: Email already exists.") + + def get_user_by_email(self, email): + cursor = self.conn.cursor() + cursor.execute("SELECT id, user_name, email, password FROM users WHERE email=?", (email,)) + result = cursor.fetchone() + print(result) + if result: + return User(result[0], result[1], result[2], result[3]) + return None + + def get_all_users(self): + cursor = self.conn.cursor() + cursor.execute("SELECT id, user_name, email FROM users") + return cursor.fetchall() + + def close(self): + self.conn.close() diff --git a/Makefile b/Makefile index 2fdbea74..21ebd440 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ TMPREPO=/tmp/docs/DirectReport ######### develop: ## install dependencies and build library python3 -m pip install Flask --user + python3 -m pip install Flask-Login --user python3 -m pip install -e .[develop] build: ## build the python library diff --git a/prompts.py b/prompts.py index e69de29b..9ced2af8 100644 --- a/prompts.py +++ b/prompts.py @@ -0,0 +1,4 @@ +global GENERATE_EMAIL_PROMPT_PREFIX +global GENERATE_SUMMARY_PROMPT_PREIX +GENERATE_EMAIL_PROMPT_PREFIX = "can you take this data and summarize in professional manner for an email on the team status for my manager?\n" + "Data: " +GENERATE_SUMMARY_PROMPT_PREIX = "can you provide a short summary of what the team as a whole accomplished this week as well as an individual breakdown based on the following list of team members and work using the following" + "Format: \n" + "{ \n" + "'team'" + ": [{" + "\n 'name'" + ": '', " + "\n 'accomplishments'" + ": '' " + " ," + "\n 'commits'" + ": '' \n" + "}]," + "\n'report'" + ": {" + "\n 'summary'" + ": " + "\n 'highlights'" + ": [{" + "\n 'title'" + ": '' ," + "\n 'description'" + ": '' "+ "\n }], \n" + " 'conclusion'" + ": ''" + "\n}" + "\n}" + "\n" + "Data:" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 5f5eba01..c5878aae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ requires = [ "Flask", "click", "openai", + "Flask-Login", "python-Levenshtein", "pytest" ]