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.