You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
8.4 KiB

import re
import urllib
import ConfigParser
import sys
import os
import shutil
import zipfile
import subprocess
import fnmatch
import googlecode_upload
from distutils.core import setup
try:
import py2exe
except:
print "The Python module py2exe is required"
sys.exit(1)
try:
import pygithub.github
except:
print "The Python module pyGitHub is required"
sys.exit(1)
# mostly stolen from the SABnzbd package.py file
name = 'SickGear'
version = '0.1'
release = name + '-' + version
Win32ConsoleName = 'SickBeard-console.exe'
Win32WindowName = 'SickBeard.exe'
def findLatestBuild():
regex = "http\://SickGear\.googlecode\.com/files/SickGear\-win32\-alpha\-build(\d+)(?:\.\d+)?\.zip"
svnFile = urllib.urlopen("http://code.google.com/p/SickGear/downloads/list")
for curLine in svnFile.readlines():
match = re.search(regex, curLine)
if match:
groups = match.groups()
return int(groups[0])
return None
def recursive_find_data_files(root_dir, allowed_extensions=('*')):
to_return = {}
for (dirpath, dirnames, filenames) in os.walk(root_dir):
if not filenames:
continue
for cur_filename in filenames:
matches_pattern = False
for cur_pattern in allowed_extensions:
if fnmatch.fnmatch(cur_filename, '*.' + cur_pattern):
matches_pattern = True
if not matches_pattern:
continue
cur_filepath = os.path.join(dirpath, cur_filename)
to_return.setdefault(dirpath, []).append(cur_filepath)
return sorted(to_return.items())
def find_all_libraries(root_dirs):
libs = []
for cur_root_dir in root_dirs:
for (dirpath, dirnames, filenames) in os.walk(cur_root_dir):
if '__init__.py' not in filenames:
continue
libs.append(dirpath.replace(os.sep, '.'))
return libs
def allFiles(dir):
files = []
for file in os.listdir(dir):
fullFile = os.path.join(dir, file)
if os.path.isdir(fullFile):
files += allFiles(fullFile)
else:
files.append(fullFile)
return files
# save the original arguments and replace them with the py2exe args
oldArgs = []
if len(sys.argv) > 1:
oldArgs = sys.argv[1:]
del sys.argv[1:]
sys.argv.append('py2exe')
# clear the dist dir
if os.path.isdir('dist'):
shutil.rmtree('dist')
# root source dir
compile_dir = os.path.dirname(os.path.normpath(os.path.abspath(sys.argv[0])))
if not 'nopull' in oldArgs:
# pull new source from git
print 'Updating source from git'
p = subprocess.Popen('git pull origin master', shell=True, cwd=compile_dir)
o, e = p.communicate()
# figure out what build this is going to be
latestBuild = findLatestBuild()
if 'test' in oldArgs:
currentBuildNumber = str(latestBuild) + 'a'
else:
currentBuildNumber = latestBuild + 1
# set up the compilation options
data_files = recursive_find_data_files('data', ['gif', 'png', 'jpg', 'ico', 'js', 'css', 'tmpl'])
options = dict(
name=name,
version=release,
author='SickGear',
author_email='SickGear@outlook.com',
description=name + ' ' + release,
scripts=['SickBeard.py'],
packages=find_all_libraries(['sickbeard', 'lib']),
)
# set up py2exe to generate the console app
program = [{'script': 'SickBeard.py'}]
options['options'] = {'py2exe':
{
'bundle_files': 3,
'packages': ['Cheetah'],
'excludes': ['Tkconstants', 'Tkinter', 'tcl'],
'optimize': 2,
'compressed': 0
}
}
options['zipfile'] = 'lib/SickGear.zip'
options['console'] = program
options['data_files'] = data_files
# compile sickbeard-console.exe
setup(**options)
# rename the exe to sickbeard-console.exe
try:
if os.path.exists("dist/%s" % Win32ConsoleName):
os.remove("dist/%s" % Win32ConsoleName)
os.rename("dist/%s" % Win32WindowName, "dist/%s" % Win32ConsoleName)
except:
print "Cannot create dist/%s" % Win32ConsoleName
# sys.exit(1)
# we don't need this stuff when we make the 2nd exe
del options['console']
del options['data_files']
options['windows'] = program
# compile sickbeard.exe
setup(**options)
# compile sabToSickbeard.exe using the existing setup.py script
auto_process_dir = os.path.join(compile_dir, 'autoProcessTV')
p = subprocess.Popen([sys.executable, os.path.join(auto_process_dir, 'setup.py')], cwd=auto_process_dir, shell=True)
o, e = p.communicate()
# copy autoProcessTV files to the dist dir
auto_process_files = ['autoProcessTV/sabToSickBeard.py',
'autoProcessTV/hellaToSickBeard.py',
'autoProcessTV/autoProcessTV.py',
'autoProcessTV/autoProcessTV.cfg.sample',
'autoProcessTV/sabToSickBeard.exe']
os.makedirs('dist/autoProcessTV')
for curFile in auto_process_files:
newFile = os.path.join('dist', curFile)
print "Copying file from", curFile, "to", newFile
shutil.copy(curFile, newFile)
# compile updater.exe
setup(
options={'py2exe': {'bundle_files': 1}},
zipfile=None,
console=['updater.py'], requires=['Cheetah']
)
if 'test' in oldArgs:
print "Ignoring changelog for test build"
else:
# start building the CHANGELOG.txt
print 'Creating changelog'
gh = github.GitHub()
# read the old changelog and find the last commit from that build
lastCommit = ""
try:
cl = open("CHANGELOG.txt", "r")
lastCommit = cl.readlines()[0].strip()
cl.close()
except:
print "I guess there's no changelog"
newestCommit = ""
changeString = ""
# cycle through all the git commits and save their commit messages
for curCommit in gh.commits.forBranch('SickGear', 'SickGear'):
if curCommit.id == lastCommit:
break
if newestCommit == "":
newestCommit = curCommit.id
changeString += curCommit.message + "\n\n"
# if we didn't find any changes don't make a changelog file
if newestCommit != "":
newChangelog = open("CHANGELOG.txt", "w")
newChangelog.write(newestCommit + "\n\n")
newChangelog.write("Changelog for build " + str(currentBuildNumber) + "\n\n")
newChangelog.write(changeString)
newChangelog.close()
else:
print "No changes found, keeping old changelog"
# put the changelog in the compile dir
if os.path.exists("CHANGELOG.txt"):
shutil.copy('CHANGELOG.txt', 'dist/')
# figure out what we're going to call the zip file
print 'Zipping files...'
zipFilename = 'SickGear-win32-alpha-build' + str(currentBuildNumber)
if os.path.isfile(zipFilename + '.zip'):
zipNum = 2
while os.path.isfile(zipFilename + '.{0:0>2}.zip'.format(str(zipNum))):
zipNum += 1
zipFilename = zipFilename + '.{0:0>2}'.format(str(zipNum))
# get a list of files to add to the zip
zipFileList = allFiles('dist/')
# add all files to the zip
z = zipfile.ZipFile(zipFilename + '.zip', 'w', zipfile.ZIP_DEFLATED)
for file in zipFileList:
z.write(file, file.replace('dist/', zipFilename + '/'))
z.close()
print "Created zip at", zipFilename
# i store my google code username/pw in a config so i can have this file in public source control
config = ConfigParser.ConfigParser()
configFilename = os.path.join(compile_dir, "gc.ini")
config.read(configFilename)
gc_username = config.get("GC", "username")
gc_password = config.get("GC", "password")
# upload to google code unless I tell it not to
if "noup" not in oldArgs and "test" not in oldArgs:
print "Uploading zip to google code"
googlecode_upload.upload(os.path.abspath(zipFilename + ".zip"), "SickGear", gc_username, gc_password,
"Win32 alpha build " + str(currentBuildNumber) + " (unstable/development release)",
["Featured", "Type-Executable", "OpSys-Windows"])
if 'nopush' not in oldArgs and 'test' not in oldArgs:
# tag commit as a new build and push changes to github
print 'Tagging commit and pushing'
p = subprocess.Popen('git tag -a "build-' + str(currentBuildNumber) + '" -m "Windows build ' + zipFilename + '"',
shell=True, cwd=compile_dir)
o, e = p.communicate()
p = subprocess.Popen('git push --tags origin windows_binaries', shell=True, cwd=compile_dir)
o, e = p.communicate()