article

Showing posts with label python Eel. Show all posts
Showing posts with label python Eel. Show all posts

Thursday, October 20, 2022

Python Desktop App Admin using python eel

Python Desktop App Admin using python eel

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
https://github.com/ChrisKnott/Eel

Install
pip install eel
C:\python_dev\crud>pip install eel

Install PyAutoGUI
https://pypi.org/project/PyAutoGUI/
pip install PyAutoGUI
C:\python_dev\crud>pip install PyAutoGUI

Download 
Bootstrap admin 
https://startbootstrap.com/

main.py
#main.py
import eel
import pyautogui #https://pypi.org/project/PyAutoGUI/
 
eel.init('views')
    
@eel.expose
def new_window(target: str):
    eel.show(f"html/{target}")
    
eel.start(
    'templates/index.html',
    size=pyautogui.size(),
    jinja_templates='templates'
)
#C:\python_dev\admin> python -m eel main.py views --onefile --icon=logo.ico --noconsole 
Make your Front-end HTML CSS and Javascript
admin\views\templates\index.html
//admin\views\templates\index.html
{% extends "base.html" %}

{% block content %}
    <div id="wrapper">
        {% include "sidebar.html" %}
    </div>   
{% endblock %}
admin\views\templates\base.html
//admin\views\templates\base.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
	
	<link href="../vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
	
    <link rel="stylesheet" href="../css/sb-admin-2.min.css">
    <link rel="icon" href="../img/myglogo.png">
    <title>Python Admin</title>
</head>
<body>
  {% block content %}
  {% endblock %}

    <!-- Bootstrap core JavaScript-->
    <script src="../vendor/jquery/jquery.min.js"></script>
    <script src="../vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

    <!-- Core plugin JavaScript-->
    <script src="../vendor/jquery-easing/jquery.easing.min.js"></script>

    <!-- Custom scripts for all pages-->
    <script src="../js/sb-admin-2.min.js"></script>

    <!-- Page level plugins -->
    <script src="../vendor/chart.js/Chart.min.js"></script>

    <!-- Page level custom scripts -->
    <script src="../js/demo/chart-area-demo.js"></script>
    <script src="../js/demo/chart-pie-demo.js"></script>	
    <script>
        function link(target) {
            window.location.href=target;
        }
    </script>
</body>
</html>
admin\views\templates\buttons.html
//admin\views\templates\buttons.html
{% extends "base.html" %}

{% block content %}
	buttons.html
{% endblock %}
admin\views\templates\sidebar.html Run : C:\python_dev\crud>python main.py

pytinstaller exe file
C:\python_dev\admin> python -m eel main.py views --onefile --icon=logo.ico --noconsole

Saturday, October 15, 2022

Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel

Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
https://github.com/ChrisKnott/Eel

Install
pip install eel
C:\python_dev\crud>pip install eel

Install PyAutoGUI
https://pypi.org/project/PyAutoGUI/
pip install PyAutoGUI
C:\python_dev\crud>pip install PyAutoGUI

Create Database sqlite3 using python

createdb.py
 
//createdb.py
import sqlite3
from sqlite3 import Error 
  
def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
  
  
if __name__ == '__main__':
    create_connection(r"C:\python_dev\crud\views\database\storage.db")
run
C:\python_dev\crud>python createdb.py

Create Database Table

CREATE TABLE tblemployee (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR (150),
position VARCHAR (150),
office VARCHAR (150)

);
main.py
 
#main.py
import eel
from views.models.employee import showallrecords, save_newemployee, show_selectedEmployee, update_newemployee, show_deleteEmployee
import pyautogui #https://pypi.org/project/PyAutoGUI/
 
eel.init('views')
  
@eel.expose
def fetchalldata():
    select_reg = showallrecords()
    eel.action_out(select_reg)
 
@eel.expose 
def btn_save(name, position, office):
    msg = save_newemployee(name, position, office)
    eel.save_return(str(msg))

@eel.expose
def get_employee(id):
    select_employee = show_selectedEmployee(id)
    eel.action_edit(select_employee)
    
@eel.expose 
def btn_update(name, position, office, id):
    msg = update_newemployee(name, position, office, id)
    eel.update_return(str(msg))    

@eel.expose
def get_delete_employee(id):
    select_del_employee = show_deleteEmployee(id)
    eel.delete_return(select_del_employee)
    
eel.start(
    'templates/index.html',
    size=pyautogui.size()
)
employee.py
 
#employee.py
import sqlite3
 
def showallrecords():
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblemployee")
        registers = []
        for item in cursor.fetchall():
            #test = item[1]
            #print(test)
            registers.append(item)
        return registers
    except Exception as error:
        print(error)
        msg = "Error"
        return msg
        
def save_newemployee(name, position, office):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()

        if name != "" and position != "" and office != "":
            cursor.execute("INSERT INTO tblemployee(name, position, office) VALUES(?,?,?)",(name, position, office))
            connect.commit()
            connect.close()
            msg = "success"
            return msg
        else:
            msg = "failure"
            return msg
    except Exception as Error:
        print(Error)
        msg = "failure"
        return msg
 
def show_selectedEmployee(id):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblemployee WHERE id =?", (id,))
        editemployees = []
        for item in cursor.fetchone():
            editemployees.append(item)
        return editemployees

    except Exception as error:
        print(error)
        msg = "Error"
        return msg

def update_newemployee(name, position, office, id):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()

        if name != "" and position != "" and office != "":
            cursor.execute("UPDATE tblemployee SET name =?, position =?, office =? WHERE id =?",
                             (name, position, office, id,))
            connect.commit()
            connect.close()
            msg = "success"
            return msg
        else:
            msg = "failure"
            return msg
    except Exception as Error:
        print(Error)
        msg = "failure"
        return msg
        
def show_deleteEmployee(id):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("DELETE FROM tblemployee WHERE id =?", (id,))
        connect.commit()
        connect.close()
        msg = "success"
        return msg
            
    except Exception as error:
        print(error)
        msg = "Error"
        return msg
Make your Front-end HTML CSS and Javascript
crud\views\templates\index.html
 
//crud\views\templates\index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="../css/index.css">
    <link rel="icon" href="../img/myglogo.png">
    <title>Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel</title>
</head>
<body>
<div class="container">
<p style="text-align:center;"><h2>Python Desktop App CRUD (Create Read Update and Delete ) sqlite3 using python eel</h2></p>
<p style="text-align:right;"><button type="button" class="btn" id="btn_addnew">Add New</button></p>
<table id="employeedatatable" class="styled-table">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Action</th>
    </tr>
</table> 

