Remove Windows exe auto updater

This commit is contained in:
JonnyWong16 2020-12-24 15:26:35 -08:00
parent 2cc5bf812f
commit 6e160bb8f8
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
10 changed files with 14 additions and 280 deletions

View file

@ -71,11 +71,6 @@ jobs:
run: | run: |
pyinstaller -y ./package/Tautulli-${{ matrix.os }}.spec pyinstaller -y ./package/Tautulli-${{ matrix.os }}.spec
- name: Move Windows Updater Files
if: matrix.os == 'windows'
run: |
Move-Item dist\updater\* dist\Tautulli\ -Force
- name: Create Windows Installer - name: Create Windows Installer
uses: joncloud/makensis-action@v3.4 uses: joncloud/makensis-action@v3.4
if: matrix.os == 'windows' if: matrix.os == 'windows'

View file

@ -61,7 +61,7 @@
Update your Docker container or <a href="#" id="updateDismiss">Dismiss</a> Update your Docker container or <a href="#" id="updateDismiss">Dismiss</a>
% elif plexpy.INSTALL_TYPE == 'snap': % elif plexpy.INSTALL_TYPE == 'snap':
Update your Snap package or <a href="#" id="updateDismiss">Dismiss</a> Update your Snap package or <a href="#" id="updateDismiss">Dismiss</a>
% elif plexpy.INSTALL_TYPE == 'macos': % elif plexpy.INSTALL_TYPE in ('windows', 'macos'):
<a href="${anon_url('https://github.com/%s/%s/releases/tag/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO, plexpy.LATEST_RELEASE))}" target="_blank" rel="noreferrer">Download</a> and install the latest version or <a href="#" id="updateDismiss">Dismiss</a> <a href="${anon_url('https://github.com/%s/%s/releases/tag/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO, plexpy.LATEST_RELEASE))}" target="_blank" rel="noreferrer">Download</a> and install the latest version or <a href="#" id="updateDismiss">Dismiss</a>
% else: % else:
<a href="update">Update</a> or <a href="#" id="updateDismiss">Dismiss</a> <a href="update">Update</a> or <a href="#" id="updateDismiss">Dismiss</a>
@ -350,7 +350,7 @@ ${next.modalIncludes()}
msg += 'Update your Docker container or <a href="#" id="updateDismiss">Dismiss</a>'; msg += 'Update your Docker container or <a href="#" id="updateDismiss">Dismiss</a>';
} else if (result.install_type === 'snap') { } else if (result.install_type === 'snap') {
msg += 'Update your Snap package or <a href="#" id="updateDismiss">Dismiss</a>'; msg += 'Update your Snap package or <a href="#" id="updateDismiss">Dismiss</a>';
} else if (result.install_type === 'macos') { } else if (result.install_type === 'windows' || result.install_type === 'macos') {
msg += '<a href="' + result.release_url + '" target="_blank" rel="noreferrer">Download</a> and install the latest version or <a href="#" id="updateDismiss">Dismiss</a>' msg += '<a href="' + result.release_url + '" target="_blank" rel="noreferrer">Download</a> and install the latest version or <a href="#" id="updateDismiss">Dismiss</a>'
} else { } else {
msg += '<a href="update">Update</a> or <a href="#" id="updateDismiss">Dismiss</a>'; msg += '<a href="update">Update</a> or <a href="#" id="updateDismiss">Dismiss</a>';

View file

@ -220,7 +220,7 @@
<p class="help-block">Check for Tautulli updates periodically.</p> <p class="help-block">Check for Tautulli updates periodically.</p>
</div> </div>
<div id="git_update_options"> <div id="git_update_options">
% if not plexpy.SNAP and not (plexpy.FROZEN and common.PLATFORM == 'Darwin'): % if not plexpy.SNAP and not plexpy.FROZEN:
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" id="plexpy_auto_update" name="plexpy_auto_update" value="1" ${config['plexpy_auto_update']} ${docker_setting}> Update Automatically ${docker_msg | n} <input type="checkbox" id="plexpy_auto_update" name="plexpy_auto_update" value="1" ${config['plexpy_auto_update']} ${docker_setting}> Update Automatically ${docker_msg | n}

View file

@ -3,7 +3,6 @@
import sys import sys
sys.modules['FixTk'] = None sys.modules['FixTk'] = None
excludes = ['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter']
block_cipher = None block_cipher = None
analysis = Analysis( analysis = Analysis(
@ -13,27 +12,13 @@ analysis = Analysis(
('..\\data', 'data'), ('..\\data', 'data'),
('..\\CHANGELOG.md', '.'), ('..\\CHANGELOG.md', '.'),
('..\\LICENSE', '.'), ('..\\LICENSE', '.'),
('..\\branch.txt', '.'),
('..\\version.txt', '.'), ('..\\version.txt', '.'),
('..\\lib\\ipwhois\\data', 'data'), ('..\\lib\\ipwhois\\data', 'data')
('TautulliUpdateTask.xml', '.')
], ],
excludes=excludes, excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'],
hiddenimports=['pkg_resources.py2_warn', 'cheroot.ssl', 'cheroot.ssl.builtin'], hiddenimports=['pkg_resources.py2_warn', 'cheroot.ssl', 'cheroot.ssl.builtin'],
cipher=block_cipher cipher=block_cipher
) )
updater_analysis = Analysis(
['updater-windows.py'],
pathex=['lib'],
excludes=excludes,
cipher=block_cipher
)
MERGE(
(analysis, 'Tautulli', 'Tautulli'),
(updater_analysis, 'updater', 'updater')
)
pyz = PYZ( pyz = PYZ(
analysis.pure, analysis.pure,
analysis.zipped_data, analysis.zipped_data,
@ -54,24 +39,3 @@ coll = COLLECT(
analysis.datas, analysis.datas,
name='Tautulli' name='Tautulli'
) )
updater_pyz = PYZ(
updater_analysis.pure,
updater_analysis.zipped_data,
cipher=block_cipher
)
updater_exe = EXE(
updater_pyz,
updater_analysis.scripts,
exclude_binaries=True,
name='updater',
console=False,
icon='..\\data\\interfaces\\default\\images\\logo-circle.ico'
)
coll = COLLECT(
updater_exe,
updater_analysis.binaries,
updater_analysis.zipfiles,
updater_analysis.datas,
name='updater'
)

View file

@ -77,13 +77,9 @@ InstallDir "$PROGRAMFILES64\${APP_NAME}"
!include Sections.nsh !include Sections.nsh
Var /GLOBAL norun
Var /GLOBAL nolaunch Var /GLOBAL nolaunch
!include "MUI.nsh" !include "MUI.nsh"
!include "FileFunc.nsh"
!insertmacro GetParameters
!insertmacro GetOptions
!define MUI_ABORTWARNING !define MUI_ABORTWARNING
!define MUI_UNABORTWARNING !define MUI_UNABORTWARNING
@ -129,10 +125,6 @@ SetOverwrite on
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
File /nonfatal /a /r "..\dist\${APP_NAME}\" File /nonfatal /a /r "..\dist\${APP_NAME}\"
nsExec::Exec "$INSTDIR\updater.exe --xml"
nsExec::Exec '$SYSDIR\SCHTASKS /Create /TN TautulliUpdateTask /XML "$INSTDIR\TautulliUpdateTask.xml" /F'
StrCmp $norun 1 +3 0
IfSilent 0 +2 IfSilent 0 +2
ExecShell "" "$INSTDIR\${MAIN_APP_EXE}" $nolaunch ExecShell "" "$INSTDIR\${MAIN_APP_EXE}" $nolaunch
SectionEnd SectionEnd
@ -218,20 +210,11 @@ RmDir "$SMPROGRAMS\${APP_NAME}"
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}" DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}" DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
nsExec::Exec "$SYSDIR\SCHTASKS /Delete /TN TautulliUpdateTask /F"
SectionEnd SectionEnd
###################################################################### ######################################################################
Function .onInit Function .onInit
StrCpy $norun 0
${GetParameters} $CMDLINE
${GetOptions} "$CMDLINE" "/NORUN" $R0
IfErrors +2 0
StrCpy $norun 1
IfSilent 0 +2 IfSilent 0 +2
StrCpy $nolaunch "--nolaunch" StrCpy $nolaunch "--nolaunch"

