Print this page
3166 feed generation needs performance improvement
3306 feed returns invalid last-modified header
@@ -33,16 +33,17 @@
import cStringIO
import datetime
import httplib
import os
import rfc822
+import sys
import time
import urllib
import xml.dom.minidom as xmini
from pkg.misc import get_rel_path, get_res_path
-import pkg.catalog as catalog
+import pkg.server.catalog as catalog
import pkg.fmri as fmri
import pkg.Uuid25 as uuid
MIME_TYPE = 'application/atom+xml'
CACHE_FILENAME = "feed.xml"
@@ -199,11 +200,11 @@
"-": ["Removed", "%s was removed from the repository."],
"U": ["Updated", "%s, an update to an existing package, was added to "
"the repository."]
}
-def add_transaction(request, scfg, rcfg, doc, feed, txn):
+def add_transaction(request, scfg, rcfg, doc, feed, txn, fmris):
"""Each transaction is an entry. We have non-trivial content, so we
can omit summary elements.
"""
e = doc.createElement("entry")
@@ -227,18 +228,15 @@
# non-well-formed document.)
op_title = "Unknown Operation"
op_content = "%s was changed in the repository."
if txn["operation"] == "+":
- c = scfg.updatelog.catalog
# Get all FMRIs matching the current FMRI's package name.
- matches = catalog.extract_matching_fmris(c.fmris(),
- f.get_name(), matcher=fmri.exact_name_match)
-
- if len(matches) > 1:
- # Get the oldest fmri (it's the last entry).
- of = matches[-1]
+ matches = fmris[f.pkg_name]
+ if len(matches["versions"]) > 1:
+ # Get the oldest fmri.
+ of = matches[str(matches["versions"][0])][0]
# If the current fmri isn't the oldest one, then this
# is an update to the package.
if f != of:
# If there is more than one matching FMRI, and
@@ -305,13 +303,19 @@
# The feed should be presented in reverse chronological order.
def compare_ul_entries(a, b):
return cmp(ults_to_ts(a["timestamp"]),
ults_to_ts(b["timestamp"]))
+ # Get the entire catalog in the format returned by catalog.cache_fmri,
+ # so that we don't have to keep looking for possible matches.
+ fmris = {}
+ catalog.ServerCatalog.read_catalog(fmris,
+ scfg.updatelog.catalog.catalog_root)
+
for txn in sorted(scfg.updatelog.gen_updates_as_dictionaries(feed_ts),
cmp=compare_ul_entries, reverse=True):
- add_transaction(request, scfg, rcfg, d, feed, txn)
+ add_transaction(request, scfg, rcfg, d, feed, txn, fmris)
d.writexml(cf)
def __get_cache_pathname(scfg):
return os.path.join(scfg.repo_root, CACHE_FILENAME)
@@ -412,12 +416,14 @@
cf.close()
# Now that the feed has been generated, set the headers
# correctly and return it.
response.headers['Content-type'] = MIME_TYPE
- response.headers['Last-Modified'] = \
- datetime.datetime.now().isoformat()
+
+ # Return the current time and date in GMT.
+ response.headers['Last-Modified'] = rfc822.formatdate()
+
response.headers['Content-length'] = len(buf)
return buf
else:
# If the server isn't operating in readonly mode, the
# feed can be generated and cached in inst_dir.