<div class="modalContainer" id="Addnewmodal">
  <div class="modal-content">
    <span id="close" class="close">×</span>
	<p style="text-align:center;"><h2>Add New Employee</h2></p>
    <form class="form-detail" action="#" method="post" id="myform">
        <div class="form-row">
            <label>Full Name:</label> 
            <input type="text" name="txtfullname" id="txtfullname" class="input-text" required placeholder="ex: Cairocoders Ednalan">
        </div>
        <div class="form-row">
            <label>Position:</label>
            <input type="text" name="txtposition" id="txtposition" class="input-text" required>
        </div>
        <div class="form-row">
            <label>Office:</label>
            <input type="text" name="txtoffice" id="txtoffice" class="input-text" required>
        </div>
        <div class="form-row-last">
            <input type="submit" name="register" class="button" value="Add New Employee" onclick="save_register_js();">
        </div>
        <div class="box"><label class="label_input" id="return_register" style="width: 90%;color:green;font-weight:bold;"></label></div>
    </form>
  </div>
</div>

<div class="modalContainer" id="Edit_modal">
  <div class="modal-content">
    <span id="close" class="closeedit">×</span>
	<p style="text-align:center;"><h2>Edit Employee</h2></p>
    <form class="form-detail" action="#" method="post" id="myformedit"><input type="hidden" name="id" id="id">
        <div class="form-row">
            <label>Full Name:</label> 
            <input type="text" name="edit_name" id="edit_name" class="input-text" required>
        </div>
        <div class="form-row">
            <label>Position:</label>
            <input type="text" name="edit_position" id="edit_position" class="input-text" required>
        </div>
        <div class="form-row">
            <label>Office:</label>
            <input type="text" name="edit_office" id="edit_office" class="input-text" required>
        </div>
        <div class="form-row-last">
            <input type="submit" name="register" class="button" value="Update" onclick="save_edit();">
        </div>
        <div class="box"><label class="label_input" id="return_update" style="width: 90%;color:green;font-weight:bold;"></label></div>
    </form>
  </div>
</div>

<div class="modalContainer" id="Delete_modal">
  <div class="modal-content">
    <span id="close" class="closedelete">×</span>
	<p style="text-align:center;"><h2>Delete Employee</h2></p>
	<p style="text-align:center;"><h3>Are you sure you want to delete this data?</h3></p>
	<div class="form-detail">
	<input type="hidden" name="idvalue" id="idvalue"> 
	<input type="submit" name="btndelete" class="button" value="Delete" onclick="btn_submitdelete($('#idvalue').val());">
	<div class="box"><label class="label_input" id="return_delete" style="width: 90%;color:green;font-weight:bold;"></label></div>
	</div>
  </div>
</div>

</div>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.validate.min.js"></script>
<script type="text/javascript" src="../js/main.js"></script>
</body>
</html>
crud\views\js\main.js
 
#crud\views\js\main.js
$(document).ready(function(){
    eel.fetchalldata()
	
  $("#btn_addnew").on("click", function() {
    $("#Addnewmodal").show();
  });
  $(".close").on("click", function() {
    $("#Addnewmodal").hide();
  });
  
  $(".closeedit").on("click", function() {
    $("#Edit_modal").hide();
  });  
  $(".closedelete").on("click", function() {
    $("#Delete_modal").hide();
  });
})
  
function link(target) {
    window.location.href=target;
}

eel.expose(action_out)
function action_out(registers){ 
    //alert("Show Table");
    registers.forEach(showdata)
}

eel.expose(action_edit)
function action_edit(editemployees){ 
   //alert(editemployees);
   editemployees.forEach(get_array_values)
}

function get_array_values(item, index){
	//alert(item);
	//alert(index);
	if (index == 0) {
		document.getElementById("id").value = item;
	} else if (index == 1) {
		document.getElementById("edit_name").value = item;
	} else if (index == 2) {
		document.getElementById("edit_position").value = item;
	} else if (index == 3) {
		document.getElementById("edit_office").value = item;
	}
	else {}

}
// SAVE 
async function save_edit(){
    $( "#myformedit" ).validate({
        messages: {
            edit_name: {
                required: "Please provide Name"
            },
            edit_position: {
                required: "Please provide Position"
            },
            edit_office: {
                required: "Please provide Office"
            },
        },
        submitHandler: function(form) {
            eel.btn_update($('#edit_name').val(),$('#edit_position').val(),$('#edit_office').val(),$('#id').val())
			//alert("Success");
        }
    });
}
		
function showdata(item, index){
    var get_table = document.getElementById("employeedatatable");
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    var td2 = document.createElement("td");
    var td3 = document.createElement("td");
    var td4 = document.createElement("td");
    var td5 = document.createElement("td");
	
	var id = item[0]
    td.innerText = item[0]
    td2.innerText = item[1]
    td3.innerText = item[2]
    td4.innerText = item[3]
        
    td5.innerHTML = '<button type="button" class="btn" onclick="btn_edit('+ id +')">Edit</button> | <button type="button" class="btndelete" onclick="buttondelete(('+ id +'))">Delete</button>'
        
    get_table.appendChild(tr)
    tr.appendChild(td)
    tr.appendChild(td2)
    tr.appendChild(td3)
    tr.appendChild(td4)
    tr.appendChild(td5)
}
    
// NEW Employee
async function save_register_js(){
    $( "#myform" ).validate({
            messages: {
                txtfullname: {
                    required: "Please provide Name"
                },
                txtposition: {
                    required: "Please provide Position"
                },
                txtoffice: {
                    required: "Please provide Office"
                },
            },
            submitHandler: function(form) {
                eel.btn_save($('#txtfullname').val(),$('#txtposition').val(),$('#txtoffice').val())
            }
    });
};
	
eel.expose(save_return); 
function save_return(status){
    if (status == "success"){
        $('#return_register').text('New Employee completed successfully!');
        $('#txtfullname').val('');
        $('#txtposition').val('');
        $('#txtoffice').val('');
    }
    if (status == "failure"){
        $('#return_register').text('Error when registering, make sure you have no blank fields.');
    }
};
	
eel.expose(edit_return); 
function edit_return(status){
    if (status == "success"){
        $('#return_register').text('Employee Updated successfully!');
    }
    if (status == "failure"){
        $('#return_register').text('Error when updating, make sure you have no blank fields.');
    }
};
  
function buttondelete(id)
{
	document.getElementById("idvalue").value = id;
	$("#Delete_modal").show();
}

async function btn_edit(id){ 
	eel.get_employee(id)
    $("#Edit_modal").show();
}

async function btn_submitdelete(id){ 
	//alert(id);
	eel.get_delete_employee(id)
}

eel.expose(update_return); 
function update_return(status){
    if (status == "success"){
        $('#return_update').text('Employee Updated successfully!');
        $('#txtfullname').val('');
        $('#txtposition').val('');
        $('#txtoffice').val('');
    }
    if (status == "failure"){
        $('#return_update').text('Error when updating record, make sure you have no blank fields.');
    }
};

