1
0
Fork 0
fgmeta/maintain_catalog.py

199 lines
5.6 KiB
Python
Raw Normal View History

2015-06-04 21:09:46 +00:00
#!/usr/bin/python
import os, sys, re, glob
import subprocess
import sgprops
2015-07-23 03:35:57 +00:00
import argparse
import urllib2
2015-07-26 03:45:01 +00:00
import package as pkg
2015-06-04 21:09:46 +00:00
import svn_catalog_repository
import git_catalog_repository
import git_discrete_repository
2015-07-23 03:35:57 +00:00
parser = argparse.ArgumentParser()
parser.add_argument("--clean", help="Regenerate every package",
action="store_true")
parser.add_argument("--update", help="Update/pull SCM source",
action="store_true")
2015-07-28 02:45:55 +00:00
parser.add_argument("--no-update", help="Disable updating from SCM source",
action="store_true")
2015-07-23 03:35:57 +00:00
parser.add_argument("dir", help="Catalog directory")
args = parser.parse_args()
includePaths = []
2015-07-15 02:37:39 +00:00
2015-06-04 21:09:46 +00:00
def scanPackages(globPath):
result = []
print "Scanning", globPath
print os.getcwd()
for d in glob.glob(globPath):
# check dir contains at least one -set.xml file
if len(glob.glob(os.path.join(d, "*-set.xml"))) == 0:
print "no -set.xml in", d
continue
2015-07-26 03:45:01 +00:00
result.append(pkg.PackageData(d))
2015-06-04 21:09:46 +00:00
return result
def initScmRepository(node):
scmType = node.getValue("type")
if (scmType == "svn"):
svnPath = node.getValue("path")
return svn_catalog_repository.SVNCatalogRepository(svnPath)
elif (scmType == "git"):
2015-06-04 21:09:46 +00:00
gitPath = node.getValue("path")
usesSubmodules = node.getValue("uses-submodules", False)
return git_catalog_repository.GitCatalogRepository(gitPath, usesSubmodules)
elif (scmType == "git-discrete"):
return git_discrete_repository.GitDiscreteSCM(node)
elif (scmType == None):
2015-06-04 21:09:46 +00:00
raise RuntimeError("No scm/type defined in catalog configuration")
else:
raise RuntimeError("Unspported SCM type:" + scmType)
2015-06-04 21:09:46 +00:00
def processUpload(node, outputPath):
if not node.getValue("enabled", True):
print "Upload disabled"
return
2015-06-04 21:09:46 +00:00
uploadType = node.getValue("type")
if (uploadType == "rsync"):
subprocess.call(["rsync", node.getValue("args", "-az"), ".",
2015-06-04 21:09:46 +00:00
node.getValue("remote")],
cwd = outputPath)
2015-07-23 03:35:57 +00:00
elif (uploadType == "rsync-ssh"):
subprocess.call(["rsync", node.getValue("args", "-azve"),
"ssh", ".",
node.getValue("remote")],
cwd = outputPath)
elif (uploadType == "scp"):
2015-07-23 03:35:57 +00:00
subprocess.call(["scp", node.getValue("args", "-r"), ".",
node.getValue("remote")],
cwd = outputPath)
2015-06-04 21:09:46 +00:00
else:
raise RuntimeError("Unsupported upload type:" + uploadType)
# dictionary
2015-06-04 21:09:46 +00:00
packages = {}
2015-07-23 03:35:57 +00:00
rootDir = args.dir
if not os.path.isabs(rootDir):
rootDir = os.path.abspath(rootDir)
os.chdir(rootDir)
2015-06-04 21:09:46 +00:00
configPath = 'catalog.config.xml'
if not os.path.exists(configPath):
2015-06-04 21:09:46 +00:00
raise RuntimeError("no config file found at:" + configPath)
config = sgprops.readProps(configPath)
2015-06-04 21:09:46 +00:00
# out path
outPath = config.getValue('output-dir')
if outPath is None:
# default out path
outPath = os.path.join(rootDir, "output")
elif not os.path.isabs(outPath):
outPath = os.path.join(rootDir, "output")
2015-07-23 03:35:57 +00:00
if args.clean:
print "Cleaning output"
shutil.rmtree(outPath)
if not os.path.exists(outPath):
os.mkdir(outPath)
2015-06-04 21:09:46 +00:00
thumbnailPath = os.path.join(outPath, config.getValue('thumbnail-dir', "thumbnails"))
if not os.path.exists(thumbnailPath):
os.mkdir(thumbnailPath)
thumbnailUrl = config.getValue('thumbnail-url')
for i in config.getChildren("include-dir"):
if not os.path.exists(i.value):
print "Skipping missing include path:", i.value
continue
includePaths.append(i.value)
mirrorUrls = []
2015-06-04 21:09:46 +00:00
# contains existing catalog
existingCatalogPath = os.path.join(outPath, 'catalog.xml')
scmRepo = initScmRepository(config.getChild('scm'))
2015-07-28 02:45:55 +00:00
if args.update or (not args.no-update and scmRepo.getValue("update")):
scmRepo.update()
2015-06-04 21:09:46 +00:00
# scan the directories in the aircraft paths
for g in config.getChildren("aircraft-dir"):
for p in scanPackages(g.value):
2015-06-04 21:09:46 +00:00
packages[p.id] = p
2015-07-23 03:35:57 +00:00
if not os.path.exists(existingCatalogPath):
try:
# can happen on new or from clean, try to pull current
# catalog from the upload location
response = urllib2.urlopen(config.getValue("template/url"), timeout = 5)
content = response.read()
f = open(existingCatalogPath, 'w' )
f.write( content )
f.close()
except urllib2.URLError as e:
print "Downloading current catalog failed", e
if os.path.exists(existingCatalogPath):
try:
previousCatalog = sgprops.readProps(existingCatalogPath)
except:
print "Previous catalog is malformed"
previousCatalog = sgprops.Node()
for p in previousCatalog.getChildren("package"):
pkgId = p.getValue("id")
if not pkgId in packages.keys():
print "Orphaned old package:", pkgId
continue
2015-06-04 21:09:46 +00:00
packages[pkgId].setPreviousData(p)
else:
print "No previous catalog"
2015-06-04 21:09:46 +00:00
catalogNode = sgprops.Node("catalog")
2015-06-04 21:09:46 +00:00
sgprops.copy(config.getChild("template"), catalogNode)
mirrorUrls = (m.value for m in config.getChildren("mirror"))
2015-06-04 21:09:46 +00:00
packagesToGenerate = []
for p in packages.values():
p.scanSetXmlFiles(includePaths)
2015-07-15 02:37:39 +00:00
2015-06-04 21:09:46 +00:00
if (p.isSourceModified(scmRepo)):
packagesToGenerate.append(p)
else:
p.useExistingCatalogData()
2015-07-23 03:35:57 +00:00
# def f(x):
# x.generateZip(outPath)
# x.extractThumbnails(thumbnailPath)
# return True
#
# p = Pool(8)
# print(p.map(f,packagesToGenerate))
2015-06-04 21:09:46 +00:00
for p in packagesToGenerate:
2015-07-23 03:35:57 +00:00
p.generateZip(outPath)
p.extractThumbnails(thumbnailPath)
print "Creating catalog"
for p in packages.values():
2015-07-26 03:45:01 +00:00
catalogNode.addChild(p.packageNode(scmRepo, mirrorUrls, thumbnailUrl))
catalogNode.write(os.path.join(outPath, "catalog.xml"))
print "Uploading"
for up in config.getChildren("upload"):
processUpload(up, outPath)