Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1330)

Side by Side Diff: charmworld/views/api/__init__.py

Issue 91140045: Include annotations in bundle search results.
Patch Set: Created 10 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 __metaclass__ = type 1 __metaclass__ = type
2 2
3 from datetime import ( 3 from datetime import (
4 datetime, 4 datetime,
5 timedelta, 5 timedelta,
6 ) 6 )
7 from email.utils import parseaddr 7 from email.utils import parseaddr
8 from inspect import getargspec 8 from inspect import getargspec
9 from os.path import ( 9 from os.path import (
10 join, 10 join,
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 self._format_related(payload['data'], payload['weight']) 188 self._format_related(payload['data'], payload['weight'])
189 for payload in value] 189 for payload in value]
190 f_provides = {} 190 f_provides = {}
191 for key, value in r_provides.items(): 191 for key, value in r_provides.items():
192 f_provides[key] = [ 192 f_provides[key] = [
193 self._format_related(payload['data'], payload['weight']) 193 self._format_related(payload['data'], payload['weight'])
194 for payload in value] 194 for payload in value]
195 return f_requires, f_provides 195 return f_requires, f_provides
196 196
197 @classmethod 197 @classmethod
198 def _format_charm(cls, charm, extra_data={}): 198 def _format_charm(cls, charm, annotations=None):
199 """Format the charm for API consumers.""" 199 """Format the charm for API consumers."""
200 mapping = { 200 mapping = {
201 'summary': 'summary', 201 'summary': 'summary',
202 'name': 'name', 202 'name': 'name',
203 'description': 'description', 203 'description': 'description',
204 'owner': 'owner', 204 'owner': 'owner',
205 'downloads': 'downloads', 205 'downloads': 'downloads',
206 'downloads_in_past_30_days': 'downloads_in_past_30_days', 206 'downloads_in_past_30_days': 'downloads_in_past_30_days',
207 'distro_series': 'series', 207 'distro_series': 'series',
208 'revision': 'revision', 208 'revision': 'revision',
(...skipping 30 matching lines...) Expand all
239 'provides': charm.provides, 239 'provides': charm.provides,
240 'requires': charm.requires, 240 'requires': charm.requires,
241 }, 241 },
242 'options': charm.options, 242 'options': charm.options,
243 'files': [join(entry['subdir'], entry['filename']) 243 'files': [join(entry['subdir'], entry['filename'])
244 for entry in charm.files.values()], 244 for entry in charm.files.values()],
245 'is_approved': charm.promulgated, 245 'is_approved': charm.promulgated,
246 'tested_providers': tested_providers, 246 'tested_providers': tested_providers,
247 'is_subordinate': charm.subordinate 247 'is_subordinate': charm.subordinate
248 }) 248 })
249 annotations = extra_data.get('annotations')
250 if annotations is not None: 249 if annotations is not None:
251 output.update({'annotations': annotations}) 250 output.update({'annotations': annotations})
252 return output 251 return output
253 252
254 @classmethod 253 @classmethod
255 def _format_related(cls, charm_data, weight, _now=None): 254 def _format_related(cls, charm_data, weight, _now=None):
256 if _now is None: 255 if _now is None:
257 now = datetime.utcnow() 256 now = datetime.utcnow()
258 else: 257 else:
259 now = _now 258 now = _now
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 mongo_bundle = db.bundles.find_one({'_id': bundle.id}) 444 mongo_bundle = db.bundles.find_one({'_id': bundle.id})
446 mongo_services = mongo_bundle['data']['services'] 445 mongo_services = mongo_bundle['data']['services']
447 service_data = bundle_dict.get('data') 446 service_data = bundle_dict.get('data')
448 # Now load the charm information we require for the services in the 447 # Now load the charm information we require for the services in the
449 # bundle. 448 # bundle.
450 for service, data in bundle.data['services'].iteritems(): 449 for service, data in bundle.data['services'].iteritems():
451 description = BundledCharmDescription( 450 description = BundledCharmDescription(
452 service, data, service_data.get('series')) 451 service, data, service_data.get('series'))
453 charm = resolve_charm_from_description(db, description) 452 charm = resolve_charm_from_description(db, description)
454 if charm: 453 if charm:
454 annotations = mongo_services[service].get('annotations')
455 formatted = cls._format_charm( 455 formatted = cls._format_charm(
456 Charm(charm), mongo_services[service]) 456 Charm(charm), annotations=annotations)
457 bundle_dict['charm_metadata'][service] = formatted 457 bundle_dict['charm_metadata'][service] = formatted
458 458 if 'annotations' not in data:
459 data['annotations'] = annotations
459 return bundle_dict 460 return bundle_dict
460 461
461 def _find_bundle(self, path): 462 def _find_bundle(self, path):
462 try: 463 try:
463 bundle_id, trailing, bundle_bits = self._parse_bundle_id(path) 464 bundle_id, trailing, bundle_bits = self._parse_bundle_id(path)
464 except ValueError: 465 except ValueError:
465 bundle = bundle_id = trailing = bundle_bits = None 466 bundle = bundle_id = trailing = bundle_bits = None
466 else: 467 else:
467 if bundle_bits['owner'] and bundle_bits['version']: 468 if bundle_bits['owner'] and bundle_bits['version']:
468 # We have all 4 parts needed, just use the ID. 469 # We have all 4 parts needed, just use the ID.
469 query = {'_id': bundle_id} 470 query = {'_id': bundle_id}
470 elif bundle_bits['owner']: 471 elif bundle_bits['owner']:
471 # This URL includes the owner, basket name, and bundle name. 472 # This URL includes the owner, basket name, and bundle name.
472 # The specified bundle may be promulgated or not. 473 # The specified bundle may be promulgated or not.
473 owner = bundle_bits['owner'][1:] # Strip the tilde. 474 owner = bundle_bits['owner'][1:] # Strip the tilde.
474 query = { 475 query = {
475 'owner': owner, 476 'owner': owner,
476 'basket_name': bundle_bits['basket'], 477 'basket_name': bundle_bits['basket'],
477 'name': bundle_bits['bundle'] 478 'name': bundle_bits['bundle'],
478 } 479 }
479 else: 480 else:
480 query = { 481 query = {
481 'basket_name': bundle_bits['basket'], 482 'basket_name': bundle_bits['basket'],
482 'name': bundle_bits['bundle'], 483 'name': bundle_bits['bundle'],
483 'promulgated': True 484 'promulgated': True,
484 } 485 }
485 486
486 bundle = Bundle.from_query(query, self.request.db) 487 bundle = Bundle.from_query(query, self.request.db)
487 return bundle_id, trailing, bundle 488 return bundle_id, trailing, bundle
488 489
489 def charm(self, path=None, **kwargs): 490 def charm(self, path=None, **kwargs):
490 """Retrieve a charm according to its API ID (the path prefix).""" 491 """Retrieve a charm according to its API ID (the path prefix)."""
491 if path is None: 492 if path is None:
492 raise HTTPNotFound(self.request.path) 493 raise HTTPNotFound(self.request.path)
493 charm_id, trailing, charm_data = self._find_charm(path) 494 charm_id, trailing, charm_data = self._find_charm(path)
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 'series': series, 832 'series': series,
832 'name': name, 833 'name': name,
833 }, sort=[('store_data.revision', pymongo.DESCENDING)]) 834 }, sort=[('store_data.revision', pymongo.DESCENDING)])
834 if charm is not None: 835 if charm is not None:
835 api_id = self._get_api_id(Charm(charm)) 836 api_id = self._get_api_id(Charm(charm))
836 # Charm ID should match up to, but not including the revision. 837 # Charm ID should match up to, but not including the revision.
837 revisionless_charm_id = charm_id.split('-', 1)[0] 838 revisionless_charm_id = charm_id.split('-', 1)[0]
838 if not api_id.startswith(revisionless_charm_id): 839 if not api_id.startswith(revisionless_charm_id):
839 charm = None 840 charm = None
840 return charm_id, trailing, charm 841 return charm_id, trailing, charm
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b