eel.expose(delete_return)
function delete_return(delemployees){ 
   alert(delemployees);
    if (status == "success"){
        location.href = "index.html";
    }
    if (status == "failure"){
        $('#return_delete').text('Error deleting record');
    }
}
crud\views\css\index.css
//crud\views\css\index.css
body {
    color: #162D5D;
    font-family: 'Roboto', sans-serif;
}
.container {margin:30px;}
.styled-table {
    border-collapse: collapse;width:100%;
    margin: 25px 0;
    font-size: 0.9em;
    font-family: sans-serif;
    min-width: 400px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.styled-table thead tr {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
}
.styled-table th,
.styled-table td {
    padding: 12px 15px;
}
.styled-table tr {
    border-bottom: 1px solid #dddddd;
}
.styled-table tr:nth-of-type(even) {
    background-color: #f3f3f3;
}
.styled-table tr:last-of-type {
    border-bottom: 2px solid #009879;
}
.btn {
    background-color: #04AA6D!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
.btndelete {
    background-color: #cf2e2e!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
.form-detail .form-row label.error {
    color: red;
}
.form-detail .input-text {
	margin-bottom: 27px;
}
.form-detail input {
	width: 91%;
    padding: 14.5px 15px;
    border: 1px solid #e5e5e5;
    border-radius: 5px;
    -o-border-radius: 5px;
    -ms-border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    appearance: unset;
    -moz-appearance: unset;
    -webkit-appearance: unset;
    -o-appearance: unset;
    -ms-appearance: unset;
    outline: none;
    -moz-outline: none;
    -webkit-outline: none;
    -o-outline: none;
    -ms-outline: none;
    font-family: 'Roboto', sans-serif;
    font-size: 16px;
    color: #333;
}
.form-detail .form-row input:focus {
	border: 1px solid #53c83c;
}
.form-detail .button {
	background: #3b63ca;
	border-radius: 6px;
	-o-border-radius: 6px;
	-ms-border-radius: 6px;
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	width: 160px;
	border: none;
	margin: 6px 0 50px 0px;
	cursor: pointer;
	font-family: 'Roboto', sans-serif;
	color: #fff;
	font-weight: 500;
	font-size: 16px;
}
.form-detail .button:hover {
	background: #3356b0;
}
.modalContainer {
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(0, 0, 0);
  background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
  background-color: #fefefe;
  margin: 15% auto;
  padding: 20px;
  border: 1px solid #888;
  width: 40%;
}

#close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
  cursor: pointer;
}
Jquery
https://jquery.com/download/
CDN : jsDelivr CDN
https://www.jsdelivr.com/package/npm/jquery
https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js

jQuery Validation
http://jqueryvalidation.org/

Run : C:\python_dev\crud>python main.py

Tuesday, September 20, 2022

Python Desktop App Fetch All Records sqlite3 using python eel

Python Desktop App Fetch All Records sqlite3 using python eel

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
https://github.com/ChrisKnott/Eel

Install
pip install eel
C:\python_dev\table>pip install eel

Install PyAutoGUI
https://pypi.org/project/PyAutoGUI/
pip install PyAutoGUI
C:\python_dev\table>pip install PyAutoGUI

Create Database sqlite3 using python

createdb.py
 
#createdb.py
import sqlite3
from sqlite3 import Error 
 
def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
 
 
if __name__ == '__main__':
    create_connection(r"C:\python_dev\table\views\database\storage.db")
run
C:\python_dev\table>python createdb.py
main.py
 
#main.py
import eel
from views.models.fetchdata import showallrecords
import pyautogui #https://pypi.org/project/PyAutoGUI/

eel.init('views')
 
@eel.expose
def get_registers():
    select_reg = showallrecords()
    eel.action_out(select_reg)
    
eel.start(
    'index.html',
    size=pyautogui.size()
)
Create Table

CREATE TABLE tblemployee (

id INTEGER PRIMARY KEY AUTOINCREMENT,

name VARCHAR (150),

position VARCHAR (150),

office VARCHAR (150)

);


table\views\models\fetchdata.py
 
#table\views\models\fetchdata.py
import sqlite3

def showallrecords():
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblemployee")
        registers = []
        for item in cursor.fetchall():
            #test = item[1]
            #print(test)
            registers.append(item)
        return registers
    except Exception as error:
        print(error)
        msg = "Error"
        return msg
Make your Front-end HTML CSS and Javascript
table\views\index.html
//table\views\index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="css/index.css">
    <link rel="icon" href="img/myglogo.png">
    <title>Python Registration</title>
</head>
<body>
<div class="container">
<p style="text-align:center;"><h2>Python Desktop App Fetch All Records sqlite3 using python eel</h2></p>
<p style="text-align:right;"><button type="button" class="btn">Add New</button></p>
<table id="employeedatatable" class="styled-table">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Action</th>
    </tr>
</table> 
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script>
    $(document).ready(function(){
		eel.get_registers()
    })
		
	eel.expose(action_out)
    function action_out(registers){ 
		//alert("Show Table");
        registers.forEach(showdata)
    }
		
    function showdata(item, index){
		var get_table = document.getElementById("employeedatatable");
        var tr = document.createElement("tr");
        var td = document.createElement("td");
		var td2 = document.createElement("td");
		var td3 = document.createElement("td");
		var td4 = document.createElement("td");
		var td5 = document.createElement("td");

        td.innerText = item[0]
        td2.innerText = item[1]
        td3.innerText = item[2]
        td4.innerText = item[3]
				
        td5.innerHTML = '<button type="button" class="btn" onclick="buttonedit()">Edit</button> | <button type="button" class="btndelete" onclick="buttondelete()">Delete</button>'
        //td5.className = "acoes"
        //td5.setAttribute("onclick","actions(this, 'documents');")
				
        get_table.appendChild(tr)
        tr.appendChild(td)
		tr.appendChild(td2)
		tr.appendChild(td3)
		tr.appendChild(td4)
		tr.appendChild(td5)
    }
	function buttonedit()
	{
	  alert("Edit Records")
	}	
	function buttondelete()
	{
		if(confirm("Are you sure you want to delete this?")) {
			alert("Successfully Deleted");
		}else{
			return false;
		}
	}

</script>
</body>
</html>
table\views\css\index.css
//table\views\css\index.css
.container {margin:30px;}
.styled-table {
    border-collapse: collapse;width:100%;
    margin: 25px 0;
    font-size: 0.9em;
    font-family: sans-serif;
    min-width: 400px;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.styled-table thead tr {
    background-color: #009879;
    color: #ffffff;
    text-align: left;
}
.styled-table th,
.styled-table td {
    padding: 12px 15px;
}
.styled-table tr {
    border-bottom: 1px solid #dddddd;
}
.styled-table tr:nth-of-type(even) {
    background-color: #f3f3f3;
}
.styled-table tr:last-of-type {
    border-bottom: 2px solid #009879;
}
.btn {
    background-color: #04AA6D!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
.btndelete {
    background-color: #cf2e2e!important;
    border-radius: 5px;color:#ffffff;
    font-size: 17px;
    font-family: 'Source Sans Pro', sans-serif;
    padding: 6px 18px;
}
Run C:\python_dev\table>python main.py

Sunday, September 18, 2022

Python Desktop App Login Registration Form with sqlite3 and Password Hash

Python Desktop App Login Registration Form with sqlite3 and Password Hash

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
https://github.com/ChrisKnott/Eel

Install
pip install eel
C:\python_dev\login_register>pip install eel

Create Database sqlite3 using python

createdb.py
 
#createdb.py
import sqlite3
from sqlite3 import Error 
  
def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
  
  
if __name__ == '__main__': 
    create_connection(r"C:\python_dev\login_register\views\database\storage.db")
run
C:\python_dev\registration>createdb.py

Install PyAutoGUI

PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

pip install PyAutoGUI
C:\python_dev\registration>pip install PyAutoGUI

Install werkzeug

pip install werkzeug
C:\python_dev\registration>pip install werkzeug

from werkzeug.security import generate_password_hash, check_password_hash #pip install werkzeug
main.py
 
#main.py
from __future__ import print_function
import eel
from views.models.signup import save_register
from views.models.login import login_user, login_session
import pyautogui #https://pypi.org/project/PyAutoGUI/
 
eel.init('views')
 
@eel.expose
def btn_login(user_name, password):
    msg = login_user(user_name, password)
    eel.login_return(str(msg))

@eel.expose
def get_user_online():
    get_user = login_session()
    print(get_user)
    eel.get_user(str(get_user))
    
@eel.expose 
def btn_save(name, email, passw):
    msg = save_register(name, email, passw)
    eel.save_return(str(msg))
     
eel.start(
    'index.html',
    size=pyautogui.size()
)
Create Table
CREATE TABLE tblusers (
id INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE,
name VARCHAR (150),
email VARCHAR (150),
password VARCHAR (150)
);

CREATE TABLE user_session (
id INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE,
user VARCHAR (150)
);

login_registration/views/models/signup.py
 
#registration/views/models/signup.py
import sqlite3
from werkzeug.security import generate_password_hash #pip install werkzeug
 
def save_register(name, email, passw):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        _hashed_password = generate_password_hash(passw)
        print(_hashed_password)
        
        cursor.execute("INSERT OR REPLACE INTO user_session(id) VALUES(?)", (1,))
        if name != "" and passw != "" and email != "":
            cursor.execute("INSERT INTO tblusers(name, email, password) VALUES(?,?,?)",(name, email, _hashed_password))
            connect.commit()
            connect.close()
            msg = "success"
            return msg
        else:
            msg = "failure"
            return msg
    except Exception as Error:
        print(Error)
        msg = "failure"
        return msg
login_registration/views/models/login.py
 
#registration/views/models/login.py
import sqlite3
from werkzeug.security import generate_password_hash, check_password_hash #pip install werkzeug

def login_user(user_name, password):
    #print(user_name)
    #print(password)
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT * FROM tblusers WHERE email =?", (user_name,))
        get_password = cursor.fetchone()
        password_rs = get_password[3]
        if check_password_hash(password_rs, password):
            cursor.execute("SELECT * FROM tblusers WHERE email =?", (user_name,))
            user = cursor.fetchone()
            cursor.execute("UPDATE user_session SET user =? WHERE id =?", (user[1], 1,))
            connect.commit()
            msg = "success"
            connect.close()
            return msg
        else:
            msg = "failed"
            connect.close()
            return msg

    except Exception as Error:
        print(Error)
        msg = "failed"
        return msg


def login_session():
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT user FROM user_session WHERE id =?", (1,))
        get_user_online = cursor.fetchone()
        user_online = []
        for name in get_user_online:
            user_online.append(name)
        connect.close()
        return user_online[0]
    except Exception as error:
        user_online = "error"
        print(error)
        return user_online
Make your Front-end HTML CSS and Javascript
login_registration/views/index.html
//login_registration/views/index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="css/index.css">
    <link rel="icon" href="img/password.png">
    <title>Python Login Registration</title>
</head>
<body class="form-v2">
    <div class="page-content">
		<div class="form-v2-content" id="login-form">
            <div class="form-left">
                <img src="img/form-v1.jpg" alt="form">
            </div>
            <form class="form-detail" action="#" method="post" id="myformlogin">
                <h2>Member Login</h2>
                <div class="form-row">
                    <label for="your_email">Your Email:</label>
                    <input type="text" name="loginmail" id="loginmail" class="input-text" required pattern="[^@]+@[^@]+.[a-zA-Z]{2,6}">
                </div>
                <div class="form-row">
                    <label for="password">Password:</label>
                    <input type="password" name="loginpassword" id="loginpassword" class="input-text" required>
                </div>
                <div class="form-row-last">
                    <input type="submit" name="login" class="login" value="Login" onclick="btnlogin();">
					<p>Don't have an account? <a href="#" id="register-form-link">Register</a></p>
                </div>
                 
                <div class="box"><label class="label_input" id="return_login" style="width: 90%;color:red;font-weight:bold;"></label></div>
            </form>
		</div>
        <div class="form-v2-content" id="register-form">
            <div class="form-left">
                <img src="img/form-v2.jpg" alt="form">
            </div>
            <form class="form-detail" action="#" method="post" id="myform">
                <h2>Registration Form</h2>
                <div class="form-row">
                    <label for="full-name">Full Name:</label> 
                    <input type="text" name="txtfullname" id="txtfullname" class="input-text" required placeholder="ex: Cairocoders Ednalan">
                </div>
                <div class="form-row">
                    <label for="your_email">Your Email:</label>
                    <input type="text" name="txtemail" id="txtemail" class="input-text" required pattern="[^@]+@[^@]+.[a-zA-Z]{2,6}">
                </div>
                <div class="form-row">
                    <label for="password">Password:</label>
                    <input type="password" name="password" id="password" class="input-text" required>
                </div>
                <div class="form-row">
                    <label for="comfirm-password">Confirm Password:</label>
                    <input type="password" name="confirm_password" id="confirm_password" class="input-text" required>
                </div>
                <div class="form-row-last">
                    <input type="submit" name="register" class="register" value="Register" onclick="save_register_js();">
					<p>Already Registered? <a href="#" class="active" id="login-form-link">Login</a></p>
                </div>
                 
                <div class="box"><label class="label_input" id="return_register" style="width: 90%;color:green;font-weight:bold;"></label></div>
            </form>
        </div>
    </div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
<script>
    jQuery.validator.setDefaults({
        debug: true,
        success:  function(label){
            label.attr('id', 'valid');
        },
    });
         
    // NEW USER REGISTRATION
    async function save_register_js(){
        $( "#myform" ).validate({
            rules: {
                password: "required",
                confirm_password: {
                    equalTo: "#password"
                }
            },
            messages: {
                txtfullname: {
                    required: "Please provide Name"
                },
                txtemail: {
                    required: "Please provide Email"
                },
                password: {
                    required: "Please provide Password"
                },
                confirm_password: {
                    required: "Please provide Password",
                    equalTo: "Wrong Password"
                }
            },
            submitHandler: function(form) {
                eel.btn_save($('#txtfullname').val(),$('#txtemail').val(),$('#password').val())
            }
        });
    };
    eel.expose(save_return); 
    function save_return(status){
        if (status == "success"){
            $('#return_register').text('Registration completed successfully!');
            $('#txtfullname').val('');
            $('#txtemail').val('');
            $('#password').val('');
        }
        if (status == "failure"){
            $('#return_register').text('Error when registering, make sure you have no blank fields.');
        }
    };
		
    // USER LOGIN
    async function btnlogin(){ 
        $( "#myformlogin" ).validate({
            rules: {
                loginpassword: "required"
            },
            messages: {
                loginmail: {
                    required: "Please provide Email"
                },
                loginpassword: {
                    required: "Please provide Password"
                }
            },
            submitHandler: function(form) {
                 eel.btn_login($('#loginmail').val(), $('#loginpassword').val())
            }
        });
    };

    eel.expose(login_return)
    function login_return(status){ //alert(status);
        if (status == "success"){
            location.href = "admin.html";
        }
        if (status == "failed"){ 
            $('#return_login').text("Incorrect User or Password")
        }
    }
		
	$(function() {
		$("#register-form").hide();
		$('#login-form-link').click(function(e) {
			$("#login-form").delay(100).fadeIn(100);
			$("#register-form").fadeOut(100);
			$("#register-form").hide();
			$("#login-form").show();
			e.preventDefault();
		});
		$('#register-form-link').click(function(e) {
			$("#register-form").delay(100).fadeIn(100);
			$("#login-form").fadeOut(100);
			$("#register-form").show();
			$("#login-form").hide();
			e.preventDefault();
		});

	});
</script>
</body>
</html>
login_registration/views/admin.html
//login_registration/views/admin.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="icon" href="img/password.png">
    <title>Admin</title>
</head>
<body>
    <div class="container">
		<h1 id="user_logged_id"></h1>
    </div>
	<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            eel.get_user_online()
        })
        eel.expose(get_user)
        function get_user(user){
            $('#user_logged_id').text('User logged in: '+ user)
        }
    </script>
</body>
</html>
login_registration/views/css/index.css
//login_registration/views/css/index.css
body {
	margin:  0;
}
.page-content {
	width: 100%;
	margin:  0 auto;
	background: -webkit-linear-gradient(left, #3931af, #00c6ff);
	display: flex;
	display: -webkit-flex;
	justify-content: center;
	-o-justify-content: center;
	-ms-justify-content: center;
	-moz-justify-content: center;
	-webkit-justify-content: center;
	align-items: center;
	-o-align-items: center;
	-ms-align-items: center;
	-moz-align-items: center;
	-webkit-align-items: center;
}
.form-v2-content  {
	background: #fff;
	width: 851px;
	border-radius: 15px;
	-o-border-radius: 15px;
	-ms-border-radius: 15px;
	-moz-border-radius: 15px;
	-webkit-border-radius: 15px;
	margin: 100px 0;
	position: relative;
	display: flex;
	display: -webkit-flex;
}
.form-v2-content .form-left {
	margin-bottom: -4px;
	position: relative;
}
.form-v2-content .form-left img {
	border-top-left-radius: 15px;
	border-bottom-left-radius: 15px;
}
.form-v2-content .form-left .text-1,
.form-v2-content .form-left .text-2 {
	font-family: 'Roboto', sans-serif;
	font-weight: 700;
	color: #fff;
}
.form-v2-content .form-left .text-1 {
	position: absolute;
    left: 9%;
    bottom: 15%;
}
.form-v2-content .form-left .text-2 {
	position: absolute;
    right: 8%;
    bottom: 1.5%;
}
.form-v2-content .form-left .text-1 p {
	font-size: 32px;
	line-height: 1.67;
}
.form-v2-content .form-detail {
    padding: 20px 40px 20px 40px;
	position: relative;
	width: 100%;
}
.form-v2-content .form-detail h2 {
	font-family: 'Roboto', sans-serif;
	font-weight: 700;
	color: #333;
	font-size: 28px;
	position: relative;
	padding: 6px 0 0;
	margin-bottom: 25px;
}
.form-v2-content .form-row {
    width: 100%;
    position: relative;
}
.form-v2-content .form-detail label {
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
	font-size: 16px;
	color: #666;
	display: block;
	margin-bottom: 11px;
}
.form-v2-content .form-detail .form-row label#valid {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    -o-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    width: 14px;
    height: 14px;
    border-radius: 50%;
    -o-border-radius: 50%;
    -ms-border-radius: 50%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    background: #53c83c;
}
.form-v2-content .form-detail .form-row label#valid::after {
	content: "";
    position: absolute;
    left: 5px;
    top: 1px;
    width: 3px;
    height: 8px;
    border: 1px solid #fff;
    border-width: 0 2px 2px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    -o-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    transform: rotate(45deg);
}
.form-v2-content .form-detail .form-row label.error {
	padding-left: 0;
	margin-left: 0;
    display: block;
    position: absolute;
    bottom: -10px;
    width: 100%;
    background: none;
    color: red;
}
.form-v2-content .form-detail .input-text {
	margin-bottom: 27px;
}
.form-v2-content .form-detail input {
	width: 91%;
    padding: 14.5px 15px;
    border: 1px solid #e5e5e5;
    border-radius: 5px;
    -o-border-radius: 5px;
    -ms-border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    appearance: unset;
    -moz-appearance: unset;
    -webkit-appearance: unset;
    -o-appearance: unset;
    -ms-appearance: unset;
    outline: none;
    -moz-outline: none;
    -webkit-outline: none;
    -o-outline: none;
    -ms-outline: none;
    font-family: 'Roboto', sans-serif;
    font-size: 16px;
    color: #333;
}
.form-v2-content .form-detail .form-row input:focus {
	border: 1px solid #53c83c;
}
.form-v2-content .form-detail input[type="radio"] {
	outline: none;
    -moz-outline: none;
    -webkit-outline: none;
    -o-outline: none;
    -ms-outline: none;
    -o-appearance: none;
    -ms-appearance: none;
	-webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    display: inline-block;
  	width: 20px;
  	height: 20px;
  	padding:  4px;
  	background-clip: content-box;
  	border: 1px solid #e5e5e5;
  	background-color: #fff;
  	border-radius: 50%;
  	-o-border-radius: 50%;
  	-ms-border-radius: 50%;
  	-moz-border-radius: 50%;
  	-webkit-border-radius: 50%;
  	cursor: pointer;
  	float: left;
  	margin-top: 0;
}
.form-v2-content .form-detail .register {
	background: #3b63ca;
	border-radius: 6px;
	-o-border-radius: 6px;
	-ms-border-radius: 6px;
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	width: 160px;
	border: none;
	margin: 6px 0 50px 0px;
	cursor: pointer;
	font-family: 'Roboto', sans-serif;
	color: #fff;
	font-weight: 500;
	font-size: 16px;
}
.form-v2-content .form-detail .login {
	background: #ee6c4d;
	border-radius: 6px;
	-o-border-radius: 6px;
	-ms-border-radius: 6px;
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	width: 160px;
	border: none;
	margin: 6px 0 50px 0px;
	cursor: pointer;
	font-family: 'Roboto', sans-serif;
	color: #fff;
	font-weight: 500;
	font-size: 16px;
}
.form-v2-content .form-detail .register:hover {
	background: #3356b0;
}
.form-v2-content .form-detail .form-row-last input {
	padding: 15.5px;
}
input::-webkit-input-placeholder { /* Chrome/Opera/Safari */
  color: #999;
  font-size: 14px;
}
input::-moz-placeholder { /* Firefox 19+ */
  color: #999;
  font-size: 14px;
}
input:-ms-input-placeholder { /* IE 10+ */
  color: #999;
  font-size: 14px;
}
input:-moz-placeholder { /* Firefox 18- */
  color: #999;
  font-size: 14px;
}

/* Responsive */
@media screen and (max-width: 991px) {
	.form-v2-content {
		margin: 180px 20px;
		flex-direction:  column;
		-o-flex-direction:  column;
		-ms-flex-direction:  column;
		-moz-flex-direction:  column;
		-webkit-flex-direction:  column;
	}
	.form-v2-content .form-left {
		width: 100%;
	}
	.form-v2-content .form-left img {
		width: 100%;
		border-bottom-left-radius: 0px;
	    border-top-right-radius: 15px;
	}
	.form-v2-content .form-detail {
		padding: 30px 20px 30px 20px;
	    width: auto;
	}
	.form-v2-content .form-detail .form-row input {
		width: 95%;
	}
	.form-v2-content .form-detail .form-checkbox {
		width: 100%;
	}
}
@media screen and (max-width: 575px) {
	.form-v2-content .form-detail .form-row input {
		width: 89.5%;
	}
}

#field { margin-left: .5em; float: left; }
#field, label { float: left; font-family: Arial, Helvetica, sans-serif; font-size: small; }
br { clear: both; }
input { border: 1px solid black; margin-bottom: .5em;  }
input.error { border: 1px solid red; }
label.error {
	background: url('images/unchecked.gif') no-repeat;
	padding-left: 16px;
	margin-left: .3em;
}
label.valid {
	background: url('images/checked.gif') no-repeat;
	display: block;
	width: 16px;
	height: 16px;
}
Run C:\python_dev\registration>python main.py

Friday, September 16, 2022

Python Eel Registration Form with sqlite3 and Password Hash

Python Eel Registration Form with sqlite3 and Password Hash

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
https://github.com/ChrisKnott/Eel

Install
pip install eel
C:\python_dev\login>pip install eel

Create Database sqlite3 using python
createdb.py
#createdb.py
import sqlite3
from sqlite3 import Error 
 
def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
 
 
if __name__ == '__main__':
    create_connection(r"C:\python_dev\registration\views\database\storage.db")
run
C:\python_dev\registration>createdb.py

Install PyAutoGUI

PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.

pip install PyAutoGUI
C:\python_dev\registration>pip install PyAutoGUI

Install werkzeug

pip install werkzeug
C:\python_dev\registration>pip install werkzeug

import from werkzeug.security import generate_password_hash
main.py
#main.py
from __future__ import print_function
import eel
from views.models.signup import save_register
import pyautogui #https://pypi.org/project/PyAutoGUI/

eel.init('views')

@eel.expose 
def btn_save(name, email, passw):
    msg = save_register(name, email, passw)
    eel.save_return(str(msg))
    
eel.start(
    'index.html',
    size=pyautogui.size()
)
Create Table
CREATE TABLE tblusers (
id INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE,
name VARCHAR (150),
email VARCHAR (150),
password VARCHAR (150)
);

registration/views/models/signup.py
#registration/views/models/signup.py
import sqlite3
from werkzeug.security import generate_password_hash #pip install werkzeug

def save_register(name, email, passw):
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        _hashed_password = generate_password_hash(passw)
        print(_hashed_password)
        if name != "" and passw != "" and email != "":
            cursor.execute("INSERT INTO tblusers(name, email, password) VALUES(?,?,?)",(name, email, _hashed_password))
            connect.commit()
            connect.close()
            msg = "success"
            return msg
        else:
            msg = "failure"
            return msg
    except Exception as Error:
        print(Error)
        msg = "failure"
        return msg
Make your Front-end HTML CSS and Javascript
registration/views/index.html
//registration/views/index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="css/index.css">
    <link rel="icon" href="img/password.png">
    <title>Python Registration</title>
</head>
<body class="form-v2">
	<div class="page-content">
		<div class="form-v2-content">
			<div class="form-left">
				<img src="img/form-v2.jpg" alt="form">
			</div>
			<form class="form-detail" action="#" method="post" id="myform">
				<h2>Registration Form</h2>
				<div class="form-row">
					<label for="full-name">Full Name:</label> 
					<input type="text" name="txtfullname" id="txtfullname" class="input-text" required placeholder="ex: Cairocoders Ednalan">
				</div>
				<div class="form-row">
					<label for="your_email">Your Email:</label>
					<input type="text" name="txtemail" id="txtemail" class="input-text" required pattern="[^@]+@[^@]+.[a-zA-Z]{2,6}">
				</div>
				<div class="form-row">
					<label for="password">Password:</label>
					<input type="password" name="password" id="password" class="input-text" required>
				</div>
				<div class="form-row">
					<label for="comfirm-password">Confirm Password:</label>
					<input type="password" name="confirm_password" id="confirm_password" class="input-text" required>
				</div>
				<div class="form-row-last">
					<input type="submit" name="register" class="register" value="Register" onclick="save_register_js();">
				</div>
				
				<div class="box"><label class="label_input" id="return_register" style="width: 90%;color:green;font-weight:bold;"></label></div>
			</form>
		</div>
	</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
<script>
		jQuery.validator.setDefaults({
		  	debug: true,
		  	success:  function(label){
        		label.attr('id', 'valid');
   		 	},
		});
		
        // NEW USER REGISTRATION
        async function save_register_js(){
			$( "#myform" ).validate({
				rules: {
					password: "required",
					confirm_password: {
						equalTo: "#password"
					}
				},
				messages: {
					txtfullname: {
						required: "Please provide Name"
					},
					txtemail: {
						required: "Please provide Email"
					},
					password: {
						required: "Please provide Password"
					},
					confirm_password: {
						required: "Please provide Password",
						equalTo: "Wrong Password"
					}
				},
				submitHandler: function(form) {
					eel.btn_save($('#txtfullname').val(),$('#txtemail').val(),$('#password').val())
				}
			});
        };
        eel.expose(save_return); 
        function save_return(status){
            if (status == "success"){
                $('#return_register').text('Registration completed successfully!');
                $('#txtfullname').val('');
                $('#txtemail').val('');
                $('#password').val('');
            }
            if (status == "failed"){
                $('#return_register').text('Error when registering, make sure you have no blank fields.');
            }
        };
</script>
</body>
</html>
css file registration\views\css\index.css
//registration\views\css\index.css
body {
	margin:  0;
}
.page-content {
	width: 100%;
	margin:  0 auto;
	background-image: -moz-linear-gradient( 136deg, rgb(224,195,252) 0%, rgb(142,197,252) 100%);
    background-image: -webkit-linear-gradient( 136deg, rgb(224,195,252) 0%, rgb(142,197,252) 100%);
    background-image: -ms-linear-gradient( 136deg, rgb(224,195,252) 0%, rgb(142,197,252) 100%);
	display: flex;
	display: -webkit-flex;
	justify-content: center;
	-o-justify-content: center;
	-ms-justify-content: center;
	-moz-justify-content: center;
	-webkit-justify-content: center;
	align-items: center;
	-o-align-items: center;
	-ms-align-items: center;
	-moz-align-items: center;
	-webkit-align-items: center;
}
.form-v2-content  {
	background: #fff;
	width: 851px;
	border-radius: 15px;
	-o-border-radius: 15px;
	-ms-border-radius: 15px;
	-moz-border-radius: 15px;
	-webkit-border-radius: 15px;
	margin: 100px 0;
	position: relative;
	display: flex;
	display: -webkit-flex;
}
.form-v2-content .form-left {
	margin-bottom: -4px;
	position: relative;
}
.form-v2-content .form-left img {
	border-top-left-radius: 15px;
	border-bottom-left-radius: 15px;
}
.form-v2-content .form-left .text-1,
.form-v2-content .form-left .text-2 {
	font-family: 'Roboto', sans-serif;
	font-weight: 700;
	color: #fff;
}
.form-v2-content .form-left .text-1 {
	position: absolute;
    left: 9%;
    bottom: 15%;
}
.form-v2-content .form-left .text-2 {
	position: absolute;
    right: 8%;
    bottom: 1.5%;
}
.form-v2-content .form-left .text-1 p {
	font-size: 32px;
	line-height: 1.67;
}
.form-v2-content .form-detail {
    padding: 20px 40px 20px 40px;
	position: relative;
	width: 100%;
}
.form-v2-content .form-detail h2 {
	font-family: 'Roboto', sans-serif;
	font-weight: 700;
	color: #333;
	font-size: 28px;
	position: relative;
	padding: 6px 0 0;
	margin-bottom: 25px;
}
.form-v2-content .form-row {
    width: 100%;
    position: relative;
}
.form-v2-content .form-detail label {
	font-family: 'Roboto', sans-serif;
	font-weight: 400;
	font-size: 16px;
	color: #666;
	display: block;
	margin-bottom: 11px;
}
.form-v2-content .form-detail .form-row label#valid {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    -o-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    width: 14px;
    height: 14px;
    border-radius: 50%;
    -o-border-radius: 50%;
    -ms-border-radius: 50%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    background: #53c83c;
}
.form-v2-content .form-detail .form-row label#valid::after {
	content: "";
    position: absolute;
    left: 5px;
    top: 1px;
    width: 3px;
    height: 8px;
    border: 1px solid #fff;
    border-width: 0 2px 2px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    -o-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    transform: rotate(45deg);
}
.form-v2-content .form-detail .form-row label.error {
	padding-left: 0;
	margin-left: 0;
    display: block;
    position: absolute;
    bottom: -10px;
    width: 100%;
    background: none;
    color: red;
}
.form-v2-content .form-detail .input-text {
	margin-bottom: 27px;
}
.form-v2-content .form-detail input {
	width: 91%;
    padding: 14.5px 15px;
    border: 1px solid #e5e5e5;
    border-radius: 5px;
    -o-border-radius: 5px;
    -ms-border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    appearance: unset;
    -moz-appearance: unset;
    -webkit-appearance: unset;
    -o-appearance: unset;
    -ms-appearance: unset;
    outline: none;
    -moz-outline: none;
    -webkit-outline: none;
    -o-outline: none;
    -ms-outline: none;
    font-family: 'Roboto', sans-serif;
    font-size: 16px;
    color: #333;
}
.form-v2-content .form-detail .form-row input:focus {
	border: 1px solid #53c83c;
}
.form-v2-content .form-detail input[type="radio"] {
	outline: none;
    -moz-outline: none;
    -webkit-outline: none;
    -o-outline: none;
    -ms-outline: none;
    -o-appearance: none;
    -ms-appearance: none;
	-webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    display: inline-block;
  	width: 20px;
  	height: 20px;
  	padding:  4px;
  	background-clip: content-box;
  	border: 1px solid #e5e5e5;
  	background-color: #fff;
  	border-radius: 50%;
  	-o-border-radius: 50%;
  	-ms-border-radius: 50%;
  	-moz-border-radius: 50%;
  	-webkit-border-radius: 50%;
  	cursor: pointer;
  	float: left;
  	margin-top: 0;
}
.form-v2-content .form-detail .register {
	background: #3b63ca;
	border-radius: 6px;
	-o-border-radius: 6px;
	-ms-border-radius: 6px;
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	width: 160px;
	border: none;
	margin: 6px 0 50px 0px;
	cursor: pointer;
	font-family: 'Roboto', sans-serif;
	color: #fff;
	font-weight: 500;
	font-size: 16px;
}
.form-v2-content .form-detail .register:hover {
	background: #3356b0;
}
.form-v2-content .form-detail .form-row-last input {
	padding: 15.5px;
}
input::-webkit-input-placeholder { /* Chrome/Opera/Safari */
  color: #999;
  font-size: 14px;
}
input::-moz-placeholder { /* Firefox 19+ */
  color: #999;
  font-size: 14px;
}
input:-ms-input-placeholder { /* IE 10+ */
  color: #999;
  font-size: 14px;
}
input:-moz-placeholder { /* Firefox 18- */
  color: #999;
  font-size: 14px;
}