Binary file not shown.

View file

@ -1,5 +1,4 @@
apscheduler==3.6.3 apscheduler==3.6.3
psutil==5.8.0
pyinstaller==4.2 pyinstaller==4.2
pyopenssl==20.0.1 pyopenssl==20.0.1
pycryptodomex==3.9.9 pycryptodomex==3.9.9

View file

@ -1,194 +0,0 @@
# -*- coding: utf-8 -*-
# This file is part of Tautulli.
#
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
from logging import handlers
import argparse
import logging
import os
import psutil
import re
import requests
import shutil
import subprocess
import sys
import tempfile
import xml.etree.ElementTree as ET
SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__))
CREATE_NO_WINDOW = 0x08000000
REPO_URL = 'https://api.github.com/repos/Tautulli/Tautulli'
LOGFILE = 'updater.log'
LOGPATH = os.path.join(SCRIPT_PATH, LOGFILE)
MAX_SIZE = 1000000 # 1MB
MAX_FILES = 1
def init_logger():
log = logging.getLogger('updater')
log.setLevel(logging.DEBUG)
file_formatter = logging.Formatter(
'%(asctime)s - %(levelname)-7s :: %(threadName)s : Tautulli Updater :: %(message)s',
'%Y-%m-%d %H:%M:%S')
file_handler = handlers.RotatingFileHandler(
LOGPATH, maxBytes=MAX_SIZE, backupCount=MAX_FILES, encoding='utf-8')
file_handler.setFormatter(file_formatter)
log.addHandler(file_handler)
return log
def read_file(file_path):
try:
with open(file_path, 'r') as f:
return f.read().strip(' \n\r')
except Exception as e:
logger.error('Read file error: %s', e)
raise Exception(1)
def request_json(url):
try:
response = requests.get(url)
response.raise_for_status()
return response.json()
except Exception as e:
logger.error('Request error: %s', e)
raise Exception(2)
def kill_and_get_processes(process_name):
processes = []
for process in psutil.process_iter():
if process.name() == process_name:
processes.append(process.cmdline())
logger.info('Sending SIGTERM to %s (PID=%d)', process.name(), process.pid)
process.terminate()
return processes
def update_tautulli():
logger.info('Starting Tautulli update check')
branch = read_file(os.path.join(SCRIPT_PATH, 'branch.txt'))
logger.info('Branch: %s', branch)
current_version = read_file(os.path.join(SCRIPT_PATH, 'version.txt'))
logger.info('Current version: %s', current_version)
logger.info('Retrieving latest version from GitHub')
commits = request_json('{}/commits/{}'.format(REPO_URL, branch))
latest_version = commits['sha']
logger.info('Latest version: %s', latest_version)
if current_version == latest_version:
logger.info('Tautulli is already up to date')
return 0
logger.info('Comparing version on GitHub')
compare = request_json('{}/compare/{}...{}'.format(REPO_URL, latest_version, current_version))
commits_behind = compare['behind_by']
logger.info('Commits behind: %s', commits_behind)
if commits_behind <= 0:
logger.info('Tautulli is already up to date')
return 0
logger.info('Retrieving releases on GitHub')
releases = request_json('{}/releases'.format(REPO_URL))
if branch == 'master':
release = next((r for r in releases if not r['prerelease']), releases[0])
else:
release = next((r for r in releases), releases[0])
version = release['tag_name']
logger.info('Release: %s', version)
win_exe = 'application/vnd.microsoft.portable-executable'
asset = next((a for a in release['assets'] if a['content_type'] == win_exe), None)
download_url = asset['browser_download_url']
download_file = asset['name']
file_path = os.path.join(tempfile.gettempdir(), download_file)
logger.info('Downloading installer to temporary directory: %s', file_path)
try:
with requests.get(download_url, stream=True) as r:
with open(file_path, 'wb') as f:
shutil.copyfileobj(r.raw, f)
except Exception as e:
logger.error('Failed to download %s: %s', download_file, e)
return 2
logger.info('Stopping Tautulli processes')
try:
processes = kill_and_get_processes('Tautulli.exe')
except Exception as e:
logger.error('Failed to stop Tautulli: %s', e)
return 1
logger.info('Running %s', download_file)
try:
subprocess.call([file_path, '/S', '/NORUN', '/D=' + SCRIPT_PATH], creationflags=CREATE_NO_WINDOW)
status = 0
except Exception as e:
logger.exception('Failed to install Tautulli: %s', e)
status = -1
if status == 0:
logger.info('Tautulli updated to %s', version)
logger.info('Restarting Tautulli processes')
for process in processes:
logger.info('Starting process: %s', process)
subprocess.Popen(process, creationflags=CREATE_NO_WINDOW)
return status
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--xml', action='store_true')
opts = parser.parse_args()
if opts.xml:
xml_path = os.path.join(SCRIPT_PATH, 'TautulliUpdateTask.xml')
tree = ET.parse(xml_path)
task = tree.getroot()
match = re.match(r'{(.*)}', task.tag)
namespace = match.group(1)
namespaces = {'': namespace}
ET.register_namespace('', namespace)
for elem in task.iterfind('./Actions/Exec/Command', namespaces=namespaces):
elem.text = os.path.join(SCRIPT_PATH, 'updater.exe')
for elem in task.iterfind('./Actions/Exec/WorkingDirectory', namespaces=namespaces):
elem.text = SCRIPT_PATH
tree.write(xml_path, encoding='UTF-16')
else:
logger = init_logger()
try:
status_code = update_tautulli()
except Exception as exc:
status_code = exc
logger.debug('Update function returned status code %s', status_code)
sys.exit(status_code)

