stockometer 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stockometer-0.1.0/PKG-INFO +6 -0
- stockometer-0.1.0/pyproject.toml +9 -0
- stockometer-0.1.0/setup.cfg +4 -0
- stockometer-0.1.0/stockometer/__init__.py +0 -0
- stockometer-0.1.0/stockometer/config.py +13 -0
- stockometer-0.1.0/stockometer/main.py +51 -0
- stockometer-0.1.0/stockometer/updater.py +75 -0
- stockometer-0.1.0/stockometer/utils.py +31 -0
- stockometer-0.1.0/stockometer.egg-info/PKG-INFO +6 -0
- stockometer-0.1.0/stockometer.egg-info/SOURCES.txt +12 -0
- stockometer-0.1.0/stockometer.egg-info/dependency_links.txt +1 -0
- stockometer-0.1.0/stockometer.egg-info/entry_points.txt +2 -0
- stockometer-0.1.0/stockometer.egg-info/requires.txt +1 -0
- stockometer-0.1.0/stockometer.egg-info/top_level.txt +1 -0
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
APP_NAME = "stockometer"
|
|
5
|
+
|
|
6
|
+
BASE_DIR = Path.home() / f".{APP_NAME}"
|
|
7
|
+
EXE_PATH = BASE_DIR / "stockometer.exe"
|
|
8
|
+
NEW_EXE_PATH = BASE_DIR / "stockometer_latest.exe"
|
|
9
|
+
VERSION_FILE = BASE_DIR / "version.txt"
|
|
10
|
+
|
|
11
|
+
GITHUB_API = "https://api.github.com/repos/AlvinJoby/stockometer-desktop/releases/latest"
|
|
12
|
+
def ensure_dirs():
|
|
13
|
+
BASE_DIR.mkdir(parents=True, exist_ok=True)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from .config import *
|
|
6
|
+
from .updater import *
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def type_text(text, delay=0.002):
|
|
10
|
+
for char in text:
|
|
11
|
+
sys.stdout.write(char)
|
|
12
|
+
sys.stdout.flush()
|
|
13
|
+
time.sleep(delay)
|
|
14
|
+
print()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def show_banner():
|
|
18
|
+
banner = r"""
|
|
19
|
+
█████╗ ██╗ ██╗ ██╗██╗███╗ ██╗
|
|
20
|
+
██╔══██╗██║ ██║ ██║██║████╗ ██║
|
|
21
|
+
███████║██║ ██║ ██║██║██╔██╗ ██║
|
|
22
|
+
██╔══██║██║ ╚██╗ ██╔╝██║██║╚██╗██║
|
|
23
|
+
██║ ██║███████╗ ╚████╔╝ ██║██║ ╚████║
|
|
24
|
+
╚═╝ ╚═╝╚══════╝ ╚═══╝ ╚═╝╚═╝ ╚═══╝
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
print("\n")
|
|
28
|
+
type_text(banner, 0.0015) # fast typing for big text
|
|
29
|
+
time.sleep(0.3)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def run_exe():
|
|
33
|
+
try:
|
|
34
|
+
subprocess.Popen([str(EXE_PATH)])
|
|
35
|
+
except FileNotFoundError:
|
|
36
|
+
print("[stockometer] Executable not found.")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def main():
|
|
40
|
+
show_banner()
|
|
41
|
+
|
|
42
|
+
ensure_dirs()
|
|
43
|
+
first_time_setup()
|
|
44
|
+
replace_exe()
|
|
45
|
+
|
|
46
|
+
run_exe()
|
|
47
|
+
start_background_update()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
import subprocess
|
|
3
|
+
import os
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from .config import *
|
|
7
|
+
from .utils import download_file
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_latest_release():
|
|
11
|
+
res = requests.get(GITHUB_API)
|
|
12
|
+
res.raise_for_status()
|
|
13
|
+
data = res.json()
|
|
14
|
+
|
|
15
|
+
version = data["tag_name"]
|
|
16
|
+
|
|
17
|
+
for asset in data["assets"]:
|
|
18
|
+
if asset["name"].endswith(".exe"):
|
|
19
|
+
return version, asset["browser_download_url"]
|
|
20
|
+
|
|
21
|
+
raise Exception("No .exe found in release assets")
|
|
22
|
+
|
|
23
|
+
def get_local_version():
|
|
24
|
+
if not VERSION_FILE.exists():
|
|
25
|
+
return None
|
|
26
|
+
return VERSION_FILE.read_text().strip()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def save_version(version):
|
|
30
|
+
VERSION_FILE.write_text(version)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def replace_exe():
|
|
34
|
+
if NEW_EXE_PATH.exists():
|
|
35
|
+
try:
|
|
36
|
+
os.replace(NEW_EXE_PATH, EXE_PATH)
|
|
37
|
+
except Exception:
|
|
38
|
+
pass # will retry next run
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def update_if_needed():
|
|
42
|
+
try:
|
|
43
|
+
latest_version, url = get_latest_release()
|
|
44
|
+
local_version = get_local_version()
|
|
45
|
+
|
|
46
|
+
if local_version == latest_version:
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
print("[stockometer] Updating in background...")
|
|
50
|
+
|
|
51
|
+
download_file(url, NEW_EXE_PATH)
|
|
52
|
+
|
|
53
|
+
replace_exe()
|
|
54
|
+
save_version(latest_version)
|
|
55
|
+
|
|
56
|
+
print("[stockometer] Updated to", latest_version)
|
|
57
|
+
|
|
58
|
+
except Exception:
|
|
59
|
+
pass # silent fail
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def start_background_update():
|
|
63
|
+
thread = threading.Thread(target=update_if_needed, daemon=True)
|
|
64
|
+
thread.start()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def first_time_setup():
|
|
68
|
+
if EXE_PATH.exists():
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
print("[yourtool] First time setup: downloading tool...")
|
|
72
|
+
|
|
73
|
+
latest_version, url = get_latest_release()
|
|
74
|
+
download_file(url, EXE_PATH)
|
|
75
|
+
save_version(latest_version)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import threading
|
|
3
|
+
import itertools
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
def spinner(stop_event, message="Loading"):
|
|
8
|
+
for char in itertools.cycle("|/-\\"):
|
|
9
|
+
if stop_event.is_set():
|
|
10
|
+
break
|
|
11
|
+
sys.stdout.write(f"\r{message} {char}")
|
|
12
|
+
sys.stdout.flush()
|
|
13
|
+
time.sleep(0.1)
|
|
14
|
+
sys.stdout.write("\r")
|
|
15
|
+
|
|
16
|
+
def download_file(url, path):
|
|
17
|
+
stop_event = threading.Event()
|
|
18
|
+
t = threading.Thread(target=spinner, args=(stop_event, "Downloading"))
|
|
19
|
+
t.start()
|
|
20
|
+
|
|
21
|
+
r = requests.get(url, stream=True)
|
|
22
|
+
r.raise_for_status()
|
|
23
|
+
|
|
24
|
+
with open(path, "wb") as f:
|
|
25
|
+
for chunk in r.iter_content(chunk_size=8192):
|
|
26
|
+
f.write(chunk)
|
|
27
|
+
|
|
28
|
+
stop_event.set()
|
|
29
|
+
t.join()
|
|
30
|
+
|
|
31
|
+
print("> Download complete :)")
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
stockometer/__init__.py
|
|
3
|
+
stockometer/config.py
|
|
4
|
+
stockometer/main.py
|
|
5
|
+
stockometer/updater.py
|
|
6
|
+
stockometer/utils.py
|
|
7
|
+
stockometer.egg-info/PKG-INFO
|
|
8
|
+
stockometer.egg-info/SOURCES.txt
|
|
9
|
+
stockometer.egg-info/dependency_links.txt
|
|
10
|
+
stockometer.egg-info/entry_points.txt
|
|
11
|
+
stockometer.egg-info/requires.txt
|
|
12
|
+
stockometer.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
stockometer
|