/* Responsive */
@media screen and (max-width: 991px) {
	.form-v2-content {
		margin: 180px 20px;
		flex-direction:  column;
		-o-flex-direction:  column;
		-ms-flex-direction:  column;
		-moz-flex-direction:  column;
		-webkit-flex-direction:  column;
	}
	.form-v2-content .form-left {
		width: 100%;
	}
	.form-v2-content .form-left img {
		width: 100%;
		border-bottom-left-radius: 0px;
	    border-top-right-radius: 15px;
	}
	.form-v2-content .form-detail {
		padding: 30px 20px 30px 20px;
	    width: auto;
	}
	.form-v2-content .form-detail .form-row input {
		width: 95%;
	}
	.form-v2-content .form-detail .form-checkbox {
		width: 100%;
	}
}
@media screen and (max-width: 575px) {
	.form-v2-content .form-detail .form-row input {
		width: 89.5%;
	}
}

#field { margin-left: .5em; float: left; }
#field, label { float: left; font-family: Arial, Helvetica, sans-serif; font-size: small; }
br { clear: both; }
input { border: 1px solid black; margin-bottom: .5em;  }
input.error { border: 1px solid red; }
label.error {
	background: url('images/unchecked.gif') no-repeat;
	padding-left: 16px;
	margin-left: .3em;
}
label.valid {
	background: url('images/checked.gif') no-repeat;
	display: block;
	width: 16px;
	height: 16px;
}
Run : C:\python_dev\registration>python main.py

