# Copyright (C) 2009 Google Inc. All rights reserved. # # 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 Google Inc. nor the names of its # 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. import re from model.queues import Queue from model.queuestatus import QueueStatus from model.workitems import WorkItems class Attachment(object): def __init__(self, attachment_id): self.id = attachment_id self._summary = None self._cached_queue_positions = None def summary(self): if self._summary: return self._summary self._summary = self._fetch_summary() return self._summary def position_in_queue(self, queue): return self._queue_positions().get(queue.name()) def status_for_queue(self, queue): # summary() is a horrible API and should be killed. queue_summary = self.summary().get(queue.name_with_underscores()) if not queue_summary: return None return queue_summary.get("status") def bug_id(self): return self.summary().get("bug_id") def _queue_positions(self): if self._cached_queue_positions: return self._cached_queue_positions # FIXME: Should we be mem-caching this? self._cached_queue_positions = self._calculate_queue_positions() return self._cached_queue_positions def _calculate_queue_positions(self): # We don't know how many rows there are in the table (as there can be stale rows # from queues that we no longer have), but it's certainly fewer that 1000. all_work_items = WorkItems.all().fetch(limit=1000) return dict([(items.queue.name(), items.display_position_for_attachment(self.id)) for items in all_work_items if items.queue]) # FIXME: This is controller/view code and does not belong in a model. def _fetch_summary(self): summary = { "attachment_id" : self.id } first_status = QueueStatus.all().filter('active_patch_id =', self.id).get() if not first_status: # We don't have any record of this attachment. return summary summary["bug_id"] = first_status.active_bug_id for queue in Queue.all(): summary[queue.name_with_underscores()] = None status = QueueStatus.all().filter('queue_name =', queue.name()).filter('active_patch_id =', self.id).order('-date').get() if status: # summary() is a horrible API and should be killed. summary[queue.name_with_underscores()] = { "status": status, } return summary