Skip to content

Commit 1c9acca

Browse files
committed
release manager
1 parent fad4dbf commit 1c9acca

File tree

15 files changed

+234
-13
lines changed

15 files changed

+234
-13
lines changed

Actions/actions.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import os
55
import sys
66
import threading
7-
import re
87
import math
98
import serial.tools.list_ports
109
import glob
@@ -66,6 +65,10 @@ def processAction(self, msg):
6665
#Commands not allowed during sending gcode
6766
elif self.data.uploadFlag:
6867
self.data.ui_queue1.put("Alert", "Alert", "Cannot issue command while sending gcode.")
68+
elif msg["data"]["command"] == "update":
69+
if not self.data.releaseManager.update(msg["data"]["arg"]):
70+
self.data.ui_queue1.put("Alert", "Alert", "Error with updating webcontrol.")
71+
return "Shutdown"
6972
elif msg["data"]["command"] == "cutTriangularCalibrationPattern":
7073
if not self.data.triangularCalibration.cutTriangularCalibrationPattern():
7174
self.data.ui_queue1.put("Alert", "Alert", "Error with cutting triangular calibration pattern.")
@@ -237,7 +240,7 @@ def processAction(self, msg):
237240
if not self.data.boardManager.clearBoard():
238241
self.data.ui_queue1.put("Alert", "Alert", "Error with clearing board")
239242
elif msg["data"]["command"] == "updatePyInstaller":
240-
if not self.updatePyInstaller():
243+
if not self.data.releaseManager.updatePyInstaller():
241244
self.data.ui_queue1.put("Alert", "Alert", "Error with updating WebControl")
242245
return "Shutdown"
243246
else:
@@ -1473,9 +1476,9 @@ def clearLogs(self):
14731476
except Exception as e:
14741477
self.data.console_queue.put(str(e))
14751478
return False
1476-
1479+
'''
14771480
def checkForLatestPyRelease(self):
1478-
if self.data.platform=="PYINSTALLER":
1481+
if True: #self.data.platform=="PYINSTALLER":
14791482
print("check for pyrelease")
14801483
g = Github()
14811484
repo = g.get_repo("madgrizzle/WebControl")
@@ -1487,10 +1490,12 @@ def checkForLatestPyRelease(self):
14871490
for release in releases:
14881491
try:
14891492
tag_name = re.sub(r'[v]',r'',release.tag_name)
1493+
print(release.body)
14901494
#print(tag_name)
14911495
if float(tag_name) > latest:
14921496
latest = float(tag_name)
14931497
latestRelease = release
1498+
14941499
except:
14951500
print("error parsing tagname")
14961501
print(latest)
@@ -1566,6 +1571,7 @@ def make_executable(self, path):
15661571
print("3")
15671572
os.chmod(path, mode)
15681573
print("4")
1574+
'''
15691575

15701576
def addDirToZip(self, zipHandle, path, basePath=""):
15711577
basePath = basePath.rstrip("\\/") + ""
@@ -1589,6 +1595,7 @@ def zipfolder(self, filename, target_dir):
15891595
zipobj.write(fn, fn[rootlen:])
15901596
zipobj.close()
15911597

1598+
15921599
def backupWebControl(self):
15931600
try:
15941601
timestr = time.strftime("%Y%m%d-%H%M%S")

Background/messageProcessor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def start(self):
1717
# check for available update file
1818
if time.time()-self.data.lastChecked > 60*60:
1919
self.data.lastChecked = time.time()
20-
self.data.actions.checkForLatestPyRelease()
20+
self.data.releaseManager.checkForLatestPyRelease()
2121
while (
2222
not self.data.message_queue.empty()
2323
): # if there is new data to be read

Connection/nonVisibleWidgets.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from Background.WebMCPProcessor import ConsoleProcessor
1818
from Background.webcamVideoStream import WebcamVideoStream
1919
from Boards.boardManager import BoardManager
20+
from ReleaseManager.releaseManager import ReleaseManager
2021

2122
class NonVisibleWidgets(MakesmithInitFuncs):
2223
"""
@@ -40,6 +41,7 @@ class NonVisibleWidgets(MakesmithInitFuncs):
4041
camera = WebcamVideoStream()
4142
gpioActions = GPIOActions()
4243
boardManager = BoardManager()
44+
releaseManager = ReleaseManager()
4345

4446
def setUpData(self, data):
4547
"""
@@ -69,6 +71,7 @@ def setUpData(self, data):
6971
data.camera = self.camera
7072
data.gpioActions = self.gpioActions
7173
data.boardManager = self.boardManager
74+
data.releaseManager = self.releaseManager
7275

