4
Scan FTP and HTTP sites specified for each ProductSeries in the database
5
to identify files and create new ProductRelease records for them.
11
from urllib import urlretrieve
12
from urlparse import urlsplit
13
from optparse import OptionParser
15
from zope.component import getUtility
17
from canonical.dyson.hose import Hose
18
from canonical.dyson.filter import Cache
19
from canonical.launchpad.interfaces import IProductSet, IProductReleaseSet
20
from canonical.librarian.interfaces import IFileUploadClient
21
from canonical.lp import initZopeless
22
from canonical.config import config
23
from canonical.launchpad.scripts import (execute_zcml_for_scripts,
24
logger, logger_options)
26
from hct.util import path
30
# Parse command-line arguments
31
parser = OptionParser()
32
logger_options(parser)
33
(options, args) = parser.parse_args()
36
log = logger(options, "dyson")
37
ztm = initZopeless(dbuser=config.dyson.dbuser, implicitBegin=False)
39
cache = Cache(config.dyson.cache_path, log_parent=log)
41
for product_name, filters in get_filters(ztm):
42
hose = Hose(filters, cache)
43
for series_name, url in hose:
44
if series_name is not None:
45
new_release(ztm, product_name, series_name, url)
47
log.warning("File in %s found that matched no glob: %s",
53
"""Build the list of products and filters.
55
Returns a list of (product_name, filters) for each product in the database,
56
where the filter keys are series names.
61
products = getUtility(IProductSet)
62
for product in products:
65
for series in product.serieslist:
66
if series.releasefileglob is None or series.releasefileglob == "":
69
releasefileglob = series.releasefileglob
71
if series.releaseroot is None or series.releaseroot == "":
72
if product.releaseroot is None or product.releaseroot == "":
75
releaseroot = product.releaseroot
77
releaseroot = series.releaseroot
79
filters[series.name] = (releaseroot, releasefileglob)
84
log.info("%s has %d series with information", product.name,
87
todo.append((product.name, filters))
92
def new_release(ztm, product_name, series_name, url):
93
"""Create a new ProductRelease.
95
Downloads the file and creates a new ProductRelease associated with
98
filename = urlsplit(url)[2]
99
slash = filename.rfind("/")
101
filename = filename[slash + 1:]
102
log.debug("Filename portion is %s", filename)
104
version = path.split_version(path.name(filename))[1]
105
log.debug("Version is %s", version)
107
log.error("Unable to parse version from %s", url)
110
(mimetype, encoding) = mimetypes.guess_type(url)
111
log.debug("Mime Type is %s", mimetype)
113
mimetype = "application/octet-stream"
115
log.debug("Downloading %s", url)
117
(local, headers) = urlretrieve(url)
118
stat = os.stat(local)
120
log.error("Download of %s failed, can't create release")
123
log.error("Unable to stat downloaded file, can't create release")
126
open_file = open(local, "r")
131
product = getUtility(IProductSet)[product_name]
132
series = product.getSeries(series_name)
133
log.info("Creating new release %s for %s %s",
134
version, product.name, series.name)
136
release = getUtility(IProductReleaseSet).\
137
new(version, series, product.owner)
138
log.debug("Created ProductRelease %d", release.id)
140
alias_id = getUtility(IFileUploadClient).\
141
addFile(filename, stat.st_size, open_file, mimetype)
142
log.debug("Created LibraryFileAlias %d", alias_id)
144
release.addFileAlias(alias_id)
152
if __name__ == "__main__":
153
execute_zcml_for_scripts()