| OLD | NEW |
| 1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 # for details. All rights reserved. Use of this source code is governed by a | 2 # for details. All rights reserved. Use of this source code is governed by a |
| 3 # BSD-style license that can be found in the LICENSE file. | 3 # BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import cgi | 5 import cgi |
| 6 import json | 6 import json |
| 7 import logging | 7 import logging |
| 8 | 8 |
| 9 from google.appengine.api import memcache | 9 from google.appengine.api import memcache |
| 10 from google.appengine.api import users | 10 from google.appengine.api import users |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 package is represented by a PackageVersion model. | 21 package is represented by a PackageVersion model. |
| 22 | 22 |
| 23 Whenever a new PackageVersion for a Package is added or modified, you must | 23 Whenever a new PackageVersion for a Package is added or modified, you must |
| 24 call invalidate_cache() to ensure any stale cached description of the | 24 call invalidate_cache() to ensure any stale cached description of the |
| 25 package is discarded. | 25 package is discarded. |
| 26 """ | 26 """ |
| 27 | 27 |
| 28 MAX_SIZE = 10 * 2**20 # 10MB | 28 MAX_SIZE = 10 * 2**20 # 10MB |
| 29 """The maximum package size, in bytes.""" | 29 """The maximum package size, in bytes.""" |
| 30 | 30 |
| 31 uploaders = db.ListProperty(users.User, validator=models.validate_not_empty) | 31 uploaderEmails = db.StringListProperty(validator=models.validate_not_empty) |
| 32 """The users who are allowed to upload new versions of the package. | |
| 33 | |
| 34 When this is set, invalidate_cache() must be called.""" | |
| 35 | |
| 36 uploaderEmails = db.StringListProperty() | |
| 37 """The user emails who are allowed to upload new versions of the package. | 32 """The user emails who are allowed to upload new versions of the package. |
| 38 | 33 |
| 39 When this is set, invalidate_cache() must be called.""" | 34 When this is set, invalidate_cache() must be called.""" |
| 40 | 35 |
| 41 name = db.StringProperty(required=True) | 36 name = db.StringProperty(required=True) |
| 42 """The name of the package.""" | 37 """The name of the package.""" |
| 43 | 38 |
| 44 created = db.DateTimeProperty(auto_now_add=True) | 39 created = db.DateTimeProperty(auto_now_add=True) |
| 45 """When the package was created.""" | 40 """When the package was created.""" |
| 46 | 41 |
| 47 downloads = db.IntegerProperty(required=True, default=0) | 42 downloads = db.IntegerProperty(required=True, default=0) |
| 48 """The number of times any version of this package has been downloaded.""" | 43 """The number of times any version of this package has been downloaded.""" |
| 49 | 44 |
| 50 # This should only reference a PackageVersion, but cyclic imports aren't | 45 # This should only reference a PackageVersion, but cyclic imports aren't |
| 51 # allowed so we can't import PackageVersion here. | 46 # allowed so we can't import PackageVersion here. |
| 52 latest_version = db.ReferenceProperty() | 47 latest_version = db.ReferenceProperty() |
| 53 """The most recent non-prerelease version of this package. | 48 """The most recent non-prerelease version of this package. |
| 54 | 49 |
| 55 When this is set, invalidate_cache() must be called.""" | 50 When this is set, invalidate_cache() must be called.""" |
| 56 | 51 |
| 57 def temp_synchronize_uploaders_to_uploaderemails(self): | |
| 58 """ Will synchronize self.uploaders -> self.uploaderEmails. """ | |
| 59 if self.uploaders is None: | |
| 60 self.uploaderEmails = None | |
| 61 elif len(self.uploaders) == 0: | |
| 62 self.uploaderEmails = self.uploaders | |
| 63 else: | |
| 64 self.uploaderEmails = [uploader.email() for uploader in self.uploaders] | |
| 65 | |
| 66 @property | 52 @property |
| 67 def description(self): | 53 def description(self): |
| 68 """The short description of the package.""" | 54 """The short description of the package.""" |
| 69 if self.latest_version is None: return None | 55 if self.latest_version is None: return None |
| 70 return self.latest_version.pubspec.get('description') | 56 return self.latest_version.pubspec.get('description') |
| 71 | 57 |
| 72 _MAX_DESCRIPTION_CHARS = 200 | 58 _MAX_DESCRIPTION_CHARS = 200 |
| 73 | 59 |
| 74 @property | 60 @property |
| 75 def ellipsized_description(self): | 61 def ellipsized_description(self): |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 """Determine whether a package with the given name exists.""" | 152 """Determine whether a package with the given name exists.""" |
| 167 return cls.get_by_key_name(name) is not None | 153 return cls.get_by_key_name(name) is not None |
| 168 | 154 |
| 169 def has_version(self, version): | 155 def has_version(self, version): |
| 170 """Determine whether this package has a given version uploaded.""" | 156 """Determine whether this package has a given version uploaded.""" |
| 171 from package_version import PackageVersion | 157 from package_version import PackageVersion |
| 172 version = PackageVersion.get_by_name_and_version( | 158 version = PackageVersion.get_by_name_and_version( |
| 173 self.name, str(version)) | 159 self.name, str(version)) |
| 174 return version is not None | 160 return version is not None |
| 175 | 161 |
| 176 def has_uploader(self, uploader): | 162 def has_uploader_email(self, uploaderEmail): |
| 177 """Determine whether the given user is an uploader for this package. | 163 """Determine whether the given user is an uploader for this package. |
| 178 | 164 |
| 179 This compares users via case-insensitive email comparison. | 165 This compares users via case-insensitive email comparison. |
| 180 | 166 |
| 181 Although admins have uploader privileges for all packages, this will not | 167 Although admins have uploader privileges for all packages, this will not |
| 182 return True for admins. | 168 return True for admins. |
| 183 """ | 169 """ |
| 184 return uploader.email().lower() in \ | 170 return uploaderEmail.lower() in \ |
| 185 [email.lower() for email in self.uploaderEmails] | 171 [email.lower() for email in self.uploaderEmails] |
| 186 | 172 |
| 187 @property | 173 @property |
| 188 def url(self): | 174 def url(self): |
| 189 """The API URL for this package.""" | 175 """The API URL for this package.""" |
| 190 return models.url( | 176 return models.url( |
| 191 controller='api.packages', action='show', id=self.name) | 177 controller='api.packages', action='show', id=self.name) |
| 192 | 178 |
| 193 def as_dict(self, full=False): | 179 def as_dict(self, full=False): |
| 194 """Returns the dictionary representation of this package. | 180 """Returns the dictionary representation of this package. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 description of the package changes. This isn't often since most package | 224 description of the package changes. This isn't often since most package |
| 239 data is immutable, but when the uploader list changes or new versions | 225 data is immutable, but when the uploader list changes or new versions |
| 240 of the package are uploaded, the data will change. | 226 of the package are uploaded, the data will change. |
| 241 """ | 227 """ |
| 242 memcache.delete(self._package_json_cache_key) | 228 memcache.delete(self._package_json_cache_key) |
| 243 | 229 |
| 244 @property | 230 @property |
| 245 def _package_json_cache_key(self): | 231 def _package_json_cache_key(self): |
| 246 """The memcache key for the cached JSON for this package.""" | 232 """The memcache key for the cached JSON for this package.""" |
| 247 return 'package_json_' + self.name | 233 return 'package_json_' + self.name |
| OLD | NEW |