7376
if hasattr(sys, '_MEIPASS'):
7477
data.platform = "PYINSTALLER"
@@ -122,6 +125,7 @@ def setUpData(self, data):
122125
self.gpioActions.setup()
123126
self.boardManager.setUpData(data)
124127
self.boardManager.initializeNewBoard()
128+
self.releaseManager.setUpData(data)
125129

126130
#set up kinematics with current settings
127131
self.holeyKinematics.initializeSettings()

DataStructures/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Data:
3838
Version Updater
3939
'''
4040
lastChecked = -1
41-
pyInstallCurrentVersion = 0.913
41+
pyInstallCurrentVersion = 0.914
4242
pyInstallUpdateAvailable = False
4343
pyInstallUpdateBrowserUrl = ""
4444
pyInstallUpdateVersion = 0

ReleaseManager/__init__.py

Whitespace-only changes.

ReleaseManager/releaseManager.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
from DataStructures.makesmithInitFuncs import MakesmithInitFuncs
2+
import time
3+
import json
4+
import datetime
5+
import os
6+
import glob
7+
import zipfile
8+
import re
9+
from github import Github
10+
import wget
11+
import subprocess
12+
from shutil import copyfile
13+
14+
15+
class ReleaseManager(MakesmithInitFuncs):
16+
17+
def __init__(self):
18+
pass
19+
20+
releases = None
21+
latestRelease = None
22+
23+
def getReleases(self):
24+
return self.releases
25+
26+
def getLatestRelease(self):
27+
return self.latestRelease
28+
29+
def checkForLatestPyRelease(self):
30+
if True: # self.data.platform=="PYINSTALLER":
31+
print("check for pyrelease")
32+
g = Github()
33+
repo = g.get_repo("madgrizzle/WebControl")
34+
self.releases = repo.get_releases()
35+
latest = 0
36+
latestRelease = None
37+
type = self.data.pyInstallType
38+
platform = self.data.pyInstallPlatform
39+
for release in self.releases:
40+
try:
41+
tag_name = re.sub(r'[v]', r'', release.tag_name)
42+
# print(tag_name)
43+
if float(tag_name) > latest:
44+
latest = float(tag_name)
45+
self.latestRelease = release
46+
47+
except:
48+
print("error parsing tagname")
49+
print(latest)
50+
if latest > self.data.pyInstallCurrentVersion:
51+
if self.latestRelease is not None:
52+
print(self.latestRelease.tag_name)
53+
assets = self.latestRelease.get_assets()
54+
for asset in assets:
55+
if asset.name.find(type) != -1 and asset.name.find(platform) != -1:
56+
print(asset.name)
57+
print(asset.url)
58+
self.data.ui_queue1.put("Action", "pyinstallUpdate", "on")
59+
self.data.pyInstallUpdateAvailable = True
60+
self.data.pyInstallUpdateBrowserUrl = asset.browser_download_url
61+
self.data.pyInstallUpdateVersion = latest
62+
63+
def processAbsolutePath(self, path):
64+
index = path.find("main.py")
65+
self.data.pyInstallInstalledPath = path[0:index - 1]
66+
print(self.data.pyInstallInstalledPath)
67+
68+
def updatePyInstaller(self, bypassCheck = False):
69+
home = self.data.config.getHome()
70+
if self.data.pyInstallUpdateAvailable == True or bypassCheck:
71+
if not os.path.exists(home + "/.WebControl/downloads"):
72+
print("creating downloads directory")
73+
os.mkdir(home + "/.WebControl/downloads")
74+
fileList = glob.glob(home + "/.WebControl/downloads/*.gz")
75+
for filePath in fileList:
76+
try:
77+
os.remove(filePath)
78+
except:
79+
print("error cleaning download directory: ", filePath)
80+
print("---")
81+
if self.data.pyInstallPlatform == "win32" or self.data.pyInstallPlatform == "win64":
82+
filename = wget.download(self.data.pyInstallUpdateBrowserUrl, out=home + "\\.WebControl\\downloads")
83+
else:
84+
filename = wget.download(self.data.pyInstallUpdateBrowserUrl, out=home + "/.WebControl/downloads")
85+
print(filename)
86+
87+
if self.data.platform == "PYINSTALLER":
88+
lhome = os.path.join(self.data.platformHome)
89+
else:
90+
lhome = "."
91+
if self.data.pyInstallPlatform == "win32" or self.data.pyInstallPlatform == "win64":
92+
path = lhome + "/tools/upgrade_webcontrol_win.bat"
93+
copyfile(path, home + "/.WebControl/downloads/upgrade_webcontrol_win.bat")
94+
path = lhome + "/tools/7za.exe"
95+
copyfile(path, home + "/.WebControl/downloads/7za.exe")
96+
self.data.pyInstallInstalledPath = self.data.pyInstallInstalledPath.replace('/', '\\')
97+
program_name = home + "\\.WebControl\\downloads\\upgrade_webcontrol_win.bat"
98+
99+
else:
100+
path = lhome + "/tools/upgrade_webcontrol.sh"
101+
copyfile(path, home + "/.WebControl/downloads/upgrade_webcontrol.sh")
102+
program_name = home + "/.WebControl/downloads/upgrade_webcontrol.sh"
103+
self.make_executable(home + "/.WebControl/downloads/upgrade_webcontrol.sh")
104+
tool_path = home + "\\.WebControl\\downloads\\7za.exe"
105+
arguments = [filename, self.data.pyInstallInstalledPath, tool_path]
106+
command = [program_name]
107+
command.extend(arguments)
108+
print("popening")
109+
print(command)
110+
subprocess.Popen(command)
111+
return True
112+
return False
113+
114+
def make_executable(self, path):
115+
print("1")
116+
mode = os.stat(path).st_mode
117+
print("2")
118+
mode |= (mode & 0o444) >> 2 # copy R bits to X
119+
print("3")
120+
os.chmod(path, mode)
121+
print("4")
122+
123+
124+
def update(self, version):
125+
if version == self.latestRelease.tag_name:
126+
return self.updatePyInstaller()
127+
else:
128+
print("downgrade to ")
129+
print(version)
130+
type = self.data.pyInstallType
131+
platform = self.data.pyInstallPlatform
132+
for release in self.releases:
133+
if release.tag_name == version:
134+
assets = release.get_assets()
135+
for asset in assets:
136+
if asset.name.find(type) != -1 and asset.name.find(platform) != -1:
137+
print(asset.name)
138+
print(asset.url)
139+
self.data.pyInstallUpdateBrowserUrl = asset.browser_download_url
140+
print(self.data.pyInstallUpdateBrowserUrl)
141+
return self.updatePyInstaller(True)
142+
143+

WebPageProcessor/webPageProcessor.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import json
66
from os import listdir
77
from os.path import isfile, join
8+
import re
89
from flask import render_template
910
import os
1011
import webbrowser
1112
import socket
13+
from github import Github
1214

1315
class WebPageProcessor:
1416

@@ -503,6 +505,31 @@ def createWebPage(self, pageID, isMobile, args):
503505
pageName = "gettingStarted.html"
504506
page = render_template(pageName, pageID="gettingStarted")
505507
return page, "Getting Started", False, "medium", "content", False
508+
elif pageID == "releases":
509+
releases = self.data.releaseManager.getReleases()
510+
latestRelease = self.data.releaseManager.getLatestRelease()
511+
currentRelease = "v"+str(self.data.pyInstallCurrentVersion)
512+
for release in releases:
513+
tag_name = re.sub(r'[v]', r'', release.tag_name)
514+
if isMobile:
515+
page = render_template(
516+
"releases_mobile.html",
517+
title="Update Manager",
518+
releases=releases,
519+
latestRelease=latestRelease,
520+
currentRelease=currentRelease,
521+
pageID="releases",
522+
)
523+
else:
524+
page = render_template(
525+
"releases.html",
526+
title="Update Manager",
527+
releases=releases,
528+
latestRelease=latestRelease,
529+
currentRelease=currentRelease,
530+
pageID="releases",
531+
)
532+
return page, "Update Manager", False, "medium", "content", False
506533

507534
else:
508535
self.data.ui_queue1.put("Alert", "Alert", "Function not currently implemented.. Sorry.")

app.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
from flask import Flask
22
from flask_mobility import Mobility
33
from flask_socketio import SocketIO
4+
from flask_misaka import Misaka
45

56
import os, sys
67
base_dir = '.'
78
if hasattr(sys, '_MEIPASS'):
89
base_dir = os.path.join(sys._MEIPASS)
910

11+
md = Misaka()
12+
1013
app = Flask(__name__, static_folder=os.path.join(base_dir, 'static'), template_folder=os.path.join(base_dir, 'templates'))
1114
app.debug = True
1215
socketio = SocketIO(app)
1316
mobility = Mobility(app)
17+
md.init_app(app)
18+

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ def isnumber(s):
682682

683683
print("-$$$$$-")
684684
print(os.path.abspath(__file__))
685-
app.data.actions.processAbsolutePath(os.path.abspath(__file__))
685+
app.data.releaseManager.processAbsolutePath(os.path.abspath(__file__))
686686
print("-$$$$$-")
687687

688688

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Click==7.0
22
Flask==1.0.2
3+
Flask-Misaka
34
Flask-Mobility==0.1.1
45
Flask-SocketIO==3.0.2
56
gevent==1.3.7

static/scripts/base.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ function setupStatusButtons(){
195195
function pyInstallUpdateBadge(data){
196196
console.log("---##-")
197197
console.log(data);
198-
$('#actionsBadge').html("1");
198+
$('#helpBadge').html("1");
199+
$('#updateBadge').html("1");
199200
console.log("---##-")
200201
}

static/scripts/frontpage3d.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var gcode = new THREE.Group();
2727
//var cutTrailGroup = new THREE.Group();
2828

2929
var camera = new THREE.PerspectiveCamera(45, w/h, 1, 500);
30+
//var camera = new THREE.OrthographicCamera(w/-2, w/2, h/2, h/-2, 1, 500);
3031
var controls = new THREE.OrbitControls(camera, renderer.domElement);
3132
controls.screenSpacePanning = true;
3233

templates/actions.html

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ <h4 class="card-title">Diagnostics/Maintenance</h4>
2222
<button type="button" class="btn btn-lg btn-block btn-secondary" onclick="requestPage('restoreWebControl');$('#contentModal').modal('hide');">Restore WebControl</button>
2323
<button type="button" class="btn btn-lg btn-block btn-secondary" onclick="action('clearLogs');$('#contentModal').modal('hide');">Clear Log Files</button>
2424
<button type="button" class="btn btn-lg btn-block btn-danger" onclick="action('shutdown');$('#contentModal').modal('hide');">{{'Shutdown WebControl/WebMCP' if docker else 'Shutdown WebControl'}}</button>
25-
{% if docker == false %}
26-
<button type="button" class="btn btn-lg btn-block {{'btn-primary' if updateAvailable else 'btn-secondary'}}" onclick="action('updatePyInstaller');$('#contentModal').modal('hide');" {{'' if updateAvailable else 'disabled'}}>Update WebControl: {{updateRelease}}</button>
27-
{% endif %}
2825
</div>
2926
</div>
3027
</div>

templates/base.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
</div>
4242
</li>
4343
<li class="nav-item" id="actionsNavItem">
44-
<span id="actionsBadge" class="badge badge-pill badge-primary" style="float:right;margin-bottom:-10px;"></span>
4544
<a class="nav-link" href="#" onclick="requestPage('actions');">Actions</a>
4645
</li>
4746
<li class="nav-item dropdown">
@@ -70,14 +69,17 @@
7069
</div>
7170
</li>
7271
<li class="nav-item dropdown">
72+
<span id="helpBadge" class="badge badge-pill badge-primary" style="float:left;margin-bottom:-10px;"></span>
7373
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown4" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
7474
Help
7575
</a>
7676
<div class="dropdown-menu" aria-labelledby="navbarDropdown4">
7777
<a class="dropdown-item" href="#" onclick="requestPage('gettingStarted');">Getting Started</a>
7878
<a class="dropdown-item" href="#" onclick="requestPage('help');">Help!</a>
7979
<a class="dropdown-item" href="#" onclick="requestPage('about');">About</a>
80-
</div>
80+
<span id="updateBadge" class="badge badge-pill badge-primary" style="float:left;margin-bottom:-10px;"></span>
81+
<a class="dropdown-item" href="#" onclick="requestPage('releases');">Update</a>
82+
</div>
8183
</li>
8284
</ul>
8385
<div id="clientStatus" class="alert alert-danger">Not Connect</div>

0 commit comments

Comments
 (0)