Saturday, September 3, 2022

Python Login with sqlite3 and Python Eel library

Python Login with sqlite3 and Python Eel library

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
https://github.com/ChrisKnott/Eel

Install
pip install eel
C:\python_dev\login>pip install eel

Create Database sqlite3 using python
createdb.py
#createdb.py
import sqlite3
from sqlite3 import Error 

def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()


if __name__ == '__main__':
    create_connection(r"C:\python_dev\login\views\database\storage.db")
run
C:\python_dev\login>createdb.py
main.py
#main.py
from __future__ import print_function
import eel
from views.models.login import login_user, login_session

eel.init('views')

@eel.expose
def btn_login(user_name, password):
    msg = login_user(user_name, password)
    eel.login_return(str(msg))

@eel.expose
def get_user_online():
    get_user = login_session()
    print(get_user)
    eel.get_user(str(get_user))
    
eel.start("index.html", size=(1366, 743))
Create table
CREATE TABLE users (
id INTEGER NOT NULL
PRIMARY KEY,
Name TEXT,
Phone NUMBER,
User TEXT,
Password TEXT,
Email TEXT,
Birth DATE
);

CREATE TABLE user_session (
id INTEGER NOT NULL
PRIMARY KEY,
User TEXT
);
login/views/models/login.py
#login/views/models/login.py
import sqlite3

