47
from charmworld.views.api.proof import proof_deployer_file
48
from charmworld.views.utils import (
47
from charmworld.views.api.proof import proof_deployer
48
from charmworld.views.utils import json_response
54
51
@view_config(route_name="search-json-obsolete")
195
192
return f_requires, f_provides
198
def _format_charm(cls, charm, annotations=None):
195
def _format_charm(cls, charm):
199
196
"""Format the charm for API consumers."""
201
198
'summary': 'summary',
215
212
if result not in cls.TEST_STATUSES:
216
213
raise ValueError('Unsupported test status: %s' % result)
217
214
tested_providers[provider] = result
218
maintainers = charm.maintainers
219
maintainer = maintainers[0] if maintainers else ''
215
maintainer = charm.maintainer
220
216
bugs_link = 'https://bugs.launchpad.net/charms/+source/%s' % charm.name
221
217
revisions = [cls._format_revision(rev) for rev in charm.changes]
234
230
'revisions': revisions,
236
232
'maintainer': cls._parsed_email(maintainer),
237
'maintainers': [cls._parsed_email(m) for m in maintainers],
239
234
'provides': charm.provides,
240
235
'requires': charm.requires,
246
241
'tested_providers': tested_providers,
247
242
'is_subordinate': charm.subordinate
249
if annotations is not None:
250
output.update({'annotations': annotations})
435
428
owner=bundle_dict['owner'],
436
429
rev=bundle_dict['basket_revision'],
439
# Add in download data.
440
downloads = get_bundle_downloads(db, bundle.id)
441
bundle_dict['downloads'] = downloads.total
442
bundle_dict['downloads_in_past_30_days'] = downloads.past_30_days
444
mongo_bundle = db.bundles.find_one({'_id': bundle.id})
445
mongo_services = mongo_bundle['data']['services']
446
431
service_data = bundle_dict.get('data')
447
432
# Now load the charm information we require for the services in the
451
436
service, data, service_data.get('series'))
452
437
charm = resolve_charm_from_description(db, description)
454
annotations = mongo_services[service].get('annotations')
455
formatted = cls._format_charm(
456
Charm(charm), annotations=annotations)
439
formatted = cls._format_charm(Charm(charm))
457
440
bundle_dict['charm_metadata'][service] = formatted
458
if 'annotations' not in data:
459
data['annotations'] = annotations
460
442
return bundle_dict
462
444
def _find_bundle(self, path):
477
459
'basket_name': bundle_bits['basket'],
478
'name': bundle_bits['bundle'],
460
'name': bundle_bits['bundle']
482
464
'basket_name': bundle_bits['basket'],
483
465
'name': bundle_bits['bundle'],
487
469
bundle = Bundle.from_query(query, self.request.db)
488
470
return bundle_id, trailing, bundle
490
def charm(self, path=None, **kwargs):
472
def charm(self, path=None):
491
473
"""Retrieve a charm according to its API ID (the path prefix)."""
493
475
raise HTTPNotFound(self.request.path)
504
486
if trailing is None:
505
487
return self._charm_details(charm_data)
506
488
elif trailing == self.ICON_TRAILING:
507
return self._charm_icon(charm, kwargs.get('debug', False))
489
return self._charm_icon(charm)
508
490
elif trailing.startswith('file/'):
509
491
return self._charm_file(charm, trailing)
510
492
elif trailing == 'qa':
627
609
headerlist=headerlist,
630
def _charm_icon(self, charm, debug=False):
612
def _charm_icon(self, charm):
631
613
if (charm.files and
632
614
charm.files.get(quote_key('icon.svg')) and
633
(debug or charm.promulgated)):
634
616
return self._charm_file(charm, '/icon.svg')
635
617
elif charm.categories:
636
618
main_category = charm.categories[0]
716
698
def _search(self, limit=None, name=None, series=None, owner=None,
717
699
provides=None, requires=None, type_=None, provider=None,
718
700
scope=None, categories=None, text=None, autocomplete=False,
719
doctype=None, min_score=None):
720
702
"""Search for charms and bundles matching parameters.
722
:limit: A query limit. (The max number of results.) Dispatched as a
723
list of numeric characters representing an int, e.g. ['4'].
724
:min_score: The minimum score for filtering. Dispatched as a
725
list of numeric characters representing a float, e.g. ['1.1'].
704
:limit: A query limit. (max number of results)
727
706
autocomplete = autocomplete == ['true']
728
707
params = dict((key, value) for key, value in locals().items()
729
708
if key in ('series', 'owner', 'name', 'categories'))
732
if min_score is not None:
733
min_score = float(min_score[0])
734
711
params['i_provides'] = provides
735
712
params['i_requires'] = requires
736
713
filters = dict(item for item in params.items() if item[1] is not None)
744
721
results = self.request.index_client.api_search(
745
722
text[0], filters, type_, limit, autocomplete=autocomplete,
746
doctype=doctype, min_score=min_score)
747
724
except InvalidCharmType as e:
748
725
return json_response(406, {
749
726
'type': 'unsupported_value',