documentation and code cleanup: auto_update, config, helper

This commit is contained in:
DESKTOP-JVKHS7I\Adam 2020-05-12 11:43:42 +05:30
parent 30b8477d8d
commit bb83a33b82
6 changed files with 98 additions and 76 deletions

View File

@ -1,3 +1,8 @@
"""
auto_update.py
checks version and auto updates
"""
import re
import subprocess
import sys
@ -9,6 +14,13 @@ from bs4 import BeautifulSoup
def _normalize_version(v):
"""
converts version string into an "normalized" of versions which is a list of version codes,
eg, input: '0.3.0', output: [0,3,0]
this is done so that, versions can be compared easily
:param v: string
:return: list
"""
rv = []
for x in v.split("."):
try:
@ -24,6 +36,12 @@ def _normalize_version(v):
def _get_highest_version(index, pkg):
"""
Crawls web for latest version name then returns latest version
:param index: website to check
:param pkg: package name
:return: latest version normalized
"""
url = "{}/{}/".format(index, pkg)
html = urllib.request.urlopen(url)
if html.getcode() != 200:
@ -43,10 +61,20 @@ def _get_highest_version(index, pkg):
def _get_current_version(pkg):
"""
Gets the current version of the package installed
:param pkg: name of the installed backage
:return: version normalized
"""
return _normalize_version(pkg_resources.get_distribution(pkg).version)
def auto_upgrade():
"""
public function,
compares current version with the latest version (from web),
if current version is older, then it updates and restarts the script
"""
index = "https://pypi.python.org/simple"
pkg = "fishy"
if _get_highest_version(index, pkg) > _get_current_version(pkg):

View File

@ -1,30 +1,56 @@
"""
config.py
Saves configuration in file as json file
"""
import json
import os
from threading import Thread
# path to save the configuration file
filename = os.path.expanduser(r"~/Documents/fishy_config.json")
class Config:
def __init__(self):
"""
cache the configuration in a dict for faster access,
if file is not found initialize the dict
"""
self.config_dict = json.loads(open(filename).read()) if os.path.exists(filename) else dict()
def get(self, key, default=None):
if key in self.config_dict:
return self.config_dict[key]
return default
"""
gets a value from configuration,
if it is not found, return the default configuration
:param key: key of the config
:param default: default value to return if key is not found
:return: config value
"""
return self.config_dict[key] if key in self.config_dict else default
def set(self, key, value, save=True):
"""
saves the configuration is cache (and saves it in file if needed)
:param key: key to save
:param value: value to save
:param save: False if don't want to save right away
"""
self.config_dict[key] = value
if save:
self.save_config()
def delete(self, key):
"""
deletes a key from config
:param key: key to delete
"""
del self.config_dict[key]
self.save_config()
def save_config(self):
"""
save the cache to the file
"""
with open(filename, 'w') as f:
f.write(json.dumps(self.config_dict))

View File

@ -1,4 +1,5 @@
"""
fishing_event.py
Defines different fishing modes (states) which acts as state for state machine
also implements callbacks which is called when states are changed
"""
@ -10,7 +11,6 @@ import pyautogui
from fishy.systems import web
from fishy.systems.globals import G
from fishy.systems.helper import round_float
class FishEvent(ABC):
@ -41,7 +41,7 @@ class HookEvent(FishEvent):
timeToHook = time.time() - G.stickInitTime
G.fish_times.append(timeToHook)
logging.info("HOOOOOOOOOOOOOOOOOOOOOOOK....... " + str(G.fishCaught) + " caught " + "in " + str(
round_float(timeToHook)) + " secs. " + "Total: " + str(G.totalFishCaught))
round(timeToHook, 2)) + " secs. " + "Total: " + str(G.totalFishCaught))
pyautogui.press(self.action_key)
if self.collect_r:

View File

@ -74,7 +74,7 @@ class GUI:
self.root.title("Fiishybot for Elder Scrolls Online")
self.root.geometry('650x550')
self.root.iconbitmap(helper.get_data_file_path('icon.ico'))
self.root.iconbitmap(helper.manifest_file('icon.ico'))
# region menu
menubar = Menu(self.root)

View File