View file

@ -2295,12 +2295,7 @@ def upgrade():
return return
def shutdown(restart=False, update=False, checkout=False, reset=False, def shutdown(restart=False, update=False, checkout=False, reset=False):
_shutdown=True):
if FROZEN and common.PLATFORM == 'Windows' and update:
restart = False
_shutdown = False
webstart.stop() webstart.stop()
# Shutdown the websocket connection # Shutdown the websocket connection
@ -2373,15 +2368,14 @@ def shutdown(restart=False, update=False, checkout=False, reset=False,
else: else:
logger.info("Tautulli is shutting down...") logger.info("Tautulli is shutting down...")
if _shutdown: logger.shutdown()
logger.shutdown()
if WIN_SYS_TRAY_ICON: if WIN_SYS_TRAY_ICON:
WIN_SYS_TRAY_ICON.shutdown() WIN_SYS_TRAY_ICON.shutdown()
elif MAC_SYS_TRAY_ICON: elif MAC_SYS_TRAY_ICON:
MAC_SYS_TRAY_ICON.shutdown() MAC_SYS_TRAY_ICON.shutdown()
os._exit(0) os._exit(0)
def generate_uuid(): def generate_uuid():

View file

@ -278,8 +278,7 @@ def check_github(scheduler=False, notify=False, use_cache=False):
logger.warn('Tautulli is running using Python 2. Unable to run automatic update.') logger.warn('Tautulli is running using Python 2. Unable to run automatic update.')
elif scheduler and plexpy.CONFIG.PLEXPY_AUTO_UPDATE and \ elif scheduler and plexpy.CONFIG.PLEXPY_AUTO_UPDATE and \
not plexpy.DOCKER and not plexpy.SNAP and \ not plexpy.DOCKER and not plexpy.SNAP and not plexpy.FROZEN:
not (plexpy.FROZEN and common.PLATFORM == 'Darwin'):
logger.info('Running automatic update.') logger.info('Running automatic update.')
plexpy.shutdown(restart=True, update=True) plexpy.shutdown(restart=True, update=True)
@ -297,15 +296,9 @@ def update():
if not plexpy.UPDATE_AVAILABLE: if not plexpy.UPDATE_AVAILABLE:
return return
if plexpy.INSTALL_TYPE in ('docker', 'snap', 'macos'): if plexpy.INSTALL_TYPE in ('docker', 'snap', 'windows', 'macos'):
return return
elif plexpy.INSTALL_TYPE == 'windows':
logger.info('Calling Windows scheduled task to update Tautulli')
CREATE_NO_WINDOW = 0x08000000
subprocess.Popen(['SCHTASKS', '/Run', '/TN', 'TautulliUpdateTask'],
creationflags=CREATE_NO_WINDOW)
elif plexpy.INSTALL_TYPE == 'git': elif plexpy.INSTALL_TYPE == 'git':
output, err = runGit('pull --ff-only {} {}'.format(plexpy.CONFIG.GIT_REMOTE, output, err = runGit('pull --ff-only {} {}'.format(plexpy.CONFIG.GIT_REMOTE,
plexpy.CONFIG.GIT_BRANCH)) plexpy.CONFIG.GIT_BRANCH))