initial push...
This commit is contained in:
parent
d82d880a17
commit
938aaca361
41
README.md
Normal file
41
README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Dropper
|
||||
Remote Mouse is a flask + pyautogui app to control a PC from your phone or any other device.
|
||||
|
||||
# Notes
|
||||
* Need python 2+
|
||||
* Make sure to change the port in the start script as needed. Have fun!
|
||||
* For Linux you will need to do sudo -i before running the script.
|
||||
|
||||
# Setup
|
||||
*** Change directory to Remote-Mouse/ or rename the folder before doing so.
|
||||
|
||||
``` python3 -m venv venv/ ```
|
||||
|
||||
Linux/Mac
|
||||
``` source bin/activate ```
|
||||
|
||||
Windows
|
||||
``` source bin/Scripts/activate ```
|
||||
|
||||
Linux/Mac
|
||||
``` pip install -r linux-requirements.txt ```
|
||||
|
||||
Windows
|
||||
``` pip install -r windows-requirements.txt ```
|
||||
|
||||
|
||||
``` cd src/ ```
|
||||
|
||||
|
||||
Linux/Mac
|
||||
``` ./linux-start.sh ```
|
||||
|
||||
Windows
|
||||
``` ./windows-start.sh ```
|
||||
|
||||
# Images
|
||||
![1 Interface.... ](images/pic1.png)
|
||||
|
||||
# TODO
|
||||
* Improve mouse translation and speed stepping...
|
||||
* Cleanup code/logic.
|
BIN
images/pic1.png
Normal file
BIN
images/pic1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
28
linux-requirements.txt
Normal file
28
linux-requirements.txt
Normal file
@ -0,0 +1,28 @@
|
||||
bcrypt==3.1.7
|
||||
cffi==1.14.0
|
||||
Click==7.0
|
||||
Flask==1.1.1
|
||||
Flask-Bcrypt==0.7.1
|
||||
Flask-Login==0.5.0
|
||||
Flask-SQLAlchemy==2.4.1
|
||||
Flask-WTF==0.14.3
|
||||
gunicorn==19.9.0
|
||||
itsdangerous==1.1.0
|
||||
Jinja2==2.10.3
|
||||
MarkupSafe==1.1.1
|
||||
MouseInfo==0.1.3
|
||||
Pillow==7.1.2
|
||||
pkg-resources==0.0.0
|
||||
PyAutoGUI==0.9.50
|
||||
pycparser==2.20
|
||||
PyGetWindow==0.0.8
|
||||
PyMsgBox==1.0.8
|
||||
pyperclip==1.8.0
|
||||
PyRect==0.1.4
|
||||
PyScreeze==0.1.26
|
||||
python3-xlib==0.15
|
||||
PyTweening==1.0.3
|
||||
six==1.14.0
|
||||
SQLAlchemy==1.3.11
|
||||
Werkzeug==0.16.0
|
||||
WTForms==2.2.1
|
14
src/core/MessageHandler.py
Normal file
14
src/core/MessageHandler.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Gtk imports
|
||||
|
||||
# Python imports
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
class MessageHandler:
|
||||
def __init__(self):
|
||||
print("MessageHandler initialized...")
|
||||
|
||||
|
||||
def createMessageJSON(self, type, text):
|
||||
return '{"message": { "type": "' + type + '", "text": "' + text + '" } }'
|
31
src/core/__init__.py
Normal file
31
src/core/__init__.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Python imports
|
||||
import secrets
|
||||
|
||||
|
||||
# Lib imports
|
||||
from flask import Flask
|
||||
from flask_bcrypt import Bcrypt
|
||||
from flask_login import current_user, login_user, logout_user, LoginManager
|
||||
|
||||
|
||||
# Apoplication imports
|
||||
|
||||
|
||||
# Configs and 'init'
|
||||
app = Flask(__name__)
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///static/db/database.db"
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
app.config['TITLE'] = 'RemoteMouse'
|
||||
|
||||
# For csrf and some other stuff...
|
||||
app.config['SECRET_KEY'] = secrets.token_hex(32)
|
||||
|
||||
|
||||
login_manager = LoginManager(app)
|
||||
bcrypt = Bcrypt(app)
|
||||
|
||||
from core.models import db, User
|
||||
db.init_app(app)
|
||||
|
||||
from core.forms import RegisterForm, LoginForm
|
||||
from core import routes
|
25
src/core/forms.py
Normal file
25
src/core/forms.py
Normal file
@ -0,0 +1,25 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, PasswordField, SubmitField
|
||||
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
|
||||
from core import User
|
||||
|
||||
|
||||
|
||||
class RegisterForm(FlaskForm):
|
||||
username = StringField('Username', validators=[DataRequired(), Length(min=4, max=24)])
|
||||
email = StringField('Email', validators=[DataRequired(), Email()])
|
||||
password = PasswordField('Password', validators=[DataRequired(), Length(min=8)])
|
||||
confirm_password = PasswordField('Confirm Password',
|
||||
validators=[DataRequired(), EqualTo('password', message="Passwords must match!")])
|
||||
submit = SubmitField("Sign Up")
|
||||
|
||||
def validate_username(self, username):
|
||||
user = User.query.filter_by(username=username.data).first()
|
||||
if user:
|
||||
raise ValidationError("User exists already! Please use a different name!")
|
||||
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
username = StringField('Username', validators=[DataRequired(), Length(min=4, max=24)])
|
||||
password = PasswordField('Password', validators=[DataRequired(), Length(min=8, max=32)])
|
||||
submit = SubmitField("Login")
|
20
src/core/models.py
Normal file
20
src/core/models.py
Normal file
@ -0,0 +1,20 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from core import app, login_manager
|
||||
from flask_login import UserMixin
|
||||
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return User.query.get(int(user_id))
|
||||
|
||||
|
||||
class User(db.Model, UserMixin):
|
||||
username = db.Column(db.String, unique=True, nullable=False)
|
||||
email = db.Column(db.String, nullable=False)
|
||||
password = db.Column(db.String, nullable=False)
|
||||
id = db.Column(db.Integer, primary_key=True, unique=True, autoincrement=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"['{self.username}', '{self.email}', '{self.password}', '{self.id}']"
|
85
src/core/routes/Routes.py
Normal file
85
src/core/routes/Routes.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
import pyautogui
|
||||
from flask import request, render_template
|
||||
|
||||
# App imports
|
||||
from core import app, db # Get from __init__
|
||||
from core.MessageHandler import MessageHandler # Get simple message processor
|
||||
|
||||
|
||||
msgHandler = MessageHandler()
|
||||
TITLE = app.config['TITLE']
|
||||
pyautogui.FAILSAFE = False # If we hit corner, that's ok
|
||||
pyautogui.MINIMUM_DURATION = 0.5
|
||||
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def home():
|
||||
if request.method == 'GET':
|
||||
return render_template('index.html',
|
||||
title=TITLE)
|
||||
|
||||
return render_template('error.html',
|
||||
title='Error!',
|
||||
message='Must use GET request type...')
|
||||
|
||||
|
||||
@app.route('/single-click', methods=['GET', 'POST'])
|
||||
def singleClick():
|
||||
pyautogui.click()
|
||||
return ""
|
||||
|
||||
@app.route('/double-click', methods=['GET', 'POST'])
|
||||
def doubleClick():
|
||||
pyautogui.doubleClick()
|
||||
return ""
|
||||
|
||||
@app.route('/get-coords', methods=['GET', 'POST'])
|
||||
def getCoords():
|
||||
x, y = pyautogui.position();
|
||||
return '{"x": "'+ str(x) +'", "y":"' + str(y) + '"}'
|
||||
|
||||
|
||||
@app.route('/update-coords', methods=['GET', 'POST'])
|
||||
def updateCoords():
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
x = float( str(request.values['x']).strip() )
|
||||
y = float( str(request.values['y']).strip() )
|
||||
# print("\nX: {} Y: {}".format(str(x), str(y)))
|
||||
pyautogui.moveRel(x, y);
|
||||
except Exception as e:
|
||||
print( repr(e) )
|
||||
return render_template('error.html',
|
||||
title='Error!',
|
||||
message='X or Y is not an integer...')
|
||||
|
||||
return render_template('error.html',
|
||||
title='Error!',
|
||||
message='Must use POST request type...')
|
||||
|
||||
|
||||
@app.route('/send-key', methods=['GET', 'POST'])
|
||||
def sendKey():
|
||||
pyautogui.doubleClick()
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
text = str(request.values['text']).strip()
|
||||
pyautogui.typewrite(text);
|
||||
|
||||
# print("\nX: {} Y: {}".format(str(x), str(y)))
|
||||
# pyautogui.typewrite('Hello world!\n', interval=secs_between_keys) # useful for entering text, newline is Enter
|
||||
# pyautogui.press(['left', 'left', 'left', 'left']) # Press the left arrow key 4 times.
|
||||
# pyautogui.keyDown('shift') # Press the Shift key down and hold it.
|
||||
# pyautogui.keyUp('shift') # Let go of the Shift key.
|
||||
except Exception as e:
|
||||
print( repr(e) )
|
||||
return render_template('error.html',
|
||||
title='Error!',
|
||||
message='Key is not a valid input...')
|
||||
|
||||
return render_template('error.html',
|
||||
title='Error!',
|
||||
message='Must use POST request type...')
|
1
src/core/routes/__init__.py
Normal file
1
src/core/routes/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from . import Routes
|
471
src/core/static/css/bootstrap/bootstrap-datepicker.css
vendored
Normal file
471
src/core/static/css/bootstrap/bootstrap-datepicker.css
vendored
Normal file
@ -0,0 +1,471 @@
|
||||
/*!
|
||||
* Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Improvements by Andrew Rowls
|
||||
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
||||
*/
|
||||
.datepicker {
|
||||
padding: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
direction: ltr;
|
||||
}
|
||||
.datepicker-inline {
|
||||
width: 220px;
|
||||
}
|
||||
.datepicker.datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.datepicker.datepicker-rtl table tr td span {
|
||||
float: right;
|
||||
}
|
||||
.datepicker-dropdown {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.datepicker-dropdown:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #999;
|
||||
border-top: 0;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #fff;
|
||||
border-top: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:before {
|
||||
left: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-left:after {
|
||||
left: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:before {
|
||||
right: 6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-right:after {
|
||||
right: 7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:before {
|
||||
top: -7px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-bottom:after {
|
||||
top: -6px;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:before {
|
||||
bottom: -7px;
|
||||
border-bottom: 0;
|
||||
border-top: 7px solid #999;
|
||||
}
|
||||
.datepicker-dropdown.datepicker-orient-top:after {
|
||||
bottom: -6px;
|
||||
border-bottom: 0;
|
||||
border-top: 6px solid #fff;
|
||||
}
|
||||
.datepicker table {
|
||||
margin: 0;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.datepicker td,
|
||||
.datepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.table-striped .datepicker table tr td,
|
||||
.table-striped .datepicker table tr th {
|
||||
background-color: transparent;
|
||||
}
|
||||
.datepicker table tr td.day:hover,
|
||||
.datepicker table tr td.day.focused {
|
||||
background: #eee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker table tr td.old,
|
||||
.datepicker table tr td.new {
|
||||
color: #999;
|
||||
}
|
||||
.datepicker table tr td.disabled,
|
||||
.datepicker table tr td.disabled:hover {
|
||||
background: none;
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td.highlighted {
|
||||
background: #d9edf7;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.today,
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today.disabled:hover {
|
||||
background-color: #fde19a;
|
||||
background-image: -moz-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -ms-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||
background-image: -webkit-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: -o-linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||
border-color: #fdf59a #fdf59a #fbed50;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today:hover,
|
||||
.datepicker table tr td.today:hover:hover,
|
||||
.datepicker table tr td.today.disabled:hover,
|
||||
.datepicker table tr td.today.disabled:hover:hover,
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active,
|
||||
.datepicker table tr td.today.disabled,
|
||||
.datepicker table tr td.today:hover.disabled,
|
||||
.datepicker table tr td.today.disabled.disabled,
|
||||
.datepicker table tr td.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.today[disabled],
|
||||
.datepicker table tr td.today:hover[disabled],
|
||||
.datepicker table tr td.today.disabled[disabled],
|
||||
.datepicker table tr td.today.disabled:hover[disabled] {
|
||||
background-color: #fdf59a;
|
||||
}
|
||||
.datepicker table tr td.today:active,
|
||||
.datepicker table tr td.today:hover:active,
|
||||
.datepicker table tr td.today.disabled:active,
|
||||
.datepicker table tr td.today.disabled:hover:active,
|
||||
.datepicker table tr td.today.active,
|
||||
.datepicker table tr td.today:hover.active,
|
||||
.datepicker table tr td.today.disabled.active,
|
||||
.datepicker table tr td.today.disabled:hover.active {
|
||||
background-color: #fbf069 \9;
|
||||
}
|
||||
.datepicker table tr td.today:hover:hover {
|
||||
color: #000;
|
||||
}
|
||||
.datepicker table tr td.today.active:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.datepicker table tr td.range,
|
||||
.datepicker table tr td.range:hover,
|
||||
.datepicker table tr td.range.disabled,
|
||||
.datepicker table tr td.range.disabled:hover {
|
||||
background: #eee;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today,
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover {
|
||||
background-color: #f3d17a;
|
||||
background-image: -moz-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -ms-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
|
||||
background-image: -webkit-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: -o-linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-image: linear-gradient(to bottom, #f3c17a, #f3e97a);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
|
||||
border-color: #f3e97a #f3e97a #edde34;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.datepicker table tr td.range.today:hover,
|
||||
.datepicker table tr td.range.today:hover:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover,
|
||||
.datepicker table tr td.range.today.disabled:hover:hover,
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active,
|
||||
.datepicker table tr td.range.today.disabled,
|
||||
.datepicker table tr td.range.today:hover.disabled,
|
||||
.datepicker table tr td.range.today.disabled.disabled,
|
||||
.datepicker table tr td.range.today.disabled:hover.disabled,
|
||||
.datepicker table tr td.range.today[disabled],
|
||||
.datepicker table tr td.range.today:hover[disabled],
|
||||
.datepicker table tr td.range.today.disabled[disabled],
|
||||
.datepicker table tr td.range.today.disabled:hover[disabled] {
|
||||
background-color: #f3e97a;
|
||||
}
|
||||
.datepicker table tr td.range.today:active,
|
||||
.datepicker table tr td.range.today:hover:active,
|
||||
.datepicker table tr td.range.today.disabled:active,
|
||||
.datepicker table tr td.range.today.disabled:hover:active,
|
||||
.datepicker table tr td.range.today.active,
|
||||
.datepicker table tr td.range.today:hover.active,
|
||||
.datepicker table tr td.range.today.disabled.active,
|
||||
.datepicker table tr td.range.today.disabled:hover.active {
|
||||
background-color: #efe24b \9;
|
||||
}
|
||||
.datepicker table tr td.selected,
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover {
|
||||
background-color: #9e9e9e;
|
||||
background-image: -moz-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -ms-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
|
||||
background-image: -webkit-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: -o-linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-image: linear-gradient(to bottom, #b3b3b3, #808080);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
|
||||
border-color: #808080 #808080 #595959;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.selected:hover,
|
||||
.datepicker table tr td.selected:hover:hover,
|
||||
.datepicker table tr td.selected.disabled:hover,
|
||||
.datepicker table tr td.selected.disabled:hover:hover,
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active,
|
||||
.datepicker table tr td.selected.disabled,
|
||||
.datepicker table tr td.selected:hover.disabled,
|
||||
.datepicker table tr td.selected.disabled.disabled,
|
||||
.datepicker table tr td.selected.disabled:hover.disabled,
|
||||
.datepicker table tr td.selected[disabled],
|
||||
.datepicker table tr td.selected:hover[disabled],
|
||||
.datepicker table tr td.selected.disabled[disabled],
|
||||
.datepicker table tr td.selected.disabled:hover[disabled] {
|
||||
background-color: #808080;
|
||||
}
|
||||
.datepicker table tr td.selected:active,
|
||||
.datepicker table tr td.selected:hover:active,
|
||||
.datepicker table tr td.selected.disabled:active,
|
||||
.datepicker table tr td.selected.disabled:hover:active,
|
||||
.datepicker table tr td.selected.active,
|
||||
.datepicker table tr td.selected:hover.active,
|
||||
.datepicker table tr td.selected.disabled.active,
|
||||
.datepicker table tr td.selected.disabled:hover.active {
|
||||
background-color: #666666 \9;
|
||||
}
|
||||
.datepicker table tr td.active,
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -o-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td.active:hover,
|
||||
.datepicker table tr td.active:hover:hover,
|
||||
.datepicker table tr td.active.disabled:hover,
|
||||
.datepicker table tr td.active.disabled:hover:hover,
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active,
|
||||
.datepicker table tr td.active.disabled,
|
||||
.datepicker table tr td.active:hover.disabled,
|
||||
.datepicker table tr td.active.disabled.disabled,
|
||||
.datepicker table tr td.active.disabled:hover.disabled,
|
||||
.datepicker table tr td.active[disabled],
|
||||
.datepicker table tr td.active:hover[disabled],
|
||||
.datepicker table tr td.active.disabled[disabled],
|
||||
.datepicker table tr td.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td.active:active,
|
||||
.datepicker table tr td.active:hover:active,
|
||||
.datepicker table tr td.active.disabled:active,
|
||||
.datepicker table tr td.active.disabled:hover:active,
|
||||
.datepicker table tr td.active.active,
|
||||
.datepicker table tr td.active:hover.active,
|
||||
.datepicker table tr td.active.disabled.active,
|
||||
.datepicker table tr td.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span {
|
||||
display: block;
|
||||
width: 23%;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 1%;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker table tr td span:hover,
|
||||
.datepicker table tr td span.focused {
|
||||
background: #eee;
|
||||
}
|
||||
.datepicker table tr td span.disabled,
|
||||
.datepicker table tr td span.disabled:hover {
|
||||
background: none;
|
||||
color: #999;
|
||||
cursor: default;
|
||||
}
|
||||
.datepicker table tr td span.active,
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -ms-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: -o-linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-image: linear-gradient(to bottom, #08c, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#08c', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.datepicker table tr td span.active:hover,
|
||||
.datepicker table tr td span.active:hover:hover,
|
||||
.datepicker table tr td span.active.disabled:hover,
|
||||
.datepicker table tr td span.active.disabled:hover:hover,
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active,
|
||||
.datepicker table tr td span.active.disabled,
|
||||
.datepicker table tr td span.active:hover.disabled,
|
||||
.datepicker table tr td span.active.disabled.disabled,
|
||||
.datepicker table tr td span.active.disabled:hover.disabled,
|
||||
.datepicker table tr td span.active[disabled],
|
||||
.datepicker table tr td span.active:hover[disabled],
|
||||
.datepicker table tr td span.active.disabled[disabled],
|
||||
.datepicker table tr td span.active.disabled:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.datepicker table tr td span.active:active,
|
||||
.datepicker table tr td span.active:hover:active,
|
||||
.datepicker table tr td span.active.disabled:active,
|
||||
.datepicker table tr td span.active.disabled:hover:active,
|
||||
.datepicker table tr td span.active.active,
|
||||
.datepicker table tr td span.active:hover.active,
|
||||
.datepicker table tr td span.active.disabled.active,
|
||||
.datepicker table tr td span.active.disabled:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.datepicker table tr td span.old,
|
||||
.datepicker table tr td span.new {
|
||||
color: #999;
|
||||
}
|
||||
.datepicker .datepicker-switch {
|
||||
width: 145px;
|
||||
}
|
||||
.datepicker .datepicker-switch,
|
||||
.datepicker .prev,
|
||||
.datepicker .next,
|
||||
.datepicker tfoot tr th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.datepicker .datepicker-switch:hover,
|
||||
.datepicker .prev:hover,
|
||||
.datepicker .next:hover,
|
||||
.datepicker tfoot tr th:hover {
|
||||
background: #eee;
|
||||
}
|
||||
.datepicker .cw {
|
||||
font-size: 10px;
|
||||
width: 12px;
|
||||
padding: 0 2px 0 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.input-append.date .add-on,
|
||||
.input-prepend.date .add-on {
|
||||
cursor: pointer;
|
||||
}
|
||||
.input-append.date .add-on i,
|
||||
.input-prepend.date .add-on i {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.input-daterange input {
|
||||
text-align: center;
|
||||
}
|
||||
.input-daterange input:first-child {
|
||||
-webkit-border-radius: 3px 0 0 3px;
|
||||
-moz-border-radius: 3px 0 0 3px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.input-daterange input:last-child {
|
||||
-webkit-border-radius: 0 3px 3px 0;
|
||||
-moz-border-radius: 0 3px 3px 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.input-daterange .add-on {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
min-width: 16px;
|
||||
height: 18px;
|
||||
padding: 4px 5px;
|
||||
font-weight: normal;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
vertical-align: middle;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-datepicker.css.map */
|
12
src/core/static/css/bootstrap/bootstrap.min.css
vendored
Normal file
12
src/core/static/css/bootstrap/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
src/core/static/css/font-awesome/font-awesome-all-v5.7.css
vendored
Normal file
5
src/core/static/css/font-awesome/font-awesome-all-v5.7.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
src/core/static/css/font-awesome/font-awesome-min-v4.7.0.css
vendored
Normal file
4
src/core/static/css/font-awesome/font-awesome-min-v4.7.0.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/core/static/css/font-awesome/font-awesome-woff2.css
vendored
Normal file
1
src/core/static/css/font-awesome/font-awesome-woff2.css
vendored
Normal file
File diff suppressed because one or more lines are too long
77
src/core/static/css/main.css
Normal file
77
src/core/static/css/main.css
Normal file
@ -0,0 +1,77 @@
|
||||
/* Elms */
|
||||
ul, li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden; /* Used to prevent touch scroll down reloading page. Ref: https://stackoverflow.com/questions/29008194/disabling-androids-chrome-pull-down-to-refresh-feature */
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Old versions of Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome, Opera and Firefox */
|
||||
}
|
||||
|
||||
input {
|
||||
width: 75% !important;
|
||||
margin: 0 auto !important;
|
||||
font-size: 200% !important;
|
||||
background-color: #00000000 !important;
|
||||
}
|
||||
|
||||
|
||||
/* IDs */
|
||||
#bg {
|
||||
position: fixed;
|
||||
top: 0%;
|
||||
left: 0%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -999;
|
||||
}
|
||||
|
||||
#bg img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -999;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
width: 100%;
|
||||
min-height: 65em;
|
||||
background-color: rgba(56, 56, 56, 0.67);
|
||||
}
|
||||
|
||||
#singleClickBtn, #doubleClickBtn {
|
||||
background-color: #62c462;
|
||||
border-style: dashed;
|
||||
border-width: 2px;
|
||||
overflow: auto;
|
||||
height: 8em;
|
||||
font-size: 200%;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#singleClickBtn:hover,
|
||||
#doubleClickBtn:hover,
|
||||
#singleClickBtn:active,
|
||||
#doubleClickBtn:active {
|
||||
background-color: rgba(0, 232, 255, 0.5);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#sendKeysBtn { width: 8em; }
|
||||
|
||||
|
||||
/* Classes */
|
||||
/* Other message text colors */
|
||||
.errorTxt { color: rgb(170, 18, 18); }
|
||||
.warningTxt { color: rgb(255, 168, 0); }
|
||||
.successTxt { color: rgb(136, 204, 39); }
|
BIN
src/core/static/css/webfonts/fa-brands-400.ttf
Normal file
BIN
src/core/static/css/webfonts/fa-brands-400.ttf
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-brands-400.woff
Normal file
BIN
src/core/static/css/webfonts/fa-brands-400.woff
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-brands-400.woff2
Normal file
BIN
src/core/static/css/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-regular-400.ttf
Normal file
BIN
src/core/static/css/webfonts/fa-regular-400.ttf
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-regular-400.woff
Normal file
BIN
src/core/static/css/webfonts/fa-regular-400.woff
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-regular-400.woff2
Normal file
BIN
src/core/static/css/webfonts/fa-regular-400.woff2
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-solid-900.ttf
Normal file
BIN
src/core/static/css/webfonts/fa-solid-900.ttf
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-solid-900.woff
Normal file
BIN
src/core/static/css/webfonts/fa-solid-900.woff
Normal file
Binary file not shown.
BIN
src/core/static/css/webfonts/fa-solid-900.woff2
Normal file
BIN
src/core/static/css/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
BIN
src/core/static/db/database.db
Normal file
BIN
src/core/static/db/database.db
Normal file
Binary file not shown.
BIN
src/core/static/favicon.png
Normal file
BIN
src/core/static/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
src/core/static/imgs/backgrounds/background.jpg
Normal file
BIN
src/core/static/imgs/backgrounds/background.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 504 KiB |
BIN
src/core/static/imgs/circle.png
Normal file
BIN
src/core/static/imgs/circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
22
src/core/static/js/ajax.js
Normal file
22
src/core/static/js/ajax.js
Normal file
@ -0,0 +1,22 @@
|
||||
const doAjax = (actionPath, data, action) => {
|
||||
let xhttp = new XMLHttpRequest();
|
||||
xhttp.open("POST", actionPath, true);
|
||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
// Force return to be JSON NOTE: Use application/xml to force XML
|
||||
xhttp.overrideMimeType('application/json');
|
||||
xhttp.send(data);
|
||||
}
|
||||
|
||||
const formatURL = (basePath) => {
|
||||
url = window.location.href;
|
||||
if ( url.endsWith('/') )
|
||||
return url + basePath;
|
||||
else
|
||||
return url + '/' + basePath;
|
||||
}
|
||||
|
||||
const fetchData = async (url) => {
|
||||
let response = null;
|
||||
response = await fetch(url);
|
||||
return await response.json();
|
||||
}
|
9
src/core/static/js/bootstrap/bootstrap-datepicker.min.js
vendored
Normal file
9
src/core/static/js/bootstrap/bootstrap-datepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
src/core/static/js/bootstrap/bootstrap.min.js
vendored
Normal file
7
src/core/static/js/bootstrap/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
src/core/static/js/bootstrap/jquery-3.3.1.slim.min.js
vendored
Normal file
2
src/core/static/js/bootstrap/jquery-3.3.1.slim.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
src/core/static/js/bootstrap/moment.min.js
vendored
Normal file
7
src/core/static/js/bootstrap/moment.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
src/core/static/js/bootstrap/popper.min.js
vendored
Normal file
5
src/core/static/js/bootstrap/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
143
src/core/static/js/events.js
Normal file
143
src/core/static/js/events.js
Normal file
@ -0,0 +1,143 @@
|
||||
// When true, moving the mouse updates coords
|
||||
const canvas = document.getElementById("canvas");
|
||||
let isDragging = false;
|
||||
let runUpdate = false;
|
||||
let xLast = 0;
|
||||
let yLast = 0;
|
||||
let mod = 2;
|
||||
let px = 0;
|
||||
let py = 0;
|
||||
let x1 = 0;
|
||||
let y1 = 0;
|
||||
let x2 = 0;
|
||||
let y2 = 0;
|
||||
let m = undefined; // slope value
|
||||
|
||||
|
||||
canvas.addEventListener('touchstart', e => { onPress(e); });
|
||||
canvas.addEventListener('mousedown', e => { onPress(e); });
|
||||
canvas.addEventListener('touchmove', e => { onMoveing(e); });
|
||||
canvas.addEventListener('mousemove', e => { onMoveing(e); });
|
||||
canvas.addEventListener('touchend', e => { onRelease(e); });
|
||||
canvas.addEventListener('mouseup', e => { onRelease(e); });
|
||||
|
||||
|
||||
// Run update when true every 100 ms
|
||||
setInterval(function () {
|
||||
if (runUpdate) {
|
||||
doAjax("/update-coords", "x=" + px + "&y=" + py, "move");
|
||||
}
|
||||
}, 100);
|
||||
|
||||
// Update mod
|
||||
setInterval(function () {
|
||||
if (runUpdate) {
|
||||
mod += 1;
|
||||
}
|
||||
}, 250);
|
||||
|
||||
|
||||
const onPress = (e) => {
|
||||
isDragging = true;
|
||||
runUpdate = true;
|
||||
xLast = e.offsetX;
|
||||
yLast = e.offsetY;
|
||||
updateText(xLast, yLast);
|
||||
}
|
||||
|
||||
|
||||
const onMoveing = (e) => {
|
||||
if (isDragging === true) {
|
||||
x1 = xLast;
|
||||
y1 = yLast;
|
||||
|
||||
if (e.type === 'mousemove') {
|
||||
x2 = e.offsetX;
|
||||
y2 = e.offsetY;
|
||||
xLast = e.offsetX;
|
||||
yLast = e.offsetY;
|
||||
} else if (e.type === 'touchmove') {
|
||||
x2 = parseInt(e.touches[0].clientX, 10);
|
||||
y2 = parseInt(e.touches[0].clientY, 10);
|
||||
xLast = parseInt(e.touches[0].clientX, 10);
|
||||
yLast = parseInt(e.touches[0].clientY, 10);
|
||||
}
|
||||
|
||||
// Calculate the delta of the points
|
||||
if (x2 > x1) {
|
||||
px = mod // Is growing
|
||||
} else {
|
||||
px = -mod // Is shrinking
|
||||
}
|
||||
|
||||
if (y2 > y1) {
|
||||
py = mod // Is growing
|
||||
} else {
|
||||
py = -mod // Is shrinking
|
||||
}
|
||||
|
||||
m = (y2-y1)/(x2-x1)
|
||||
if (m === undefined) {
|
||||
py = 0;
|
||||
} else if (!isFinite(m)) {
|
||||
px = 0;
|
||||
}
|
||||
|
||||
if ( (m > 0.05 && m <= 1) && (m > -0.05 && m >= -1) ) {
|
||||
py = 0;
|
||||
}
|
||||
|
||||
updateText(px, py);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const onRelease = (e) => {
|
||||
if (isDragging === true) {
|
||||
isDragging = false;
|
||||
runUpdate = false;
|
||||
mod = 3;
|
||||
xLast = 0;
|
||||
yLast = 0;
|
||||
px = 0;
|
||||
py = 0;
|
||||
updateText(px, py);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const updateText = (x, y) => {
|
||||
const coordsTxt = "X coords: " + x + ", Y coords: " + y;
|
||||
document.getElementById("cordsText").innerText = coordsTxt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Click events
|
||||
document.getElementById("singleClickBtn").addEventListener('mouseup', e => { onSingleClick(e); });
|
||||
document.getElementById("singleClickBtn").addEventListener('touchend', e => { onSingleClick(e); });
|
||||
document.getElementById("doubleClickBtn").addEventListener('mouseup', e => { onDoubleClick(e); });
|
||||
document.getElementById("doubleClickBtn").addEventListener('touchend', e => { onDoubleClick(e); });
|
||||
|
||||
const onSingleClick = (e) => {
|
||||
doAjax("/single-click", "ref=null", "singleClick");
|
||||
}
|
||||
|
||||
const onDoubleClick = (e) => {
|
||||
doAjax("/double-click", "ref=null", "doubleClick");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Key input events
|
||||
// document.getElementById("sendKeysField").addEventListener('input', e => { onSendKeys(e); });
|
||||
// document.getElementById("sendKeysField").addEventListener('change', e => { onSendKeys(e); });
|
||||
document.getElementById("sendKeysBtn").addEventListener('mouseup', e => { onSendKeys(e); });
|
||||
document.getElementById("sendKeysBtn").addEventListener('touchend', e => { onSendKeys(e); });
|
||||
|
||||
const onSendKeys = (e) => {
|
||||
let target = document.getElementById("sendKeysField");
|
||||
const text = target.value;
|
||||
doAjax("/send-key", "text=" + text, "sendKeys");
|
||||
target.value = "";
|
||||
}
|
15
src/core/templates/error.html
Normal file
15
src/core/templates/error.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col justify-content-center text-center">
|
||||
<h1 class="errorTxt">{{title}}</h1>
|
||||
<p>{{message}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
{% block scripts %}
|
||||
<!-- Created scripts -->
|
||||
{% endblock scripts %}
|
41
src/core/templates/index.html
Normal file
41
src/core/templates/index.html
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block body_header_additional %}
|
||||
{% endblock body_header_additional %}
|
||||
|
||||
{% block body_content %}
|
||||
<div class="container-auto">
|
||||
<div class="row">
|
||||
<div id="singleClickBtn" class="col justify-content-center text-center">
|
||||
Single-Click
|
||||
</div>
|
||||
<div id="doubleClickBtn" class="col justify-content-center text-center">
|
||||
Double-Click
|
||||
</div>
|
||||
</div>
|
||||
<br/><br/>
|
||||
<div class="row">
|
||||
<input id="sendKeysField" type="text" value="" class="form-control" placeholder="Send keys...">
|
||||
<button id="sendKeysBtn" class="btn btn-success">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="canvas" class="container-auto">
|
||||
<div class="row">
|
||||
<div class="col justify-content-center text-center">
|
||||
<div id="cordsText" style="font-size: 280%;">
|
||||
X coords: 0, Y coords: 0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock body_content %}
|
||||
|
||||
|
||||
{% block body_footer_additional %}
|
||||
{% endblock body_footer_additional %}
|
||||
|
||||
{% block body_scripts_additional %}
|
||||
<script src="{{url_for('static', filename='js/ajax.js')}}"></script>
|
||||
<script src="{{url_for('static', filename='js/events.js')}}"></script>
|
||||
<script src="{{url_for('static', filename='js/draging.js')}}"></script>
|
||||
{% endblock body_scripts_additional %}
|
84
src/core/templates/layout.html
Normal file
84
src/core/templates/layout.html
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{% if title %}
|
||||
<title>{{title}}</title>
|
||||
{% else %}
|
||||
<title>App</title>
|
||||
{% endif %}
|
||||
|
||||
{% block header_css %}
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.png') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap/bootstrap.min.css')}}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap/bootstrap-datepicker.css')}}">
|
||||
|
||||
<!-- Font Awesome CSS Notes -->
|
||||
<!-- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous"> -->
|
||||
<!-- https://use.fontawesome.com/releases/v5.7.0/webfonts/fa-regular-400.woff2 -->
|
||||
<!-- https://use.fontawesome.com/releases/v5.7.0/webfonts/ -->
|
||||
|
||||
<!-- Site Font Awesome CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/font-awesome/font-awesome-all-v5.7.css')}}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/font-awesome/font-awesome-min-v4.7.0.css')}}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/font-awesome/font-awesome-woff2.css')}}">
|
||||
|
||||
<!-- Site CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css')}}">
|
||||
{% block header_css_additional %}
|
||||
{% endblock header_css_additional %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block header_scripts %}
|
||||
{% block header_scripts_additional %}
|
||||
{% endblock header_scripts_additional %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<!-- <img id="bg" src="{{ url_for('static', filename='imgs/backgrounds/background.jpg')}}" alt="{{title}} Background Logo" /> -->
|
||||
|
||||
{% block body_header %}
|
||||
{% block body_header_additional %}
|
||||
{% endblock body_header_additional%}
|
||||
{% endblock %}
|
||||
|
||||
<!-- System flashed messages! -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<div class=flashes>
|
||||
{% for category, message in messages %}
|
||||
<li class="alert alert-{{ category }}">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
{% block body_content %}
|
||||
{% block body_content_additional %}
|
||||
{% endblock body_content_additional%}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body_footer %}
|
||||
{% block body_footer_additional %}
|
||||
{% endblock body_footer_additional%}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body_scripts %}
|
||||
<!-- For Bootstrap in this exact order... -->
|
||||
<script src="{{ url_for('static', filename='js/bootstrap/jquery-3.3.1.slim.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap/popper.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap/bootstrap.min.js')}}"></script>
|
||||
|
||||
<!-- For DatePicker -->
|
||||
<script src="{{ url_for('static', filename='js/bootstrap/moment.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap/bootstrap-datepicker.min.js')}}"></script>
|
||||
{% block body_scripts_additional %}
|
||||
{% endblock body_scripts_additional%}
|
||||
{% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
13
src/linux-start.sh
Normal file
13
src/linux-start.sh
Normal file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
source "../venv/bin/activate"
|
||||
# Note can replace 127.0.0.1 with 0.0.0.0 to make it 'network/internet' accessable...
|
||||
gunicorn wsgi:app -b 127.0.0.1:8080 # <module>:<app> IE <file>:<flask app variable>
|
||||
}
|
||||
main $@;
|
13
src/windows-start.sh
Normal file
13
src/windows-start.sh
Normal file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -o xtrace ## To debug scripts
|
||||
# set -o errexit ## To exit on error
|
||||
# set -o errunset ## To exit if a variable is referenced but not set
|
||||
|
||||
|
||||
function main() {
|
||||
source "../venv/Scripts/activate"
|
||||
# Note can replace 127.0.0.1 with 0.0.0.0 to make it 'network/internet' accessable...
|
||||
waitress-serve --listen=127.0.0.1:8080 wsgi:app # <module>:<app> IE <file>:<flask app variable>
|
||||
}
|
||||
main $@;
|
4
src/wsgi.py
Normal file
4
src/wsgi.py
Normal file
@ -0,0 +1,4 @@
|
||||
from core import app
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
28
windows-requirements.txt
Normal file
28
windows-requirements.txt
Normal file
@ -0,0 +1,28 @@
|
||||
bcrypt==3.1.7
|
||||
cffi==1.14.0
|
||||
Click==7.0
|
||||
Flask==1.1.1
|
||||
Flask-Bcrypt==0.7.1
|
||||
Flask-Login==0.5.0
|
||||
Flask-SQLAlchemy==2.4.1
|
||||
Flask-WTF==0.14.3
|
||||
waitress==1.4.3
|
||||
itsdangerous==1.1.0
|
||||
Jinja2==2.10.3
|
||||
MarkupSafe==1.1.1
|
||||
MouseInfo==0.1.3
|
||||
Pillow==7.1.2
|
||||
pkg-resources==0.0.0
|
||||
PyAutoGUI==0.9.50
|
||||
pycparser==2.20
|
||||
PyGetWindow==0.0.8
|
||||
PyMsgBox==1.0.8
|
||||
pyperclip==1.8.0
|
||||
PyRect==0.1.4
|
||||
PyScreeze==0.1.26
|
||||
python3-xlib==0.15
|
||||
PyTweening==1.0.3
|
||||
six==1.14.0
|
||||
SQLAlchemy==1.3.11
|
||||
Werkzeug==0.16.0
|
||||
WTForms==2.2.1
|
Loading…
Reference in New Issue
Block a user