@ -1,16 +1,12 @@
import logging
import os
import shutil
import sys
import threading
import traceback
import webbrowser
from decimal import Decimal
from threading import Thread
from zipfile import ZipFile
import cv2
import numpy as np
from uuid import uuid1
from hashlib import md5
@ -18,52 +14,22 @@ from win32com.client import Dispatch
import fishy
import winshell
import functools
from fishy.systems.gui import GUIFunction
def round_float(v, ndigits=2, rt_str=False):
"""
Rounds float
:param v: float ot round off
:param ndigits: round off to ndigits decimal points
:param rt_str: true to return string
:return: rounded float or strings
"""
d = Decimal(v)
v_str = ("{0:.%sf}" % ndigits).format(round(d, ndigits))
if rt_str:
return v_str
return Decimal(v_str)
def draw_keypoints(vis, keypoints, color=(0, 0, 255)):
"""
draws a point on cv2 image array
:param vis: cv2 image array to draw
:param keypoints: keypoints array to draw
:param color: color of the point
"""
for kp in keypoints:
x, y = kp.pt
cv2.circle(vis, (int(x), int(y)), 5, color, -1)
def enable_full_array_printing():
"""
Used to enable full array logging
(summarized arrays are printed by default)
"""
np.set_printoptions(threshold=sys.maxsize)
def open_web(website):
"""
Opens a website on browser,
uses multi-threading so that current thread doesnt get blocked
:param website: url
"""
logging.debug("opening web, please wait...")
Thread(target=lambda: webbrowser.open(website, new=2)).start()
def create_new_uid():
"""
Creates a unique id for user
"""
return md5(str(uuid1()).encode()).hexdigest()
@ -95,50 +61,52 @@ def unhandled_exception_logging(*exc_info):
logging.error("Unhandled exception: %s", text)
def get_data_file_path(rel_path):
def manifest_file(rel_path):
"""
returns a file from the manifest files,
used to get the files which are installed along with the scripts
:param rel_path: relative path from `__init__.py`
:return: abs path of the file
"""
return os.path.join(os.path.dirname(fishy.__file__), rel_path)
def create_shortcut(gui):
"""
creates a new shortcut on desktop
:param gui: does nothing todo
"""
try:
user = os.path.expanduser("~")
if os.path.exists(os.path.join(user, "Desktop")):
path = os.path.join(user, "Desktop", "Fishybot ESO.lnk")
_copy_shortcut(path)
else:
gui.call(GUIFunction.ASK_DIRECTORY, (_copy_shortcut,
"Could not find Desktop please specify path to create shortcut"))
except Exception:
logging.info("Couldn't create shortcut")
traceback.print_exc()
desktop = winshell.desktop()
path = os.path.join(desktop, "Fishybot ESO.lnk")
shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
shortcut.Targetpath = os.path.join(os.path.dirname(sys.executable), "python.exe")
shortcut.Arguments = "-m fishy"
shortcut.IconLocation = manifest_file("icon.ico")
shortcut.save()
def _copy_shortcut(path):
desktop = winshell.desktop()
path = os.path.join(desktop, "Fishybot ESO.lnk")
shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
shortcut.Targetpath = os.path.join(os.path.dirname(sys.executable), "python.exe")
shortcut.Arguments = "-m fishy"
shortcut.IconLocation = get_data_file_path("icon.ico")
shortcut.save()
logging.info("Shortcut created")
logging.info("Shortcut created")
except:
logging.error("Couldn't create shortcut")
def check_addon():
"""
Extracts the addon from zip and installs it into the AddOn folder of eso
"""
try:
user = os.path.expanduser("~")
addon_dir = os.path.join(user, "Documents", "Elder Scrolls Online", "live", "Addons")
if not os.path.exists(os.path.join(addon_dir, 'ProvisionsChalutier')):
logging.info("Addon not found, installing it...")
with ZipFile(get_data_file_path("ProvisionsChalutier.zip"), 'r') as zip:
with ZipFile(manifest_file("ProvisionsChalutier.zip"), 'r') as zip:
zip.extractall(path=addon_dir)
logging.info("Please make sure you enable \"Allow outdated addons\" in-game\n"
"Also, make sure the addon is visible clearly on top left corner of the game window")
except Exception:
print("couldn't install addon, try doing it manually")
logging.error("couldn't install addon, try doing it manually")
def restart():

View File

@ -31,12 +31,12 @@ def _run_terms_window(config: Config):
message = f'I agree to the [Terms of Service and Privacy Policy]({web.get_terms_page()})'
root.title("EULA")
root.resizable(False, False)
root.iconbitmap(helper.get_data_file_path('icon.ico'))
root.iconbitmap(helper.manifest_file('icon.ico'))
f = Frame(root)
canvas = Canvas(f, width=300, height=200)
canvas.pack()
root.image = Image.open(helper.get_data_file_path('fishybot_logo.png')).resize((300, 200))
root.image = Image.open(helper.manifest_file('fishybot_logo.png')).resize((300, 200))
root.image = ImageTk.PhotoImage(root.image)
canvas.create_image(0, 0, anchor=NW, image=root.image)