~jcsackett/charmworld/bac-tag-constraints

« back to all changes in this revision

Viewing changes to charmworld/views/api/__init__.py

  • Committer: Benji York
  • Date: 2013-11-18 20:38:47 UTC
  • mto: This revision was merged to the branch mainline in revision 465.
  • Revision ID: benji@benjiyork.com-20131118203847-2mfs1w7b8aqy64mr
checkpoint

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    quote_key,
45
45
    timestamp,
46
46
)
47
 
from charmworld.views.api.proof import proof_deployer_file
48
 
from charmworld.views.utils import (
49
 
    get_bundle_downloads,
50
 
    json_response,
51
 
)
 
47
from charmworld.views.api.proof import proof_deployer
 
48
from charmworld.views.utils import json_response
52
49
 
53
50
 
54
51
@view_config(route_name="search-json-obsolete")
195
192
        return f_requires, f_provides
196
193
 
197
194
    @classmethod
198
 
    def _format_charm(cls, charm, annotations=None):
 
195
    def _format_charm(cls, charm):
199
196
        """Format the charm for API consumers."""
200
197
        mapping = {
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]
222
218
        output.update({
234
230
                'revisions': revisions,
235
231
            },
236
232
            'maintainer': cls._parsed_email(maintainer),
237
 
            'maintainers': [cls._parsed_email(m) for m in maintainers],
238
233
            'relations': {
239
234
                'provides': charm.provides,
240
235
                'requires': charm.requires,
246
241
            'tested_providers': tested_providers,
247
242
            'is_subordinate': charm.subordinate
248
243
        })
249
 
        if annotations is not None:
250
 
            output.update({'annotations': annotations})
251
244
        return output
252
245
 
253
246
    @classmethod
339
332
            # provided.
340
333
            version = None
341
334
 
342
 
        if version is not None:
 
335
        if version:
343
336
            if owner:
344
337
                # URL includes an owner, a basket, and a version.
345
338
                bundle = path[3]
435
428
            owner=bundle_dict['owner'],
436
429
            rev=bundle_dict['basket_revision'],
437
430
        )
438
 
 
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
443
 
 
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
448
433
        # bundle.
451
436
                service, data, service_data.get('series'))
452
437
            charm = resolve_charm_from_description(db, description)
453
438
            if charm:
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
 
441
 
460
442
        return bundle_dict
461
443
 
462
444
    def _find_bundle(self, path):
475
457
                query = {
476
458
                    'owner': owner,
477
459
                    'basket_name': bundle_bits['basket'],
478
 
                    'name': bundle_bits['bundle'],
 
460
                    'name': bundle_bits['bundle']
479
461
                }
480
462
            else:
481
463
                query = {
482
464
                    'basket_name': bundle_bits['basket'],
483
465
                    'name': bundle_bits['bundle'],
484
 
                    'promulgated': True,
 
466
                    'promulgated': True
485
467
                }
486
468
 
487
469
            bundle = Bundle.from_query(query, self.request.db)
488
470
        return bundle_id, trailing, bundle
489
471
 
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)."""
492
474
        if path is None:
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':
561
543
        path = list(path)
562
544
 
563
545
        if path[0] == 'proof':
564
 
            return proof_deployer_file(self.request)
 
546
            return proof_deployer(self.request)
565
547
 
566
548
        bundle_id, trailing, bundle = self._find_bundle(path)
567
549
 
627
609
            headerlist=headerlist,
628
610
            status_code=200)
629
611
 
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)):
 
615
                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):
 
701
                doctype=None):
720
702
        """Search for charms and bundles matching parameters.
721
703
 
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)
726
705
        """
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'))
730
709
        if text is None:
731
710
            text = ['']
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)
743
720
        try:
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)
 
723
                doctype=doctype)
747
724
        except InvalidCharmType as e:
748
725
            return json_response(406, {
749
726
                                 'type': 'unsupported_value',