16c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen# Copyright (C) 2010 Google Inc. All rights reserved. 2cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# 3cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# Redistribution and use in source and binary forms, with or without 4cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# modification, are permitted provided that the following conditions are 5cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# met: 6cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# 7cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# * Redistributions of source code must retain the above copyright 8cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# notice, this list of conditions and the following disclaimer. 9cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# * Redistributions in binary form must reproduce the above 10cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# copyright notice, this list of conditions and the following disclaimer 11cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# in the documentation and/or other materials provided with the 12cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# distribution. 13cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# * Neither the name of Google Inc. nor the names of its 14cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# contributors may be used to endorse or promote products derived from 15cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# this software without specific prior written permission. 16cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# 17cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenfrom google.appengine.ext import db 30cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochfrom model.queuepropertymixin import QueuePropertyMixin 32cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochclass WorkItems(db.Model, QueuePropertyMixin): 356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen queue_name = db.StringProperty() 366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen item_ids = db.ListProperty(int) 376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen date = db.DateTimeProperty(auto_now_add=True) 38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch @classmethod 402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch def key_for_queue(cls, queue_name): 412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return "work-items-%s" % (queue_name) 422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch @classmethod 442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch def lookup_by_queue(cls, queue_name): 452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch return cls.get_or_insert(key_name=cls.key_for_queue(queue_name), queue_name=queue_name) 462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch def display_position_for_attachment(self, attachment_id): 48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch """Returns a 1-based index corresponding to the position 49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch of the attachment_id in the queue. If the attachment is 50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch not in this queue, this returns None""" 51a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if attachment_id in self.item_ids: 52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return self.item_ids.index(attachment_id) + 1 53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return None 54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 55a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch @staticmethod 56a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch def _unguarded_add(key, attachment_id): 57a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch work_items = db.get(key) 58a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if attachment_id in work_items.item_ids: 59a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return 60a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch work_items.item_ids.append(attachment_id) 61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch work_items.put() 62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 6328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError. 64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch def add_work_item(self, attachment_id): 65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch db.run_in_transaction(self._unguarded_add, self.key(), attachment_id) 66a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch @staticmethod 68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch def _unguarded_remove(key, attachment_id): 69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch work_items = db.get(key) 70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if attachment_id in work_items.item_ids: 71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch # We should never have more than one entry for a work item, so we only need remove the first. 72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch work_items.item_ids.remove(attachment_id) 73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch work_items.put() 74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 7528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu # Because this uses .key() self.is_saved() must be True or this will throw NotSavedError. 76a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch def remove_work_item(self, attachment_id): 77a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch db.run_in_transaction(self._unguarded_remove, self.key(), attachment_id) 78