cleanup, improvements, etc
This commit is contained in:
parent
938aaca361
commit
16c4d3f1dc
|
@ -12,10 +12,10 @@ Remote Mouse is a flask + pyautogui app to control a PC from your phone or any o
|
||||||
``` python3 -m venv venv/ ```
|
``` python3 -m venv venv/ ```
|
||||||
|
|
||||||
Linux/Mac
|
Linux/Mac
|
||||||
``` source bin/activate ```
|
``` source venv/bin/activate ```
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
``` source bin/Scripts/activate ```
|
``` source venv/bin/Scripts/activate ```
|
||||||
|
|
||||||
Linux/Mac
|
Linux/Mac
|
||||||
``` pip install -r linux-requirements.txt ```
|
``` pip install -r linux-requirements.txt ```
|
||||||
|
@ -37,5 +37,5 @@ Windows
|
||||||
![1 Interface.... ](images/pic1.png)
|
![1 Interface.... ](images/pic1.png)
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
* Improve mouse translation and speed stepping...
|
* Fix typing input
|
||||||
* Cleanup code/logic.
|
* Fix clicking lockup issues during touch
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
bcrypt==3.1.7
|
bcrypt==3.1.7
|
||||||
cffi==1.14.0
|
cffi==1.14.0
|
||||||
Click==7.0
|
Click==7.0
|
||||||
|
dnspython==1.16.0
|
||||||
|
eventlet==0.25.2
|
||||||
Flask==1.1.1
|
Flask==1.1.1
|
||||||
Flask-Bcrypt==0.7.1
|
Flask-SocketIO==4.3.0
|
||||||
Flask-Login==0.5.0
|
greenlet==0.4.16
|
||||||
Flask-SQLAlchemy==2.4.1
|
|
||||||
Flask-WTF==0.14.3
|
|
||||||
gunicorn==19.9.0
|
gunicorn==19.9.0
|
||||||
itsdangerous==1.1.0
|
itsdangerous==1.1.0
|
||||||
Jinja2==2.10.3
|
Jinja2==2.10.3
|
||||||
MarkupSafe==1.1.1
|
MarkupSafe==1.1.1
|
||||||
|
monotonic==1.5
|
||||||
MouseInfo==0.1.3
|
MouseInfo==0.1.3
|
||||||
Pillow==7.1.2
|
Pillow==7.1.2
|
||||||
pkg-resources==0.0.0
|
pkg-resources==0.0.0
|
||||||
|
@ -20,9 +21,9 @@ PyMsgBox==1.0.8
|
||||||
pyperclip==1.8.0
|
pyperclip==1.8.0
|
||||||
PyRect==0.1.4
|
PyRect==0.1.4
|
||||||
PyScreeze==0.1.26
|
PyScreeze==0.1.26
|
||||||
|
python-engineio==3.13.0
|
||||||
|
python-socketio==4.6.0
|
||||||
python3-xlib==0.15
|
python3-xlib==0.15
|
||||||
PyTweening==1.0.3
|
PyTweening==1.0.3
|
||||||
six==1.14.0
|
six==1.14.0
|
||||||
SQLAlchemy==1.3.11
|
|
||||||
Werkzeug==0.16.0
|
Werkzeug==0.16.0
|
||||||
WTForms==2.2.1
|
|
||||||
|
|
|
@ -3,9 +3,15 @@ import secrets
|
||||||
|
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
|
import eventlet
|
||||||
|
|
||||||
|
from engineio.payload import Payload
|
||||||
|
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_bcrypt import Bcrypt
|
from flask_bcrypt import Bcrypt
|
||||||
from flask_login import current_user, login_user, logout_user, LoginManager
|
from flask_login import current_user, login_user, logout_user, LoginManager
|
||||||
|
from flask_socketio import SocketIO
|
||||||
|
|
||||||
|
|
||||||
# Apoplication imports
|
# Apoplication imports
|
||||||
|
@ -13,19 +19,12 @@ from flask_login import current_user, login_user, logout_user, LoginManager
|
||||||
|
|
||||||
# Configs and 'init'
|
# Configs and 'init'
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///static/db/database.db"
|
|
||||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
||||||
app.config['TITLE'] = 'RemoteMouse'
|
app.config['TITLE'] = 'RemoteMouse'
|
||||||
|
app.config['SECRET_KEY'] = secrets.token_hex(32) # For csrf and some other stuff...
|
||||||
|
|
||||||
# For csrf and some other stuff...
|
# For Websockets
|
||||||
app.config['SECRET_KEY'] = secrets.token_hex(32)
|
# eventlet.monkey_patch()
|
||||||
|
Payload.max_decode_packets = 120 # Fix too many small packets causing error
|
||||||
|
socketio = SocketIO(app, async_mode='eventlet')
|
||||||
|
|
||||||
|
|
||||||
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
|
from core import routes
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
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")
|
|
|
@ -1,20 +0,0 @@
|
||||||
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}']"
|
|
|
@ -4,15 +4,21 @@
|
||||||
import pyautogui
|
import pyautogui
|
||||||
from flask import request, render_template
|
from flask import request, render_template
|
||||||
|
|
||||||
|
|
||||||
# App imports
|
# App imports
|
||||||
from core import app, db # Get from __init__
|
from core import app, socketio # Get from __init__
|
||||||
from core.MessageHandler import MessageHandler # Get simple message processor
|
from core.MessageHandler import MessageHandler # Get simple message processor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
msgHandler = MessageHandler()
|
msgHandler = MessageHandler()
|
||||||
TITLE = app.config['TITLE']
|
TITLE = app.config['TITLE']
|
||||||
pyautogui.FAILSAFE = False # If we hit corner, that's ok
|
|
||||||
pyautogui.MINIMUM_DURATION = 0.5
|
pyautogui.FAILSAFE = False # If we hit corner, that's ok
|
||||||
|
# Let piautogui make updates as quick as it can...
|
||||||
|
pyautogui.MINIMUM_DURATION = 0
|
||||||
|
pyautogui.PAUSE = 0
|
||||||
|
|
||||||
|
|
||||||
@app.route('/', methods=['GET', 'POST'])
|
@app.route('/', methods=['GET', 'POST'])
|
||||||
|
@ -42,24 +48,15 @@ def getCoords():
|
||||||
return '{"x": "'+ str(x) +'", "y":"' + str(y) + '"}'
|
return '{"x": "'+ str(x) +'", "y":"' + str(y) + '"}'
|
||||||
|
|
||||||
|
|
||||||
@app.route('/update-coords', methods=['GET', 'POST'])
|
@socketio.on('update_coords')
|
||||||
def updateCoords():
|
def updateCoords(message):
|
||||||
if request.method == 'POST':
|
try:
|
||||||
try:
|
parts = message.split(",")
|
||||||
x = float( str(request.values['x']).strip() )
|
x = float( parts[0] )
|
||||||
y = float( str(request.values['y']).strip() )
|
y = float( parts[1] )
|
||||||
# print("\nX: {} Y: {}".format(str(x), str(y)))
|
pyautogui.moveRel(x, y);
|
||||||
pyautogui.moveRel(x, y);
|
except Exception as e:
|
||||||
except Exception as e:
|
print( repr(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'])
|
@app.route('/send-key', methods=['GET', 'POST'])
|
||||||
def sendKey():
|
def sendKey():
|
||||||
|
|
Binary file not shown.
|
@ -1,3 +1,9 @@
|
||||||
|
const socket = io();
|
||||||
|
socket.on('connect', function() {
|
||||||
|
console.log("Websocket connected...");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// When true, moving the mouse updates coords
|
// When true, moving the mouse updates coords
|
||||||
const canvas = document.getElementById("canvas");
|
const canvas = document.getElementById("canvas");
|
||||||
let isDragging = false;
|
let isDragging = false;
|
||||||
|
@ -22,21 +28,6 @@ canvas.addEventListener('touchend', e => { onRelease(e); });
|
||||||
canvas.addEventListener('mouseup', 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) => {
|
const onPress = (e) => {
|
||||||
isDragging = true;
|
isDragging = true;
|
||||||
runUpdate = true;
|
runUpdate = true;
|
||||||
|
@ -87,7 +78,7 @@ const onMoveing = (e) => {
|
||||||
py = 0;
|
py = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateText(px, py);
|
socket.emit('update_coords', x2 + "," + y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +86,7 @@ const onMoveing = (e) => {
|
||||||
const onRelease = (e) => {
|
const onRelease = (e) => {
|
||||||
if (isDragging === true) {
|
if (isDragging === true) {
|
||||||
isDragging = false;
|
isDragging = false;
|
||||||
runUpdate = false;
|
mod = 2
|
||||||
mod = 3;
|
|
||||||
xLast = 0;
|
xLast = 0;
|
||||||
yLast = 0;
|
yLast = 0;
|
||||||
px = 0;
|
px = 0;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,7 @@
|
||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
{% block body_header_additional %}
|
{% block body_header_additional %}
|
||||||
|
<script src="{{url_for('static', filename='js/libs/socket.io.js')}}"></script>
|
||||||
{% endblock body_header_additional %}
|
{% endblock body_header_additional %}
|
||||||
|
|
||||||
{% block body_content %}
|
{% block body_content %}
|
||||||
|
@ -37,5 +38,5 @@
|
||||||
{% block body_scripts_additional %}
|
{% block body_scripts_additional %}
|
||||||
<script src="{{url_for('static', filename='js/ajax.js')}}"></script>
|
<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/events.js')}}"></script>
|
||||||
<script src="{{url_for('static', filename='js/draging.js')}}"></script>
|
<!-- <script src="{{url_for('static', filename='js/draging.js')}}"></script> -->
|
||||||
{% endblock body_scripts_additional %}
|
{% endblock body_scripts_additional %}
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
function main() {
|
function main() {
|
||||||
source "../venv/bin/activate"
|
source "../venv/bin/activate"
|
||||||
# Note can replace 127.0.0.1 with 0.0.0.0 to make it 'network/internet' accessable...
|
# 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>
|
gunicorn wsgi:app -b 127.0.0.1:8088 # <module>:<app> IE <file>:<flask app variable>
|
||||||
}
|
}
|
||||||
main $@;
|
main $@;
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/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() {
|
||||||
|
SCRIPTPATH="$( cd "$(dirname "")" >/dev/null 2>&1 ; pwd -P )"
|
||||||
|
cd "${SCRIPTPATH}"
|
||||||
|
echo "Working Dir: " $(pwd)
|
||||||
|
mkdir /tmp/apps
|
||||||
|
../venv/bin/gunicorn --bind unix:/tmp/apps/remoteconn.sock wsgi:app
|
||||||
|
}
|
||||||
|
main $@;
|
|
@ -1,4 +1,5 @@
|
||||||
from core import app
|
from core import socketio, app
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True)
|
socketio.run(app, host="127.0.0.1", port="8088")
|
||||||
|
# app.run(debug=True)
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
bcrypt==3.1.7
|
bcrypt==3.1.7
|
||||||
cffi==1.14.0
|
cffi==1.14.0
|
||||||
Click==7.0
|
Click==7.0
|
||||||
|
dnspython==1.16.0
|
||||||
|
eventlet==0.25.2
|
||||||
Flask==1.1.1
|
Flask==1.1.1
|
||||||
Flask-Bcrypt==0.7.1
|
Flask-SocketIO==4.3.0
|
||||||
Flask-Login==0.5.0
|
greenlet==0.4.16
|
||||||
Flask-SQLAlchemy==2.4.1
|
|
||||||
Flask-WTF==0.14.3
|
|
||||||
waitress==1.4.3
|
waitress==1.4.3
|
||||||
itsdangerous==1.1.0
|
itsdangerous==1.1.0
|
||||||
Jinja2==2.10.3
|
Jinja2==2.10.3
|
||||||
MarkupSafe==1.1.1
|
MarkupSafe==1.1.1
|
||||||
|
monotonic==1.5
|
||||||
MouseInfo==0.1.3
|
MouseInfo==0.1.3
|
||||||
Pillow==7.1.2
|
Pillow==7.1.2
|
||||||
pkg-resources==0.0.0
|
pkg-resources==0.0.0
|
||||||
|
@ -20,9 +21,8 @@ PyMsgBox==1.0.8
|
||||||
pyperclip==1.8.0
|
pyperclip==1.8.0
|
||||||
PyRect==0.1.4
|
PyRect==0.1.4
|
||||||
PyScreeze==0.1.26
|
PyScreeze==0.1.26
|
||||||
python3-xlib==0.15
|
python-engineio==3.13.0
|
||||||
|
python-socketio==4.6.0
|
||||||
PyTweening==1.0.3
|
PyTweening==1.0.3
|
||||||
six==1.14.0
|
six==1.14.0
|
||||||
SQLAlchemy==1.3.11
|
|
||||||
Werkzeug==0.16.0
|
Werkzeug==0.16.0
|
||||||
WTForms==2.2.1
|
|
||||||
|
|
Loading…
Reference in New Issue