def login_user(user_name, password):
    print(user_name)
    print(password)
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute(
            "SELECT Password FROM users WHERE User =?", (user_name,))
        get_password = cursor.fetchone()
        if password == get_password[0]:
            msg = "success"
            connect.close()
            return msg
        else:
            msg = "failed"
            connect.close()
            return msg

    except Exception as Error:
        print(Error)
        msg = "failed"
        return msg


def login_session():
    try:
        connect = sqlite3.connect("views/database/storage.db")
        cursor = connect.cursor()
        cursor.execute("SELECT User FROM user_session WHERE id =?", (1,))
        get_user_online = cursor.fetchone()
        user_online = []
        for name in get_user_online:
            user_online.append(name)
        connect.close()
        return user_online[0]
    except Exception as error:
        user_online = "error"
        print(error)
        return user_online
Make your Front-end HTML CSS and Javascript

login/views/index.html
//login/views/index.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="stylesheet" href="css/index.css">
    <link rel="icon" href="img/password.png">
    <title>Python Login</title>
</head>
<body class="background">
    <div class="container">
		<div class="row">
        <div class="wrap-login">
            <div class="login_label">
                <label class="label_login">Member Login</label>
            </div>
            <div class="login_user">
                <label class="label_input">User:</label>
                <input type="text" class="inputs" name="username" id="get_user_login" placeholder="Username"><br>
            </div>
            <div class="login_user">
                <label class="label_input">Password:</label>
                <input type="password" class="inputs" name="password" id="get_user_password" placeholder="* * * * * * * * *">
            </div>
            <div class="buttons_container">
                <label class="top_label" style="margin: 0 20px;">Forgot your password? Click here</label>
                <button class="buttons" onclick="btnlogin();">Confirm</button>
            </div>
            <div class="login_user" style="text-align: center;width: 100%;">
                <div id="login_txt"></div>
            </div>
        </div>
        </div>
    </div>
    <script type="text/javascript" >
        // USER LOGIN
        async function btnlogin(){ 
			//var username = $('#get_user_login').val();
			//alert(username);
            eel.btn_login($('#get_user_login').val(), $('#get_user_password').val())
        };

        eel.expose(login_return)
        function login_return(status){ //alert(status);
            if (status == "success"){
                location.href = "admin.html";
            }
            if (status == "failed"){ 
                $('#login_txt').text("Incorrect User or Password")
            }
        }
    </script>
