[Python-checkins] r56598 - tracker/instances/python-dev/detectors/changes_xml_writer.py

erik.forsberg python-checkins at python.org
Sat Jul 28 01:17:58 CEST 2007


Author: erik.forsberg
Date: Sat Jul 28 01:17:57 2007
New Revision: 56598

Removed:
   tracker/instances/python-dev/detectors/changes_xml_writer.py
Log:
Need a python 2.4 compatible variant

Deleted: /tracker/instances/python-dev/detectors/changes_xml_writer.py
==============================================================================
--- /tracker/instances/python-dev/detectors/changes_xml_writer.py	Sat Jul 28 01:17:57 2007
+++ (empty file)
@@ -1,191 +0,0 @@
-#
-#  changes.xml writer detector.
-#
-# Copyright (c) 2007  Michal Kwiatkowski <constant.beta at gmail.com>
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-#
-# * Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-#
-# * Neither the name of the author nor the names of his contributors
-#   may be used to endorse or promote products derived from this software
-#   without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-"""changes.xml writer detector -- save each database change to an XML file.
-
-Root element is called `changes` and it has at most `ChangesXml.max_items`
-children, each called a `change`. Each `change` has the following attributes:
-
-:date:  date in RFC2822 format when the change was made
-:id:    unique identifier of this change (note: not an integer)
-:type:  type of this change (see below)
-
-A structure of a `change` depends on its `type`. Currently implemented
-change types and their formats are listed below.
-
-* type = `file-added`
-
-  Describes a new file attached to an existing issue. Child elements:
-
-  :file-id:   unique integer identifier of the file
-  :file-name: name of the uploaded file
-  :file-type: MIME type of the file content
-  :file-url:  permanent URL of the file
-  :issue-id:  unique integer identifier of an issue this file is attached to
-"""
-
-import os
-import urllib
-from xml.dom import minidom
-from xml.parsers.expat import ExpatError
-from time import gmtime, strftime
-
-# Relative to tracker home directory.
-FILENAME = os.path.join('%(TEMPLATES)s', 'recent-changes.xml')
-
-
-def tracker_url(db):
-    return str(db.config.options[('tracker', 'web')])
-
-def changes_xml_path(db):
-    return os.path.join(db.config.HOME, FILENAME % db.config.options)
-
-def rfc2822_date():
-    return strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
-
-class File(object):
-    def __init__(self, db, id, issue_id):
-        self.db = db
-        self.id = id
-        self.issue_id = issue_id
-
-        self.name = db.file.get(id, 'name')
-        self.type = db.file.get(id, 'type')
-        # Based on roundup.cgi.templating._HTMLItem.download_url().
-        self.download_url = tracker_url(self.db) +\
-            urllib.quote('%s%s/%s' % ('file', self.id, self.name))
-
-class ChangesXml(object):
-    # Maximum number of changes stored in a file.
-    max_items = 20
-
-    def __init__(self, filename):
-        self.filename = filename
-        self._read_document()
-        self.modified = False
-
-    def save(self):
-        if not self.modified:
-            return
-
-        self._trim_to_max_items()
-
-        fd = open(self.filename, 'w')
-        self.document.writexml(fd, encoding="UTF-8")
-        fd.close()
-
-    def add_file(self, file):
-        change = self._change("file%s-added-to-issue%s" % (file.id, file.issue_id),
-                              "file-added")
-
-        change.appendChild(self._element_with_text("file-id",   file.id))
-        change.appendChild(self._element_with_text("file-name", file.name))
-        change.appendChild(self._element_with_text("file-type", file.type))
-        change.appendChild(self._element_with_text("file-url",  file.download_url))
-        change.appendChild(self._element_with_text("issue-id",  file.issue_id))
-
-        self.root.appendChild(change)
-        self.modified = True
-
-    def add_files(self, files):
-        for file in files:
-            self.add_file(file)
-
-    def _change(self, id, type):
-        """Return new 'change' element of a given type.
-           <change id='id' date='now' type='type'></change>
-        """
-        change = self.document.createElement("change")
-        change.setAttribute("id",   id)
-        change.setAttribute("type", type)
-        change.setAttribute("date", rfc2822_date())
-        return change
-
-    def _element_with_text(self, name, value):
-        """Return new element with given name and text node as a value.
-           <name>value</name>
-        """
-        element = self.document.createElement(name)
-        text = self.document.createTextNode(str(value))
-        element.appendChild(text)
-        return element
-
-    def _trim_to_max_items(self):
-        """Remove changes exceeding self.max_items.
-        """
-        # Assumes that changes are stored sequentially from oldest to newest.
-        # Will do for now.
-        for change in self.root.getElementsByTagName("change")[0:-self.max_items]:
-            self.root.removeChild(change)
-
-    def _read_document(self):
-        try:
-            self.document = minidom.parse(self.filename)
-            self.root = self.document.firstChild
-        except IOError, e:
-            # File not found, create a new one then.
-            if e.errno != 2:
-                raise
-            self._create_new_document()
-        except ExpatError:
-            # File has been damaged, forget about it and create a new one.
-            self._create_new_document()
-
-    def _create_new_document(self):
-        self.document = minidom.Document()
-        self.root = self.document.createElement("changes")
-        self.document.appendChild(self.root)
-
-def get_new_files_ids(issue_now, issue_then):
-    """Return ids of files added between `now` and `then`.
-    """
-    files_now = set(issue_now['files'])
-    files_then = set(issue_then['files']) if issue_then else set()
-    return map(int, files_now - files_then)
-
-def file_added_to_issue(db, cl, issue_id, olddata):
-    try:
-        changes   = ChangesXml(changes_xml_path(db))
-        issue     = db.issue.getnode(issue_id)
-        new_files = [ File(db, id, issue_id) for id in get_new_files_ids(issue, olddata) ]
-
-        changes.add_files(new_files)
-        changes.save()
-    except:
-        # We can't mess up with a database commit.
-        pass
-
-
-def init(db):
-    db.issue.react('create', file_added_to_issue)
-    db.issue.react('set',    file_added_to_issue)


More information about the Python-checkins mailing list