</body>
</html>
login/views/admin.html
 
#login/views/admin.html
<!DOCTYPE html>
<html lang="pt-br">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="/eel.js"></script>
    <link rel="icon" href="img/password.png">
    <title>Admin</title>
</head>
<body>
    <div class="container">
		<h1 id="user_logged_id"></h1>
    </div>
    <script type="text/javascript">
        $(document).ready(function(){
            eel.get_user_online()
        })
        eel.expose(get_user)
        function get_user(user){
            $('#user_logged_id').text('User logged in: '+ user)
        }
    </script>
</body>
</html>
css file
 
#login/views/css/main.css
body{
    padding: 0;
    margin: 0;
}
@font-face{
    font-family: "BungeeInline-Regular";
    src: url("../fonts/BungeeInline-Regular.ttf");
}
@font-face{
    font-family: "PoiretOne-Regular";
    src: url("../fonts/PoiretOne-Regular.ttf");
}
.container{
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
.background{
display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;background:#9053c7;background:-webkit-linear-gradient(-135deg,#c850c0,#4158d0);background:-o-linear-gradient(-135deg,#c850c0,#4158d0);background:-moz-linear-gradient(-135deg,#c850c0,#4158d0);background:linear-gradient(-135deg,#c850c0,#4158d0)
}
.wrap-login{
	margin: auto;
width:560px;height:450px;background:#fff;border-radius:10px;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;flex-wrap:wrap;justify-content:space-between;
}
.row {
	padding-top:100px;
}

.login_label, .buttons_container{
    width: 100%;
    height: 10vh;
    margin: 20px auto;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
}
.label_login{
    font-family: "PoiretOne-Regular";
    font-size: 40px;
    
}
.login_user{
    width: 100%;
    height: 10vh;
    margin-top: 10px;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
}
.label_input{
    display: inline-block;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 20px;
    color: black;
    margin: 0 10px;
    width: 80px;
}
.inputs{
    background: transparent;
    border: none;
    border-bottom: 1px solid #BF3EFF;
    margin: 0 10px;
    outline: 0;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 16px;
    color:black;
    padding-left: 10px;
}
.inputs:focus{
    border-bottom:2px solid #9A32CD;
}
.buttons{
    margin: 0 20px;
    border:1px solid white;
    background:#BF3EFF ;
    color:white;
    border-radius: 3px;
    width: 120px;
    height: 40px;
    font-family: sans-serif;
    font-size: 16px;
}
.buttons:hover{
   cursor: pointer;
   background:#9A32CD ; 
}
#login_txt { color: #EC4E20; width: 100%;font-weight:bold;font-size:22px;}
Run : C:\python_dev\login>python main.py

Related Post