Exemplo n.º 1
0
class ConnectionsResource(LoggingMixin, Resource):
    id = fields.CharField(attribute='id')
    facebook_id = fields.CharField(attribute='facebook_id', null=True)
    username = fields.CharField(attribute='username', null=True)
    first_name = fields.CharField(attribute='first_name')
    last_name = fields.CharField(attribute='last_name')
    user_id = fields.CharField(attribute='user_id')

    age = fields.IntegerField(attribute='age')
    distance = fields.ListField(attribute='distance')
    about = fields.CharField(attribute='about', null=True)
    gender = fields.CharField(attribute='gender', default=u'all')

    photos = fields.ListField(attribute='photos')
    goals = fields.ListField(attribute='goals')
    offers = fields.ListField(attribute='offers')
    interests = fields.ListField(attribute='interests')
    top_interests = fields.ListField(attribute='top_interests')

    score = fields.IntegerField(attribute='score', null=True)
    mutual_likes_count = fields.IntegerField(attribute='mutual_likes_count',
                                             null=True)
    total_likes_count = fields.IntegerField(attribute='total_likes_count',
                                            null=True)
    es_score = fields.FloatField(attribute='es_score', null=True)
    friends_score = fields.IntegerField(attribute='friends_score', null=True)

    friend_id = fields.CharField(attribute='friend_id', null=True)

    seen = fields.BooleanField(attribute='seen', null=True)
    last_login = fields.DateTimeField(attribute='last_login', null=True)
    image = fields.FileField(attribute="image", null=True, blank=True)
    position = fields.DictField(attribute="position", null=True, blank=True)
    lives_in = fields.CharField(attribute="lives_in", null=True, blank=True)

    twitter_provider = fields.CharField(attribute="twitter_provider",
                                        null=True,
                                        blank=True)
    linkedin_provider = fields.CharField(attribute="linkedin_provider",
                                         null=True,
                                         blank=True)
    twitter_username = fields.CharField(attribute="twitter_username",
                                        null=True,
                                        blank=True)

    class Meta:
        resource_name = 'connections'
        authentication = JSONWebTokenAuthentication()
        authorization = Authorization()

    def detail_uri_kwargs(self, bundle_or_obj):
        kwargs = {}
        if isinstance(bundle_or_obj, Bundle):
            kwargs['pk'] = bundle_or_obj.obj.id
        else:
            kwargs['pk'] = bundle_or_obj.id

        return kwargs

    def get_object_list(self, request):
        logger.info('Get connections for user_id {}'.format(request.user.id))
        fs = FilterState.objects.filter(user=request.user.id)

        cache_match_users_with_filter = None
        cache_match_users = None
        filter_updated_sha = None

        raw_filter = request.GET.get('filter')
        is_filter = True if (raw_filter and raw_filter in ['true']) else False

        if is_filter:
            if fs:
                try:
                    attrs = [
                        fs[0].gender, fs[0].min_age, fs[0].max_age,
                        fs[0].distance, fs[0].distance_unit,
                        fs[0].order_criteria, fs[0].keyword
                    ]
                    filter_updated = '.'.join(map(str, attrs))
                    filter_updated_sha = hashlib.sha1(
                        filter_updated).hexdigest()
                    cache_match_users_with_filter = cache.get(
                        'c_%s_%s' % (request.user.id, filter_updated_sha))
                except AttributeError as err:
                    logger.error(err)
            if cache_match_users_with_filter:
                match_users = cache_match_users_with_filter
            else:
                match_users = MatchQuerySet. \
                    all(request.user.id, is_filter=True, friends=True)
                cache.set('c_%s_%s' % (request.user.id, filter_updated_sha),
                          match_users)

        else:
            if cache_match_users:
                match_users = cache_match_users
            else:
                match_users = MatchQuerySet. \
                    all(request.user.id, friends=True)
                match_users = sorted(match_users, key=lambda x: -x.score)
                cache.set('c_%s' % (request.user.id, ), match_users)

        return match_users

    def obj_get_list(self, bundle, **kwargs):
        # Filtering disabled for brevity...
        return self.get_object_list(bundle.request)

    def rollback(self, bundles):
        pass

    def obj_get(self, bundle, **kwargs):
        pass

    def dehydrate(self, bundle):
        bundle.data['religious_views'] = get_religious_views(bundle.obj.id)
        bundle.data['political_views'] = get_political_views(bundle.obj.id)
        return bundle
Exemplo n.º 2
0
class FoodTruckResource(Resource):
    '''
    Tastypie non-ORM resource to capture Yelp data and pass it back to the client.
    '''
    # Define all the relevant "model" fields here without actually defining a Django ORM model
    id = fields.CharField(attribute='id')
    name = fields.CharField(attribute='name')
    categories = fields.CharField(attribute='categories')
    display_address = fields.CharField(attribute='display_address')
    url = fields.CharField(attribute='url')
    review_count = fields.IntegerField(attribute='review_count')
    rating_img_url = fields.CharField(attribute='rating_img_url')
    rating = fields.FloatField(attribute='rating')
    latitude = fields.FloatField(attribute='latitude')
    longitude = fields.FloatField(attribute='longitude')

    class Meta:
        object_class = FoodTruck

    def obj_get_list(self, bundle, **kwargs):
        '''
        Search's Yelp's API for relevant food trucks defined in the search parameters given in bundle. 
        
        :param bundle: A Tastypie bundle containing, among other things, the HTTP request containing search parameters.
        
        Mandatory parameters are:
            -ne: coordinates (in latitude, longitude form) representing the north-eastern point of the search area.
            -sw: coordinates (in latitude, longitude form) representing the south-wetern point of the search area.
        
        Optional parameters are:
            -name: a search term relevant to the food truck you are looking for, i.e. waffles, HappyIceCreamTruck, etc.
        
        :type bundle: Bundle.
        '''
        foodTrucks = []
        if 'ne' in bundle.request.GET and bundle.request.GET[
                'ne'] and 'sw' in bundle.request.GET and bundle.request.GET[
                    'sw']:

            [neLat, neLng] = [
                float(c)
                for c in re.findall('[0-9.-]+', bundle.request.GET['ne'])
            ]
            [swLat, swLng] = [
                float(c)
                for c in re.findall('[0-9.-]+', bundle.request.GET['sw'])
            ]

            # Set up a session to the Yelp API
            session = OAuth1Session(
                consumer_key=os.environ['YELP_CONSUMER_KEY'],
                consumer_secret=os.environ['YELP_CONSUMER_SECRET'],
                access_token=os.environ['YELP_TOKEN'],
                access_token_secret=os.environ['YELP_TOKEN_SECRET'])

            searchParams = {
                'category_filter': 'foodtrucks',
                'limit': 20,
                'bounds': '{0},{1}|{2},{3}'.format(swLat, swLng, neLat, neLng)
            }

            # Optionally pass in the name of the food truck the user is looking for, if at all
            if 'name' in bundle.request.GET and bundle.request.GET['name']:
                searchParams['term'] = bundle.request.GET['name']

            response = session.get('http://api.yelp.com/v2/search',
                                   params=searchParams)
            parsed_response = response.json()

            for foodTruck in parsed_response['businesses']:
                if foodTruck['is_closed'] == False:

                    display_address = "\n".join(
                        foodTruck['location']['display_address'])
                    # Get rid of the Yelp category identifiers
                    categories = ", ".join(
                        [x[0] for x in foodTruck['categories']])

                    ftModel = {
                        'id':
                        foodTruck['id'],
                        'name':
                        foodTruck['name'],
                        'display_address':
                        display_address,
                        'url':
                        foodTruck['url'],
                        'categories':
                        categories,
                        'review_count':
                        foodTruck['review_count'],
                        'rating_img_url':
                        foodTruck['rating_img_url'],
                        'rating':
                        foodTruck['rating'],
                        'latitude':
                        foodTruck['location']['coordinate']['latitude'],
                        'longitude':
                        foodTruck['location']['coordinate']['longitude']
                    }
                    foodTrucks.append(FoodTruck(**ftModel))
        return foodTrucks
Exemplo n.º 3
0
class ProjectsResource(ModelResource):
    """Projects resource"""
    id = fields.CharField(attribute='id', readonly=True)
    name = fields.CharField(attribute='name', readonly=True)
    url = fields.CharField(attribute='url', readonly=True)
    is_private = fields.BooleanField(attribute='is_private', readonly=True)
    branches = fields.ListField(attribute='branches', readonly=True)
    icon = fields.CharField(attribute='icon', readonly=True, null=True)
    badge_url = fields.CharField(attribute='get_badge_url', readonly=True)
    owner_id = fields.CharField(attribute='owner_id', readonly=True)
    token = fields.CharField(attribute='token', blank=True, null=True)
    default_branch = fields.CharField(
        attribute='default_branch',
        blank=True,
        null=True,
    )
    dashboard_branch = fields.CharField(
        attribute='dashboard_branch',
        blank=True,
        null=True,
    )
    can_change = fields.BooleanField(default=False)
    success_percents = fields.ListField(blank=True, null=True)
    last_task = fields.DictField(blank=True, null=True)
    trend = fields.FloatField(blank=True, null=True)
    week_statistic = fields.DictField(
        attribute='week_statistic',
        blank=True,
        null=True,
        readonly=True,
    )
    day_time_statistic = fields.DictField(
        attribute='day_time_statistic',
        blank=True,
        null=True,
        readonly=True,
    )
    quality_game = fields.DictField(
        attribute='quality_game',
        blank=True,
        null=True,
        readonly=True,
    )

    class Meta:
        queryset = Project.objects.all()
        authentication = Authentication()
        authorization = ProjectsAuthorization()
        resource_name = 'projects/project'
        detail_uri_name = 'name'
        fields = (
            'name',
            'is_enabled',
            'id',
            'is_private',
            'icon',
            'comment_from_owner_account',
            'run_here',
        )

    def dehydrate(self, bundle):
        """Attach token to bundle if owner"""
        if (bundle.request.user.is_authenticated()
                and bundle.obj.can_change(bundle.request.user)):
            bundle.data['can_change'] = True
        else:
            bundle.data['token'] = ''
        self._attach_success_percent(bundle)
        self._attach_last_task(bundle)
        self._attach_trend(bundle)
        return bundle

    @attach_field('with_success_percent', 'success_percents')
    def _attach_success_percent(self, bundle):
        """Attach success percent"""
        return bundle.obj.get_success_percents(
            100,
            bundle.request.GET.get('branch'),
        )

    @attach_field('with_last_task', 'last_task')
    def _attach_last_task(self, bundle):
        """Attach last task to project"""
        try:
            return bundle.obj.get_last_task()
        except TaskDoesNotExists:
            return None

    @attach_field('with_trend', 'trend')
    def _attach_trend(self, bundle):
        """Attach trend to project"""
        return bundle.obj.get_trend(bundle.request.GET.get('branch'))
Exemplo n.º 4
0
class TargetResource(ChemblModelResource):

    target_chembl_id = fields.CharField('chembl_id')
    target_type = fields.CharField('target_type_id')
    target_components = fields.ToManyField(
        'chembl_webservices.resources.target.TargetComponentsResource',
        'targetcomponents_set',
        full=True,
        null=True,
        blank=True)
    cross_references = fields.ToManyField(
        'chembl_webservices.resources.target.TargetXRefResource',
        'targetxref_set',
        full=True,
        null=True,
        blank=True)
    score = fields.FloatField('score', use_in='search', null=True, blank=True)

    class Meta(ChemblResourceMeta):
        queryset = TargetDictionary.objects.all() if 'downgraded' not in available_fields else \
            TargetDictionary.objects.filter(downgraded=False)
        es_join_column = 'chembl_id'
        excludes = ['tid']
        resource_name = 'target'
        collection_name = 'targets'
        serializer = ChEMBLApiSerializer(
            resource_name, {
                collection_name: resource_name,
                'target_components': 'target_component',
                'target_component_synonyms': 'target_component_synonym'
            })
        detail_uri_name = 'chembl_id'
        prefetch_related = [
            Prefetch('targetcomponents_set',
                     queryset=TargetComponents.objects.only(
                         'pk', 'relationship', 'target', 'component')),
            Prefetch('targetcomponents_set__component',
                     queryset=ComponentSequences.objects.only(
                         'accession', 'pk', 'component_type', 'description')),
            Prefetch('targetxref_set',
                     queryset=TargetXref.objects.only('pk', 'target',
                                                      'xref_name', 'xref_id',
                                                      'xref_src_db')),
            Prefetch('targetxref_set__xref_src_db',
                     queryset=XrefSource.objects.only('pk')),
            Prefetch('targetcomponents_set__component__componentsynonyms_set'),
            Prefetch('targetcomponents_set__component__componentxref_set'),
        ]

        fields = (
            'organism',
            'tax_id',
            'pref_name',
            'species_group_flag',
            'target_chembl_id',
        )

        filtering = {
            'organism': CHAR_FILTERS,
            'tax_id': NUMBER_FILTERS,
            'pref_name': CHAR_FILTERS,
            'target_type': CHAR_FILTERS,
            'species_group_flag': FLAG_FILTERS,
            'target_chembl_id': ALL,
            'target_components': ALL_WITH_RELATIONS,
        }
        ordering = [
            'organism',
            'tax_id',
            'pref_name',
            'target_type',
            'species_group_flag',
            'target_chembl_id',
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def prepend_urls(self):
        """
        Returns a URL scheme based on the default scheme to specify
        the response format as a file extension, e.g. /api/v1/users.json
        """
        return [
            url(r"^(?P<resource_name>%s)/search%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)/search\.(?P<format>xml|json|jsonp|yaml)$"
                % self._meta.resource_name,
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)/datatables\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_datatables'),
                name="api_get_datatables"),
            url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_schema'),
                name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/set/(?P<%s_list>\w[\w/;-]*)\.(?P<format>\w+)$"
                % (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/(?P<%s>\w[\w/-]*)\.(?P<format>\w+)$" %
                (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def preprocess_filters(self, filters, for_cache_key=False):
        ret = {}
        for filter_expr, value in list(filters.items()):
            filter_bits = filter_expr.split(LOOKUP_SEP)
            field_name = filter_bits.pop(0)

            if field_name == 'target_synonym':
                field_name = 'target_components'
                filter_bits = [
                    'target_component_synonyms', 'component_synonym'
                ] + filter_bits
                ret[LOOKUP_SEP.join([field_name] + filter_bits)] = value

            else:
                ret[filter_expr] = value
        return ret
Exemplo n.º 5
0
class SearchResource(ModelResourceWithFieldsFilter):
    # Roses to the clever person that makes this introspect the model and
    # removes all this code.
    absolute_url = fields.CharField(
        attribute='absolute_url',
        help_text="The URL on CourtListener for the item.",
        null=True,
    )
    case_name = fields.CharField(
        attribute='caseName',
        help_text="The full name of the case",
        null=True,
    )
    case_number = fields.CharField(
        attribute='caseNumber',
        help_text="The combination of the citation and the docket number. "
        "Only applies to opinion results.",
        null=True,
    )
    citation = fields.CharField(
        attribute='citation',
        help_text="A concatenated list of all the citations for an opinion. "
        "Only applies to opinion results.",
        null=True,
    )
    cite_count = fields.IntegerField(
        attribute='citeCount',
        help_text="The number of times this document is cited by other cases. "
        "Only applies to opinion results.",
        null=True,
    )
    court = fields.CharField(
        attribute='court',
        help_text="The name of the court where the document was filed.",
        null=True,
    )
    court_id = fields.CharField(
        attribute='court_id',
        help_text='The id of the court where the document was filed.',
        null=True,
    )
    date_argued = fields.DateField(
        attribute='dateArgued',
        help_text='The date argued in the court. Only applies to oral '
        'argument results.',
        null=True,
    )
    date_filed = fields.DateField(
        attribute='dateFiled',
        help_text='The date filed by the court. Only applies to opinion '
        'results.',
        null=True,
    )
    docket_number = fields.CharField(
        attribute='docketNumber',
        help_text='The docket numbers of a case, can be consolidated and '
        'quite long',
        null=True,
    )
    download_url = fields.CharField(
        attribute='download_url',
        help_text='The URL on the court website where the item was '
        'originally scraped',
        null=True,
    )
    duration = fields.IntegerField(
        attribute='duration',
        help_text='The length, in seconds, of the mp3 file. Only applies to '
        'oral arguments.',
        null=True,
    )
    id = fields.CharField(
        attribute='id',
        help_text='The primary key for an item.',
    )
    judge = fields.CharField(
        attribute='judge',
        help_text='The judges that brought the opinion as a simple text '
        'string',
        null=True,
    )
    local_path = fields.CharField(
        attribute='local_path',
        help_text='The location, relative to MEDIA_ROOT on the CourtListener '
        'server, where files are stored.',
        null=True,
    )
    score = fields.FloatField(
        attribute='score',
        help_text='The relevance of the result. Will vary from query to '
        'query.',
    )
    source = fields.CharField(
        attribute='source',
        help_text='the source of the document, one of: %s' %
        ', '.join(['%s (%s)' % (t[0], t[1]) for t in SOURCES]),
        null=True,
    )
    snippet = fields.CharField(
        attribute='snippet',
        help_text='a snippet as found in search results, utilizing <mark> for '
        'highlighting and &hellip; for ellipses.',
        null=True,
    )
    status = fields.CharField(
        attribute='status',
        help_text='The precedential status of document, one of: %s. Only '
        'applies to opinion results.' %
        ', '.join([('stat_%s' % t[1]).replace(' ', '+')
                   for t in DOCUMENT_STATUSES]),
        null=True,
    )
    suit_nature = fields.CharField(
        attribute='suitNature',
        help_text="The nature of the suit. For the moment can be codes or "
        "laws or whatever. Only applies to opinion results.",
        null=True,
    )
    text = fields.CharField(
        attribute='text',
        use_in='detail',  # Only shows on the detail page.
        help_text="A concatenated copy of most fields in the item so those "
        "fields are available for search. Only applies to opinion "
        "results.")
    timestamp = fields.DateField(
        attribute='timestamp',
        help_text='The moment when an item was indexed by Solr.')

    class Meta:
        authentication = authentication.MultiAuthentication(
            BasicAuthenticationWithUser(realm="courtlistener.com"),
            authentication.SessionAuthentication())
        throttle = PerUserCacheThrottle(throttle_at=1000)
        resource_name = 'search'
        max_limit = 20
        include_absolute_url = True
        allowed_methods = ['get']
        filtering = {
            'q': ('search', ),
            'case_name': ('search', ),
            'judge': ('search', ),
            'stat_': ('boolean', ),
            'filed_after': ('date', ),
            'filed_before': ('date', ),
            'argued_after': ('date', ),
            'argued_before': ('date', ),
            'citation': ('search', ),
            'neutral_cite': ('search', ),
            'docket_number': ('search', ),
            'cited_gt': ('int', ),
            'cited_lt': ('int', ),
            'court': ('csv', ),
            'type': ('search', ),
        }
        ordering = [
            'dateFiled+desc',
            'dateFiled+asc',
            'dateArgued+desc',
            'dateArgued+asc',
            'citeCount+desc',
            'citeCount+asc',
            'score+desc',
        ]

    def get_resource_uri(self,
                         bundle_or_obj=None,
                         url_name='api_dispatch_list'):
        """Creates a URI like /api/v1/search/$id/
        """
        url_str = '/api/rest/%s/%s/%s/'
        if bundle_or_obj:
            return url_str % (
                self.api_name,
                'document',
                bundle_or_obj.obj.id,
            )
        else:
            return ''

    def get_object_list(self, request=None, **kwargs):
        """Performs the Solr work."""
        main_query = {'caller': 'api_search'}
        try:
            main_query.update(build_main_query(kwargs['cd'], highlight='text'))
            sl = SolrList(main_query=main_query,
                          offset=request.GET.get('offset', 0),
                          limit=request.GET.get('limit', 20),
                          type=kwargs['cd']['type'])
        except KeyError:
            sf = forms.SearchForm({'q': "*:*"})
            if sf.is_valid():
                main_query.update(
                    build_main_query(sf.cleaned_data, highlight='text'))
            sl = SolrList(
                main_query=main_query,
                offset=request.GET.get('offset', 0),
                limit=request.GET.get('limit', 20),
            )

        return sl

    def obj_get_list(self, bundle, **kwargs):
        search_form = forms.SearchForm(bundle.request.GET)
        if search_form.is_valid():
            cd = search_form.cleaned_data
            if cd['q'] == '':
                cd['q'] = '*:*'  # Get everything.
            return self.get_object_list(bundle.request, cd=cd)
        else:
            BadRequest("Invalid resource lookup data provided. Unable to "
                       "complete your query.")

    def obj_get(self, bundle, **kwargs):
        search_form = forms.SearchForm(bundle.request.GET)
        if search_form.is_valid():
            cd = search_form.cleaned_data
            cd['q'] = 'id:%s' % kwargs['pk']
            return self.get_object_list(bundle.request, cd=cd)[0]
        else:
            BadRequest("Invalid resource lookup data provided. Unable to "
                       "complete your request.")

    def apply_sorting(self, obj_list, options=None):
        """Since we're not using Django Model sorting, we just want to use
        our own, which is already passed into the search form anyway.

        Thus: Do nothing here.
        """
        return obj_list
class ChemblIdLookupResource(ChemblModelResource):

    resource_url = fields.CharField()
    score = fields.FloatField('score', use_in='search', null=True, blank=True)

    class Meta(ChemblResourceMeta):
        queryset = ChemblIdLookup.objects.all()
        es_join_column = 'chembl_id'
        es_multi_index_search_resources = [
            'molecule', 'document', 'assay', 'target'
        ]
        resource_name = 'chembl_id_lookup'
        collection_name = 'chembl_id_lookups'
        serializer = ChEMBLApiSerializer(resource_name,
                                         {collection_name: resource_name})
        fields = (
            'chembl_id',
            'entity_type',
            'status',
        )
        filtering = {
            'chembl_id': CHAR_FILTERS,
            'entity_type': CHAR_FILTERS,
            'status': CHAR_FILTERS,
        }
        ordering = [
            field for field in list(filtering.keys())
            if not ('comment' in field or 'description' in field)
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def alter_list_data_to_serialize(self, request, data):
        """
        A hook to alter list data just before it gets serialized & sent to the user.

        Useful for restructuring/renaming aspects of the what's going to be
        sent.

        Should accommodate for a list of objects, generally also including
        meta data.
        """
        bundles = data['chembl_id_lookups']
        for idx, bundle in enumerate(bundles):
            bundles[idx] = self.alter_detail_data_to_serialize(request, bundle)
        return data

# ----------------------------------------------------------------------------------------------------------------------

    def alter_detail_data_to_serialize(self, request, bundle):
        """
        A hook to alter detail data just before it gets serialized & sent to the user.

        Useful for restructuring/renaming aspects of the what's going to be
        sent.

        Should accommodate for receiving a single bundle of data.
        """
        datas = bundle.data
        detail_name = 'api_dispatch_detail'
        if datas.get('entity_type'):
            if datas['entity_type'] == 'COMPOUND':
                datas['resource_url'] = molecule._build_reverse_url(
                    detail_name, kwargs=molecule.resource_uri_kwargs(bundle))
            elif datas['entity_type'] == 'ASSAY':
                datas['resource_url'] = assay._build_reverse_url(
                    detail_name, kwargs=assay.resource_uri_kwargs(bundle))
            elif datas['entity_type'] == 'TARGET':
                datas['resource_url'] = target._build_reverse_url(
                    detail_name, kwargs=target.resource_uri_kwargs(bundle))
            elif datas['entity_type'] == 'DOCUMENT':
                datas['resource_url'] = document._build_reverse_url(
                    detail_name, kwargs=document.resource_uri_kwargs(bundle))
            elif datas['entity_type'] == 'CELL':
                kw = cell.resource_uri_kwargs(bundle)
                kw['cell_chembl_id'] = kw['pk']
                del kw['pk']
                datas['resource_url'] = cell._build_reverse_url(detail_name,
                                                                kwargs=kw)
        return bundle

# ----------------------------------------------------------------------------------------------------------------------

    def prepend_urls(self):
        """
        Returns a URL scheme based on the default scheme to specify
        the response format as a file extension, e.g. /api/v1/users.json
        """
        return [
            url(r"^(?P<resource_name>%s)/search%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)/search\.(?P<format>xml|json|jsonp|yaml)$"
                % self._meta.resource_name,
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_schema'),
                name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/datatables\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_datatables'),
                name="api_get_datatables"),
            url(r"^(?P<resource_name>%s)/set/(?P<%s_list>\w[\w/;-]*)\.(?P<format>\w+)$"
                % (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/(?P<%s>\w[\w/-]*)\.(?P<format>\w+)$" %
                (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
        ]
Exemplo n.º 7
0
class JobDuration(StatisticsResource):
    """
    Histograms of total job duration (from submission to completion)
    for completed jobs and for error jobs
    """
    status = fields.CharField(attribute="status")
    platform = fields.CharField(attribute="platform")
    values = fields.ListField(attribute="values")
    bins = fields.ListField(attribute="bins")
    max = fields.FloatField(attribute="max")

    class Meta:
        resource_name = "statistics/job-duration"
        list_allowed_methods = ['get']
        detail_allowed_methods = []

    def get_object_list(self, request):
        n_bins = int(request.GET.get("bins", 50))
        scale = request.GET.get("scale", "linear")
        requested_max = request.GET.get("max", None)

        all_jobs = Job.objects.annotate(
            duration=ExpressionWrapper(F('timestamp_completion') -
                                       F('timestamp_submission'),
                                       output_field=DurationField()))
        job_durations = []
        for status in ("finished", "error"):
            for platform in STANDARD_QUEUES:
                durations = [
                    x['duration'].total_seconds() for x in all_jobs.filter(
                        status=status, hardware_platform=platform).values(
                            'duration') if x['duration'] is not None
                ]
                durations = np.array(durations)
                negative_durations = (durations < 0)
                if negative_durations.any():
                    n_neg = negative_durations.sum()
                    logger.warning(
                        "There were {} negative durations ({}%) for status={} and platform={}"
                        .format(n_neg, 100 * n_neg / durations.size, status,
                                platform))
                    durations = durations[~negative_durations]
                if durations.size > 0:
                    if requested_max is None:
                        max = (durations.max() // n_bins + 1) * n_bins
                    else:
                        max = float(requested_max)
                    if scale == "log":
                        log_bins = np.linspace(0, np.ceil(np.log10(max)),
                                               n_bins)
                        values = np.histogram(np.log10(durations),
                                              bins=log_bins)[0]
                        #bins = np.power(10, log_bins)
                        bins = log_bins
                    else:  # linear, whatever the value of `scale`
                        values, bins = np.histogram(durations,
                                                    bins=n_bins,
                                                    range=(0, max))
                    job_durations.append(
                        Histogram(platform=platform,
                                  status=status,
                                  values=values.tolist(),
                                  bins=bins,
                                  scale=scale,
                                  max=max))
        return job_durations
Exemplo n.º 8
0
class MoleculeResource(ChemblModelResource):

    molecule_chembl_id = fields.CharField('chembl_id')
    molecule_properties = fields.ForeignKey(
        'chembl_webservices.resources.molecule.MoleculePropertiesResource',
        'compoundproperties',
        full=True,
        null=True,
        blank=True)
    molecule_hierarchy = fields.ForeignKey(
        'chembl_webservices.resources.molecule.MoleculeHierarchyResource',
        'moleculehierarchy',
        full=True,
        null=True,
        blank=True)
    molecule_structures = fields.ForeignKey(
        'chembl_webservices.resources.molecule.MoleculeStructuresResource',
        'compoundstructures',
        full=True,
        null=True,
        blank=True)
    molecule_synonyms = fields.ToManyField(
        'chembl_webservices.resources.molecule.MoleculeSynonymsResource',
        'moleculesynonyms_set',
        full=True,
        null=True,
        blank=True)
    helm_notation = fields.CharField('biotherapeutics__helm_notation',
                                     null=True,
                                     blank=True)
    biotherapeutic = fields.ForeignKey(
        'chembl_webservices.resources.bio_component.BiotherapeuticComponentsResource',
        'biotherapeutics',
        full=True,
        null=True,
        blank=True)
    atc_classifications = fields.ToManyField(
        'chembl_webservices.resources.atc.AtcResource',
        'atcclassification_set',
        full=False,
        null=True,
        blank=True)
    cross_references = fields.ToManyField(
        'chembl_webservices.resources.molecule.MoleculeXRefResource',
        'compoundxref_set',
        full=True,
        null=True,
        blank=True)
    score = fields.FloatField('score', use_in='search', null=True, blank=True)

    class Meta(ChemblResourceMeta):
        queryset = MoleculeDictionary.objects.all() if 'downgraded' not in available_fields else \
                    MoleculeDictionary.objects.exclude(downgraded=True)
        es_join_column = 'chembl_id'
        excludes = ['molregno']
        resource_name = 'molecule'
        collection_name = 'molecules'
        description = {
            'api_dispatch_list':
            '''
Retrieve list of molecules. Apart from the standard set of relation types, there is one specific operator:

*  __flexmatch__ \- matches _SMILES_ with the same structure, as opposed to exact match, for example:
    [`COc1ccc2[C@@H]3[C@H](COc2c1)C(C)(C)OC4=C3C(=O)C(=O)C5=C4OC`
    `(C)(C)[C@H]6COc7cc(OC)ccc7[C@@H]56`](https://www.ebi.ac.uk/chembl/api/data/molecule?molecule_structures__canonical_smiles__flexmatch=COc1ccc2[C@@H]3[C@H]%28COc2c1%29C%28C%29%28C%29OC4=C3C%28=O%29C%28=O%29C5=C4OC%28C%29%28C%29[C@H]6COc7cc%28OC%29ccc7[C@@H]56 "Example")
will match two molecules with:

*  `COc1ccc2[C@@H]3[C@H](COc2c1)C(C)(C)OC4=C3C(=O)C(=O)C5=C4OC`
`(C)(C)[C@H]6COc7cc(OC)ccc7[C@@H]56` and
*  `COc1ccc2[C@@H]3[C@H](COc2c1)C(C)(C)OC4=C3C(=O)C(=O)C5=C4OC`
`(C)(C)[C@@H]6COc7cc(OC)ccc7[C@H]56`

_SMILES_.
        '''
        }
        serializer = MoleculeSerializer(
            resource_name, {
                collection_name: resource_name,
                'biocomponents': 'biocomponent',
                'molecule_synonyms': 'synonym',
                'atc_classifications': 'level5'
            })
        detail_uri_name = 'chembl_id'

        prefetch_related = [
            Prefetch('moleculesynonyms_set'),
            Prefetch('atcclassification_set'),
            Prefetch('biotherapeutics__bio_component_sequences'),
            Prefetch('compoundproperties'),
            Prefetch('moleculehierarchy'),
            Prefetch('compoundstructures'),
            Prefetch('compoundxref_set',
                     queryset=CompoundXref.objects.only(
                         'pk', 'xref_name', 'xref_id', 'xref_src_db',
                         'molecule')),
            Prefetch('compoundxref_set__xref_src_db',
                     queryset=XrefSource.objects.only('pk')),
            Prefetch('moleculehierarchy__parent_molecule',
                     queryset=MoleculeDictionary.objects.only('chembl')),
        ]

        fields = (
            'atc_classifications',
            'availability_type',
            'biotherapeutic',
            'black_box_warning',
            'chebi_par_id',
            'chirality',
            'cross_references',
            'dosed_ingredient',
            'first_approval',
            'first_in_class',
            'helm_notation',
            'indication_class',
            'inorganic_flag',
            'max_phase',
            'molecule_chembl_id',
            'molecule_hierarchy',
            'molecule_properties',
            'molecule_structures',
            'molecule_type',
            'natural_product',
            'oral',
            'parenteral',
            'polymer_flag',
            'pref_name',
            'prodrug',
            'structure_type',
            'therapeutic_flag',
            'topical',
            'usan_stem',
            'usan_stem_definition',
            'usan_substem',
            'usan_year',
            'withdrawn_flag',
            'withdrawn_year',
            'withdrawn_country',
            'withdrawn_reason',
            'withdrawn_class',
        )

        filtering = {
            'availability_type': CHAR_FILTERS,
            'biotherapeutic': ALL_WITH_RELATIONS,
            'molecule_synonyms': ALL_WITH_RELATIONS,
            'black_box_warning': FLAG_FILTERS,
            'chebi_par_id': NUMBER_FILTERS,
            'chirality': NUMBER_FILTERS,
            'dosed_ingredient': FLAG_FILTERS,
            'first_approval': NUMBER_FILTERS,
            'first_in_class': FLAG_FILTERS,
            'indication_class': CHAR_FILTERS,
            'inorganic_flag': FLAG_FILTERS,
            'helm_notation': CHAR_FILTERS,
            'max_phase': NUMBER_FILTERS,
            'molecule_chembl_id': ALL,
            'atc_classifications': ALL_WITH_RELATIONS,
            'cross_references': ALL_WITH_RELATIONS,
            'molecule_hierarchy': ALL_WITH_RELATIONS,
            'molecule_properties': ALL_WITH_RELATIONS,
            'molecule_structures': ALL_WITH_RELATIONS,
            'molecule_type': CHAR_FILTERS,
            'natural_product': FLAG_FILTERS,
            'oral': FLAG_FILTERS,
            'parenteral': FLAG_FILTERS,
            'polymer_flag': FLAG_FILTERS,
            'pref_name': CHAR_FILTERS,
            'prodrug': FLAG_FILTERS,
            'structure_type': CHAR_FILTERS,
            'therapeutic_flag': FLAG_FILTERS,
            'topical': FLAG_FILTERS,
            'usan_stem': CHAR_FILTERS,
            'usan_stem_definition': CHAR_FILTERS,
            'usan_substem': CHAR_FILTERS,
            'usan_year': NUMBER_FILTERS,
            'withdrawn_flag': FLAG_FILTERS,
            'withdrawn_year': NUMBER_FILTERS,
            'withdrawn_country': CHAR_FILTERS,
            'withdrawn_reason': CHAR_FILTERS,
            'withdrawn_class': CHAR_FILTERS,
        }
        ordering = [
            'availability_type',
            'biotherapeutic',
            'black_box_warning',
            'chebi_par_id',
            'chirality',
            'dosed_ingredient',
            'first_approval',
            'first_in_class',
            'indication_class',
            'inorganic_flag',
            'helm_notation',
            'max_phase',
            'molecule_chembl_id',
            'molecule_hierarchy',
            'molecule_properties',
            'molecule_structures',
            'molecule_type',
            'natural_product',
            'oral',
            'parenteral',
            'polymer_flag',
            'pref_name',
            'prodrug',
            'structure_type',
            'therapeutic_flag',
            'topical',
            'usan_stem',
            'usan_stem_definition',
            'usan_substem',
            'usan_year',
            'withdrawn_flag',
            'withdrawn_year',
            'withdrawn_country',
            'withdrawn_reason',
            'withdrawn_class',
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def base_urls(self):

        return [
            url(r"^(?P<resource_name>%s)/search%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)/search\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/schema%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_schema'),
                name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/schema\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('get_schema'),
                name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/datatables\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_datatables'),
                name="api_get_datatables"),
            url(r"^(?P<resource_name>%s)/set/(?P<chembl_id_list>[Cc][Hh][Ee][Mm][Bb][Ll]\d[\d]*(;[Cc][Hh][Ee][Mm][Bb][Ll]\d[\d]*)*)%s$"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/set/(?P<chembl_id_list>[Cc][Hh][Ee][Mm][Bb][Ll]\d[\d]*(;[Cc][Hh][Ee][Mm][Bb][Ll]\d[\d]*)*)\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/set/(?P<molecule_structures__standard_inchi_key_list>[A-Z]{14}-[A-Z]{10}-[A-Z](;[A-Z]{14}-[A-Z]{10}-[A-Z])*)%s$"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/set/(?P<molecule_structures__standard_inchi_key_list>[A-Z]{14}-[A-Z]{10}-[A-Z](;[A-Z]{14}-[A-Z]{10}-[A-Z])*)\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/set/(?P<molecule_structures__canonical_smiles_list>[^jx]+(;[^jx]+)*)%s$"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/set/(?P<molecule_structures__canonical_smiles_list>[^jx]+(;[^jx]+)*)\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/(?P<chembl_id>[Cc][Hh][Ee][Mm][Bb][Ll]\d[\d]*)\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
            url(r"^(?P<resource_name>%s)/(?P<chembl_id>[Cc][Hh][Ee][Mm][Bb][Ll]\d[\d]*)%s$"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
            url(r"^(?P<resource_name>%s)/(?P<molecule_structures__standard_inchi_key>[A-Z]{14}-[A-Z]{10}-[A-Z])\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
            url(r"^(?P<resource_name>%s)/(?P<molecule_structures__standard_inchi_key>[A-Z]{14}-[A-Z]{10}-[A-Z])%s$"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
            url(r"^(?P<resource_name>%s)/(?P<molecule_structures__canonical_smiles>[^jx]+)\.(?P<format>xml|json|jsonp|yaml|sdf|mol)$"
                % self._meta.resource_name,
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
            url(r"^(?P<resource_name>%s)/(?P<molecule_structures__canonical_smiles>[^jx]+)%s$"
                % (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def prepend_urls(self):
        return []

# ----------------------------------------------------------------------------------------------------------------------

    def get_multiple(self, request, **kwargs):
        """
        Returns a serialized list of resources based on the identifiers
        from the URL.

        Calls ``obj_get`` to fetch only the objects requested. This method
        only responds to HTTP GET.

        Should return a HttpResponse (200 OK).
        """
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        detail_uri_name = None
        obj_identifiers = None

        for key, value in list(kwargs.items()):
            if key.endswith('_list'):
                detail_uri_name = key.split('_list')[0]
                obj_identifiers = value.split(';')
                break

        objects = []
        not_found = []
        base_bundle = self.build_bundle(request=request)

        for identifier in obj_identifiers:
            try:
                obj, _ = self.cached_obj_get(bundle=base_bundle,
                                             **{detail_uri_name: identifier})
                bundle = self.build_bundle(obj=obj, request=request)
                bundle = self.full_dehydrate(bundle, for_list=True, **kwargs)
                objects.append(bundle)
            except (ObjectDoesNotExist, Unauthorized):
                not_found.append(identifier)

        object_list = {
            self._meta.collection_name: objects,
        }

        if len(not_found):
            object_list['not_found'] = not_found

        self.log_throttled_access(request)
        return self.create_response(request, object_list)

# ----------------------------------------------------------------------------------------------------------------------

    def decode_plus(self, kwargs):
        return {
            k: v.replace(' ', '+') if
            (isinstance(k, str)
             and k.startswith('molecule_structures__canonical_smiles')) else v
            for k, v in list(kwargs.items())
        }

# ----------------------------------------------------------------------------------------------------------------------

    def remove_api_resource_names(self, kwargs):
        aliases = {'smiles': 'molecule_structures__canonical_smiles'}
        for alias, name in list(aliases.items()):
            if alias in kwargs:
                kwargs[name] = kwargs.pop(alias)
        decoded_kwargs = self.decode_plus(kwargs)
        return super(MoleculeResource,
                     self).remove_api_resource_names(decoded_kwargs)

# ----------------------------------------------------------------------------------------------------------------------

    def alter_list_data_to_serialize(self, request, data):
        bundles = data['molecules']
        for idx, bundle in enumerate(bundles):
            bundles[idx] = self.alter_detail_data_to_serialize(request, bundle)
        return data

# ----------------------------------------------------------------------------------------------------------------------

    def alter_detail_data_to_serialize(self, request, data):
        if 'molecule_structures' in data.data:
            mol_struts = data.data['molecule_structures']
            sdf_style = request.format != 'mol'
            if mol_struts is not None and mol_struts.data is not None and sdf_style:
                mol_struts.data[
                    'molfile'] += '\n\n> <chembl_id>\n{0}\n\n'.format(
                        data.data.get('molecule_chembl_id'))
                mol_struts.data[
                    'molfile'] += '> <chembl_pref_name>\n{0}\n\n'.format(
                        data.data.get('pref_name', 'undefined'))
        if 'atc_classifications' in data.data:
            atc = data.data['atc_classifications']
            for idx, item in enumerate(atc):
                atc[idx] = item.split('/')[-1]
        return data

# ----------------------------------------------------------------------------------------------------------------------

    def elastic_search_flexmatch(self, smiles):
        smiles_2_inchi_key_url = settings.BEAKER_URL + '/smiles2inchiKey'
        inchikey_resp = requests.post(smiles_2_inchi_key_url, data=smiles)
        if inchikey_resp.status_code != 200 or inchikey_resp.text.strip(
        ) == "":
            raise ImmediateHttpResponse(response=http.HttpBadRequest(
                'ERROR: could not generate an inchi key for smiles.\n{}'.
                format(smiles)))
        connectivity_layer = inchikey_resp.text.split('-')[0]
        idx_name = (settings.ELASTICSEARCH_INDEXES_PREFIX +
                    '{0}').format('molecule')
        try:
            es_conn = get_es_connection()
            es_query = \
            {
                'track_total_hits': True,
                '_source': False,
                'query': {
                    'query_string': {
                        'query': '_metadata.hierarchy.family_inchi_connectivity_layer:{}'.format(connectivity_layer)
                    }
                }
            }
            search_results = elasticsearch.helpers.scan(es_conn,
                                                        query=es_query,
                                                        index=idx_name,
                                                        preserve_order=True,
                                                        size=1000)

            mol_chembl_ids = []
            for result_i in search_results:
                chembl_id = result_i['_id']
                mol_chembl_ids.append(chembl_id)
            return mol_chembl_ids
        except:
            self.log.error('Searching exception',
                           exc_info=True,
                           extra={
                               'user_query': connectivity_layer,
                           })
            raise RuntimeError(
                'Could not execute query on elasticsearch engine at {0}'.
                format(settings.ELASTICSEARCH_CONNECTION_URL))

# ----------------------------------------------------------------------------------------------------------------------

    def preprocess_filters(self, filters, for_cache_key=False):
        ret = {}
        for filter_expr, value in list(filters.items()):
            filter_bits = filter_expr.split(LOOKUP_SEP)
            if filter_expr == 'similarity':
                continue
            if len(filter_bits) and filter_bits[-1] == 'flexmatch':
                if not value.strip():
                    raise BadRequest("Input string is empty")
                if value.upper().startswith('CHEMBL'):
                    try:
                        mol = MoleculeDictionary.objects.get(
                            chembl_id=value.upper())
                        smiles = mol.compoundstructures.canonical_smiles
                        value = smiles
                    except ObjectDoesNotExist:
                        raise ImmediateHttpResponse(
                            response=http.HttpNotFound())
                if not for_cache_key:
                    molecule_chembl_ids_flexmatch = self.elastic_search_flexmatch(
                        value)
                    ret["molecule_chembl_id__in"] = molecule_chembl_ids_flexmatch
                    continue
            ret[filter_expr] = value
        return ret

# ----------------------------------------------------------------------------------------------------------------------

    def _get_cache_args(self, *args, **kwargs):
        cache_ordered_dict = super(MoleculeResource,
                                   self)._get_cache_args(*args, **kwargs)
        smooshed = []
        filters, _ = self.build_filters(kwargs, for_cache_key=True)
        for key, value in list(filters.items()):
            smooshed.append("%s=%s" % (key, value))
        cache_ordered_dict['filters'] = '|'.join(sorted(smooshed))
        return cache_ordered_dict
Exemplo n.º 9
0
class StatisticsResource(BaseModelResource):
    account_id = fields.IntegerField('account_id')
    handle = fields.CharField('account__key')
    contest_id = fields.IntegerField('contest_id')
    event = fields.CharField('contest__title')
    date = fields.DateTimeField('contest__end_time')
    coder_id = fields.IntegerField()
    place = fields.IntegerField('place_as_int', null=True)
    score = fields.FloatField('solving')
    new_rating = fields.IntegerField('new_rating', null=True)
    old_rating = fields.IntegerField('old_rating', null=True)
    rating_change = fields.IntegerField('rating_change', null=True)
    total_count = fields.BooleanField()

    class Meta(BaseModelResource.Meta):
        abstract = False
        queryset = Statistics.objects.all()
        resource_name = 'statistics'
        excludes = ('total_count', )
        filtering = {
            'total_count': ['exact'],
            'contest_id': ['exact'],
            'account_id': ['exact'],
            'coder_id': ['exact'],
            'place': ['exact', 'isnull'],
            'new_rating': ['isnull'],
            'rating_change': ['isnull'],
        }
        ordering = ['score', 'place', 'new_rating', 'rating_change', 'date']
        detail_allowed_methods = []

    def build_filters(self, filters=None, *args, **kwargs):
        filters = filters or {}
        tmp = {}
        for k in 'new_rating__isnull', 'rating_change__isnull', 'coder_id':
            tmp[k] = filters.pop(k, None)
        filters = super().build_filters(filters, *args, **kwargs)
        filters.update(tmp)
        return filters

    def apply_filters(self, request, applicable_filters):
        one_of = ['contest_id__exact', 'account_id__exact', 'coder_id']
        for k in one_of:
            if applicable_filters.get(f'{k}'):
                break
        else:
            raise BadRequest(
                f'One of {[k.split("__")[0] for k in one_of]} is required')

        rating_change_isnull = applicable_filters.pop('rating_change__isnull',
                                                      None)
        new_rating_isnull = applicable_filters.pop('new_rating__isnull', None)
        coder_id = applicable_filters.pop('coder_id', None)

        qs = super().apply_filters(request, applicable_filters)
        qs = qs.select_related('account', 'contest')

        if rating_change_isnull:
            qs = qs.filter(
                addition__rating_change__isnull=rating_change_isnull[0] in
                ['true', '1', 'yes'])
        if new_rating_isnull:
            qs = qs.filter(addition__new_rating__isnull=new_rating_isnull[0] in
                           ['true', '1', 'yes'])
        if coder_id:
            qs = qs.filter(account__coders=coder_id[0])

        qs = qs \
            .annotate(new_rating=Cast(KeyTextTransform('new_rating', 'addition'), IntegerField())) \
            .annotate(old_rating=Cast(KeyTextTransform('old_rating', 'addition'), IntegerField())) \
            .annotate(rating_change=Cast(KeyTextTransform('rating_change', 'addition'), IntegerField()))

        return qs

    def dehydrate(self, *args, **kwargs):
        bundle = super().dehydrate(*args, **kwargs)
        bundle.data.pop('coder_id', None)
        return bundle
Exemplo n.º 10
0
class AssayResource(ChemblModelResource):

    assay_chembl_id = fields.CharField('chembl_id', null=True, blank=True)
    document_chembl_id = fields.CharField('doc__chembl_id',
                                          null=True,
                                          blank=True)
    target_chembl_id = fields.CharField('target__chembl_id',
                                        null=True,
                                        blank=True)
    tissue_chembl_id = fields.CharField('tissue__chembl_id',
                                        null=True,
                                        blank=True)
    cell_chembl_id = fields.CharField('cell__chembl_id', null=True, blank=True)
    assay_type = fields.CharField('assay_type__assay_type',
                                  null=True,
                                  blank=True)
    assay_type_description = fields.CharField('assay_type__assay_desc',
                                              null=True,
                                              blank=True)
    relationship_type = fields.CharField(
        'relationship_type__relationship_type', null=True, blank=True)
    relationship_description = fields.CharField(
        'relationship_type__relationship_desc', null=True, blank=True)
    confidence_score = fields.IntegerField(
        'confidence_score__confidence_score', null=True, blank=True)
    confidence_description = fields.CharField('confidence_score__description',
                                              null=True,
                                              blank=True)
    src_id = fields.IntegerField('src_id', null=True, blank=True)
    bao_format = fields.CharField('bao_format_id', null=True, blank=True)
    bao_label = fields.CharField('bao_format__label', null=True, blank=True)
    score = fields.FloatField('score', use_in='search', null=True, blank=True)
    assay_classifications = fields.ToManyField(
        'chembl_webservices.resources.assays.AssayClassResource',
        'assayclassification_set',
        full=True,
        null=True,
        blank=True)
    assay_parameters = fields.ToManyField(
        'chembl_webservices.resources.assays.AssayParametersResource',
        'assayparameters_set',
        full=True,
        null=True,
        blank=True)
    variant_sequence = fields.ForeignKey(
        'chembl_webservices.resources.assays.VariantSequenceResource',
        'variant',
        full=True,
        null=True,
        blank=True)

    class Meta(ChemblResourceMeta):
        queryset = Assays.objects.all()
        es_join_column = 'chembl_id'
        excludes = ['assay_id']
        resource_name = 'assay'
        collection_name = 'assays'
        detail_uri_name = 'chembl_id'
        serializer = ChEMBLApiSerializer(
            resource_name, {
                collection_name: resource_name,
                'assay_classifications': 'assay_class',
                'assay_parameters': 'assay_parameters'
            })
        prefetch_related = [
            Prefetch('assay_type',
                     queryset=AssayType.objects.only('assay_type',
                                                     'assay_desc')),
            Prefetch('cell',
                     queryset=CellDictionary.objects.only('chembl_id')),
            Prefetch('confidence_score',
                     queryset=ConfidenceScoreLookup.objects.only(
                         'confidence_score', 'description')),
            Prefetch('doc', queryset=Docs.objects.only('chembl_id')),
            Prefetch('relationship_type',
                     queryset=RelationshipType.objects.only(
                         'relationship_type', 'relationship_desc')),
            Prefetch('src', queryset=Source.objects.only('src_id')),
            Prefetch('target',
                     queryset=TargetDictionary.objects.only('chembl_id')),
            Prefetch('tissue',
                     queryset=TissueDictionary.objects.only('chembl_id')),
            Prefetch('bao_format',
                     queryset=BioassayOntology.objects.only('bao_id',
                                                            'label')),
            Prefetch('assayclassification_set'),
            Prefetch('assayparameters_set'),
            Prefetch('variant'),
        ]

        fields = (
            'assay_classifications',
            'assay_category',
            'assay_cell_type',
            'assay_chembl_id',
            'assay_organism',
            'assay_strain',
            'assay_subcellular_fraction',
            'assay_tax_id',
            'assay_test_type',
            'assay_tissue',
            'assay_type',
            'assay_type_description',
            'bao_format',
            'cell_chembl_id',
            'confidence_description',
            'confidence_score',
            'description',
            'document_chembl_id',
            'relationship_description',
            'relationship_type',
            'src_assay_id',
            'src_id',
            'target_chembl_id',
            'variant_sequence',
        )

        filtering = {
            'assay_parameters': ALL_WITH_RELATIONS,
            'assay_classifications': ALL_WITH_RELATIONS,
            'assay_category': CHAR_FILTERS,
            'assay_cell_type': CHAR_FILTERS,
            'assay_chembl_id': ALL,
            'assay_organism': CHAR_FILTERS,
            'assay_strain': CHAR_FILTERS,
            'assay_subcellular_fraction': CHAR_FILTERS,
            'assay_tax_id': NUMBER_FILTERS,
            'assay_test_type': CHAR_FILTERS,
            'assay_tissue': CHAR_FILTERS,
            'assay_type': CHAR_FILTERS,
            #            'assay_type_description': ALL,
            'bao_format': ALL,
            'cell_chembl_id': CHAR_FILTERS,
            #            'confidence_description': ALL,
            'confidence_score': NUMBER_FILTERS,
            'description': CHAR_FILTERS,  #TODO: remove from ordering
            'document_chembl_id': ALL,
            #            'relationship_description': ALL,
            'relationship_type': CHAR_FILTERS,
            'src_assay_id': NUMBER_FILTERS,
            'src_id': NUMBER_FILTERS,
            'target_chembl_id': ALL,
            'variant_sequence': ALL_WITH_RELATIONS
        }
        ordering = [
            field for field in list(filtering.keys())
            if not ('comment' in field or 'description' in field)
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def prepend_urls(self):
        """
        Returns a URL scheme based on the default scheme to specify
        the response format as a file extension, e.g. /api/v1/users.json
        """
        return [
            url(r"^(?P<resource_name>%s)/search%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)/search\.(?P<format>xml|json|jsonp|yaml)$"
                % self._meta.resource_name,
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_schema'),
                name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/datatables\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_datatables'),
                name="api_get_datatables"),
            url(r"^(?P<resource_name>%s)/set/(?P<%s_list>\w[\w/;-]*)\.(?P<format>\w+)$"
                % (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/(?P<%s>\w[\w/-]*)\.(?P<format>\w+)$" %
                (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
        ]
Exemplo n.º 11
0
class TaskResource(LockTimeoutMixin, resources.Resource):
    TASK_TYPE = 'pending'
    SYNTHETIC_FIELDS = [
        'blocks',
    ]

    id = UUIDField(attribute='uuid', null=True)
    uuid = UUIDField(attribute='uuid')
    short_id = fields.IntegerField(attribute='id', null=True)
    status = fields.CharField(attribute='status')
    urgency = fields.FloatField(attribute='urgency')
    description = fields.CharField(attribute='description')
    priority = fields.CharField(attribute='priority', null=True)
    project = fields.CharField(attribute='project', null=True)
    due = fields.DateTimeField(attribute='due', null=True)
    entry = fields.DateTimeField(attribute='entry', null=True)
    modified = fields.DateTimeField(attribute='modified', null=True)
    start = fields.DateTimeField(attribute='start', null=True)
    wait = fields.DateTimeField(attribute='wait', null=True)
    scheduled = fields.DateTimeField(attribute='scheduled', null=True)
    depends = fields.ListField(attribute='depends', null=True)
    blocks = fields.ListField(attribute='blocks', null=True)
    annotations = fields.ListField(attribute='annotations', null=True)
    tags = fields.ListField(attribute='tags', null=True)
    imask = fields.IntegerField(attribute='imask', null=True)

    def prepend_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/sms/?$" %
                (self._meta.resource_name),
                self.wrap_view('incoming_sms'),
                name="incoming_sms"),
            url(
                r"^(?P<resource_name>%s)/(?P<uuid>[\w\d_.-]+)/start/?$" %
                (self._meta.resource_name), self.wrap_view('start_task')),
            url(
                r"^(?P<resource_name>%s)/(?P<uuid>[\w\d_.-]+)/stop/?$" %
                (self._meta.resource_name), self.wrap_view('stop_task')),
            url(
                r"^(?P<resource_name>%s)/(?P<uuid>[\w\d_.-]+)/delete/?$" %
                (self._meta.resource_name), self.wrap_view('delete')),
            url(r"^(?P<resource_name>%s)/lock/?$" % (self._meta.resource_name),
                self.wrap_view('manage_lock')),
            url(
                r"^(?P<resource_name>%s)/pebble-card/"
                r"(?P<secret_id>[\w\d_.-]+)/?$" % (self._meta.resource_name),
                self.wrap_view('pebble_card'),
                name='pebble_card_url',
            ),
            url(
                r"^(?P<resource_name>%s)/ical/(?P<variant>\w+)/"
                r"(?P<secret_id>[\w\d_.-]+)/?$" % (self._meta.resource_name),
                self.wrap_view('ical_feed'),
                name='ical_feed',
            ),
            url(
                r"^(?P<resource_name>%s)/refresh/?$" %
                (self._meta.resource_name),
                self.wrap_view('refresh_tasks'),
                name='refresh_tasks',
            ),
            url(
                r"^(?P<resource_name>%s)/revert/?$" %
                (self._meta.resource_name),
                self.wrap_view('revert_to_last_commit'),
                name='revert_to_last_commit',
            ),
            url(
                r"^(?P<resource_name>%s)/sync/?$" % (self._meta.resource_name),
                self.wrap_view('sync_immediately'),
                name='sync_immediately',
            ),
            url(
                r"^(?P<resource_name>%s)/sync-init/?$" %
                (self._meta.resource_name),
                self.wrap_view('sync_init'),
                name='sync_init',
            ),
            url(
                r"^(?P<resource_name>%s)/trello/?$" %
                (self._meta.resource_name),
                self.wrap_view('trello_authorize'),
                name='trello_authorize',
            ),
            url(
                r"^(?P<resource_name>%s)/trello/callback/?$" %
                (self._meta.resource_name),
                self.wrap_view('trello_callback'),
                name='trello_callback',
            ),
            url(
                r"^(?P<resource_name>%s)/bugwarrior/?$" %
                (self._meta.resource_name),
                self.wrap_view('bugwarrior_config'),
                name='bugwarrior_config',
            ),
            url(
                r"^(?P<resource_name>%s)/bugwarrior/sync/?$" %
                (self._meta.resource_name),
                self.wrap_view('bugwarrior_sync'),
                name='bugwarrior_sync',
            ),
            url(
                r"^(?P<resource_name>%s)/trello/incoming/"
                r"(?P<secret_id>[\w\d_.-]+)/?$" % (self._meta.resource_name),
                self.wrap_view('trello_incoming'),
                name='trello_incoming',
            ),
            url(
                r"^(?P<resource_name>%s)/trello/resynchronize/?$" %
                (self._meta.resource_name),
                self.wrap_view('trello_resynchronize'),
                name='trello_resynchronize',
            ),
            url(
                r"^(?P<resource_name>%s)/trello/reset/?$" %
                (self._meta.resource_name),
                self.wrap_view('trello_reset'),
                name='trello_reset',
            )
        ]

    def get_task_store(self, request):
        return models.TaskStore.get_for_user(request.user)

    def dehydrate(self, bundle):
        store = self.get_task_store(bundle.request)
        for key, data in store.client.config.get_udas().items():
            value = getattr(bundle.obj, key.encode('utf8'), None)
            bundle.data[key] = value
        return bundle

    def hydrate(self, bundle):
        store = self.get_task_store(bundle.request)
        for key, field_instance in store.client.config.get_udas().items():
            value = bundle.data.get(key, None)
            if value and isinstance(field_instance, DateField):
                try:
                    setattr(bundle.obj, key, parse(value))
                except (TypeError, ValueError):
                    raise exceptions.BadRequest(
                        "Invalid date provided for field %s: " % (
                            key,
                            value,
                        ))
            elif value:
                setattr(bundle.obj, key, value)

        try:
            depends = []
            for task_id in bundle.data.get('depends', []):
                depends.append(uuid.UUID(task_id))
            bundle.data['depends'] = depends
        except (TypeError, ValueError):
            raise exceptions.BadRequest(
                "Invalid task IDs provided for field depends: %s" %
                (bundle.data.get('depends')))

        return bundle

    @process_authentication()
    def manage_lock(self, request, **kwargs):
        store = self.get_task_store(request)
        lock_name = get_lock_name_for_store(store)
        client = get_lock_redis()

        if request.method == 'DELETE':
            value = client.delete(lock_name)
            if value:
                store.log_message("Lockfile deleted.")
                return HttpResponse(json.dumps({
                    'lock_status': value,
                }),
                                    status=200)
            store.log_error(
                "Attempted to delete lockfile, but repository was not locked.")
            return HttpResponse(json.dumps(
                {'error_message': 'Repository is not locked'}),
                                status=404)
        elif request.method == 'GET':
            value = client.get(lock_name)
            if value:
                return HttpResponse(json.dumps({
                    'lock_status': value,
                }),
                                    status=200)
            return HttpResponse(json.dumps(
                {'error_message': 'Repository is not locked'}),
                                status=404)
        return HttpResponseNotAllowed(request.method)

    @requires_task_store
    def revert_to_last_commit(self, request, store, **kwargs):
        if request.method != 'POST':
            return HttpResponseBadRequest(request.method)

        old_head = store.repository.head()
        new_head = store.repository.get_object(old_head).parents[0]

        with git_checkpoint(store, "Reverting to previous commit", sync=True):
            store.git_reset(new_head)

        store.log_message(
            "Taskstore was reverted from %s to %s via user-initiated "
            "revert operation.",
            old_head,
            new_head,
        )

        return HttpResponse(
            json.dumps({
                'message': 'OK',
                'old_head': old_head,
                'new_head': new_head
            }),
            content_type='application/json',
        )

    @requires_task_store
    def sync_immediately(self, request, store, **kwargs):
        if request.method != 'POST':
            return HttpResponseNotAllowed(request.method)

        result = store.sync(async=False)
        if not result:
            return HttpResponse(
                json.dumps({
                    'error_message': ('Synchronization is currently disabled '
                                      'for your account.')
                }),
                content_type='application/json',
                status=406,
            )
        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    @git_managed("Sync init", sync=False)
    def sync_init(self, request, store, **kwargs):
        if request.method != 'POST':
            return HttpResponseNotAllowed(request.method)

        store.client.sync(init=True)
        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    def bugwarrior_config(self, request, store, **kwargs):
        if request.method == 'DELETE':
            config = store.bugwarrior_config
            if not config:

                return HttpResponseNotFound()

            return HttpResponse(
                json.dumps({
                    'message': 'OK',
                }),
                content_type='application/json',
            )
        elif request.method == 'PUT':
            config = store.bugwarrior_config
            if not config:
                config = models.BugwarriorConfig.objects.create(
                    store=store,
                    enabled=True,
                )

            config.serialized_config = request.body
            try:
                config.validate_configuration()
                config.save()
            except Exception as e:
                return HttpResponseBadRequest(
                    json.dumps({
                        'error_message': unicode(e),
                    }),
                    content_type='application/json',
                )

            return HttpResponse(
                json.dumps({
                    'message': 'OK',
                }),
                content_type='application/json',
            )
        else:
            return HttpResponseNotAllowed(request.method)

    @requires_task_store
    def bugwarrior_sync(self, request, store, **kwargs):
        if request.method != 'POST':
            return HttpResponseNotAllowed(request.method)

        config = store.bugwarrior_config
        if not config:
            return HttpResponseNotFound()

        store.sync_bugwarrior()

        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    def trello_authorize(self, request, store, **kwargs):
        if request.method != 'GET':
            return HttpResponseNotAllowed(request.method)
        return HttpResponseRedirect(get_authorize_url(request))

    @requires_task_store
    def trello_reset(self, request, store, **kwargs):
        if request.method != 'POST':
            return HttpResponseNotAllowed(request.method)

        for obj in models.TrelloObject.objects.filter(store=store):
            obj.delete()

        with git_checkpoint(store,
                            "Reset trello IDs for pending/waiting tasks."):
            for task in store.client.filter_tasks({
                    'intheamtrelloid.any':
                    None,
                    'or': [
                        ('status', 'pending'),
                        ('status', 'waiting'),
                    ]
            }):
                task['intheamtrelloid'] = ''
                task['intheamtrelloboardid'] = ''
                task['intheamtrellolistid'] = ''
                store.client.task_update(task)

        store.trello_auth_token = ''
        store.save()

        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    def trello_resynchronize(self, request, store, **kwargs):
        if request.method != 'POST':
            return HttpResponseNotAllowed(request.method)

        sync_trello_tasks.apply_async(args=(store.pk, ))

        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    def trello_incoming(self, request, secret_id, **kwargs):
        try:
            store = models.TaskStore.objects.get(secret_id=secret_id)
        except:
            return HttpResponseNotFound()

        if not message_signature_is_valid(request):
            # @TODO: Once this is verified, return
            # HTTPRESPONSEBADREQUEST here.
            pass

        if request.method == 'POST':
            process_trello_action.apply_async(
                args=(store.pk, json.loads(request.body.decode('utf-8'))))

        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    def trello_callback(self, request, store, **kwargs):
        if request.method != 'GET':
            return HttpResponseNotAllowed(request.method)

        if 'trello_oauth_token' not in request.session:
            return HttpResponseBadRequest(
                'Arrived at Trello authorization URL without having '
                'initiated a Trello authorization!')

        token = get_access_token(request)

        store.trello_auth_token = token[0]
        if not store.trello_board:
            board = models.TrelloObject.create(
                store=store,
                type=models.TrelloObject.BOARD,
                name='Inthe.AM Tasks',
                desc='Tasks listed on your Inthe.AM account')
            for list_data in board.client.get_list(board.id):
                obj = models.TrelloObject.objects.create(
                    id=list_data.get('id'),
                    store=store,
                    type=models.TrelloObject.LIST,
                    parent=board,
                    meta=list_data)
                obj.subscribe()

        store.save()
        store.sync_trello()

        return HttpResponseRedirect('/')

    @requires_task_store
    def refresh_tasks(self, request, store, **kwargs):
        """ Refreshes the task list manually.

        .. warning::

           This method is DEPRECATED, and will be removed
           in a future version.

        """
        if request.method != 'GET':
            return HttpResponseNotAllowed(request.method)
        try:
            head = request.GET['head']
        except KeyError:
            return HttpResponseBadRequest()

        store.sync(async=False)

        changes = []

        new_head = store.repository.head()
        for id in store.get_changed_task_ids(head, new_head):
            changes.append({
                'action': 'task_changed',
                'body': id,
            })

        if new_head != head:
            changes.append({'action': 'head_changed', 'body': new_head})

        response = {
            'messages': changes,
        }

        return HttpResponse(
            json.dumps(response),
            content_type='application/json',
        )

    def ical_feed(self, request, variant, secret_id, **kwargs):
        if variant not in ('due', 'waiting'):
            return HttpResponseNotFound()
        try:
            store = models.TaskStore.objects.get(secret_id=secret_id)
        except:
            return HttpResponseNotFound()

        if not store.ical_enabled:
            return HttpResponseNotFound()

        if variant == 'due':
            calendar_title = "Tasks Due"
            task_filter = {
                'due.any': None,
                'status': 'pending',
            }
            field = 'due'
        elif variant == 'waiting':
            calendar_title = "Tasks Waiting"
            task_filter = {
                'status': 'waiting',
            }
            field = 'wait'

        tasks = store.client.filter_tasks(task_filter)

        calendar = Calendar()
        calendar.add('version', '2.0')
        calendar.add('prodid', '-//inthe.am//ical.%s//' % variant)
        calendar.add('X-WR-CALNAME', calendar_title)

        for task in tasks:
            event = Event()
            event.add('uid', task['uuid'])
            event.add('dtstart', task[field].date())
            event.add('dtend', task[field].date() + datetime.timedelta(days=1))
            event.add('dtstamp', task.get('modified', task['entry']))
            event.add('summary', task['description'])

            calendar.add_component(event)

        return HttpResponse(
            calendar.to_ical(),
            content_type='text/calendar',
        )

    def pebble_card(self, request, secret_id, **kwargs):
        if request.method != 'GET':
            return HttpResponseNotAllowed(request.method)
        try:
            store = models.TaskStore.objects.get(secret_id=secret_id)
        except:
            return HttpResponseNotFound()

        if not store.pebble_cards_enabled:
            return HttpResponseNotFound()

        pending_tasks = store.client.filter_tasks({'status': self.TASK_TYPE})
        pending_tasks = sorted(pending_tasks,
                               key=lambda d: float(d['urgency']),
                               reverse=True)

        response = {'content': None, 'refresh_frequency': 15}
        try:
            response['content'] = pending_tasks[0]['description']
        except IndexError:
            response['content'] = 'No tasks exist'

        return HttpResponse(
            json.dumps(response),
            content_type='application/json',
        )

    @requires_task_store
    @git_managed("Start task", sync=True)
    def start_task(self, request, uuid, store, **kwargs):
        if not request.method == 'POST':
            return HttpResponseNotAllowed(request.method)
        try:
            store.client.task_start(uuid=uuid)
        except ValueError:
            raise exceptions.NotFound()
        store.log_message("Task %s started.", uuid)
        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    @git_managed("Stop task", sync=True)
    def stop_task(self, request, uuid, store, **kwargs):
        if not request.method == 'POST':
            return HttpResponseNotAllowed(request.method)
        try:
            store.client.task_stop(uuid=uuid)
        except ValueError:
            raise exceptions.NotFound()
        store.log_message("Task %s stopped.", uuid)
        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    @requires_task_store
    @git_managed("Delete task", sync=True)
    def delete(self, request, uuid, store, **kwargs):
        if not request.method == 'POST':
            return HttpResponseNotAllowed(request.method)
        try:
            store.client.task_delete(uuid=uuid)
        except ValueError:
            raise exceptions.NotFound()

        store.log_message("Task %s deleted.", uuid)
        return HttpResponse(
            json.dumps({
                'message': 'OK',
            }),
            content_type='application/json',
        )

    def incoming_sms(self, request, username, **kwargs):
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            return HttpResponse(status=404)

        r = Response()

        # This request is unauthenticated; we'll need to fetch the user's
        # store directly rather than looking it up via the auth cookie.
        store = models.TaskStore.get_for_user(user)

        if not store.twilio_auth_token:
            log_args = (
                "Incoming SMS for %s, but no auth token specified.",
                user,
                user,
            )
            logger.warning(*log_args)
            store.log_error(*log_args)
            return HttpResponse(status=404)
        if store.sms_whitelist:
            incoming_number = re.sub('[^0-9]', '', request.POST['From'])
            valid_numbers = [
                re.sub('[^0-9]', '', n)
                for n in store.sms_whitelist.split('\n')
            ]
            if incoming_number not in valid_numbers:
                log_args = (
                    "Incoming SMS for %s, but phone number %s is not "
                    "in the whitelist.",
                    user,
                    incoming_number,
                )
                store.log_error(*log_args)
                logger.warning(*log_args,
                               extra={
                                   'data': {
                                       'incoming_number': incoming_number,
                                       'whitelist': valid_numbers,
                                   }
                               })
                return HttpResponseForbidden()
        try:
            validator = RequestValidator(store.twilio_auth_token)
            url = request.build_absolute_uri()
            signature = request.META['HTTP_X_TWILIO_SIGNATURE']
        except (AttributeError, KeyError) as e:
            log_args = (
                "Incoming SMS for %s, but error encountered while "
                "attempting to build request validator: %s.",
                user,
                e,
            )
            logger.exception(*log_args)
            store.log_error(*log_args)
            return HttpResponseForbidden()
        if not validator.validate(url, request.POST, signature):
            log_args = (
                "Incoming SMS for %s, but validator rejected message.",
                user,
            )
            logger.warning(*log_args)
            store.log_error(*log_args)
            return HttpResponseForbidden()

        with git_checkpoint(store, "Incoming SMS", sync=True):
            from_ = request.POST['From']
            body = request.POST['Body']
            task_info = body[4:]

            if not body.lower().startswith('add'):
                if store.sms_replies >= store.REPLY_ERROR:
                    r.sms("Bad Request: Unknown command.")
                log_args = (
                    "Incoming SMS from %s had no recognized command: '%s'." % (
                        from_,
                        body,
                    ), )
                logger.warning(*log_args)
                store.log_error(*log_args)
            elif not task_info:
                log_args = ("Incoming SMS from %s had no content." % (
                    from_,
                    body,
                ), )
                logger.warning(*log_args)
                store.log_error(*log_args)
                if store.sms_replies >= store.REPLY_ERROR:
                    r.sms("Bad Request: Empty task.")
            else:
                task_uuid = str(uuid.uuid4())
                task_args = (['add'] + shlex.split(store.sms_arguments) +
                             shlex.split(task_info))
                task_args.append('uuid:%s' % task_uuid)
                result = store.client._execute_safe(*task_args)
                stdout, stderr = result
                if store.sms_replies >= store.REPLY_ALL:
                    r.sms("Added.")

                log_args = ("Added task %s via SMS from %s; message '%s'; "
                            "automatic args: '%s';"
                            "response: '%s'." % (
                                task_uuid,
                                from_,
                                body,
                                store.sms_arguments,
                                stdout,
                            ), )
                logger.info(*log_args)
                store.log_message(*log_args)

        return HttpResponse(str(r), content_type='application/xml')

    def _get_store(self, user):
        return user.task_stores.get()

    def detail_uri_kwargs(self, bundle_or_obj):
        kwargs = {}

        if isinstance(bundle_or_obj, bundle.Bundle):
            kwargs['pk'] = bundle_or_obj.obj.uuid
        else:
            kwargs['pk'] = bundle_or_obj.uuid

        return kwargs

    def apply_sorting(self, obj_list, options=None):
        if options is None:
            options = {}

        parameter_name = 'order_by'

        if hasattr(options, 'getlist'):
            order_bits = options.getlist(parameter_name)
        else:
            order_bits = options.get(parameter_name)

            if not isinstance(order_bits, list, tuple):
                order_bits = [order_bits]

        if not order_bits:
            order_bits = ['-urgency']

        order_by_args = []
        for order_by in order_bits:
            order_by_bits = order_by.split(',')

            field_name = order_by_bits[0]
            reverse = False

            if order_by_bits[0].startswith('-'):
                field_name = order_by_bits[0][1:]
                reverse = True

            order_by_args.append((field_name, reverse))

        order_by_args.reverse()
        for arg, reverse in order_by_args:
            obj_list = sorted(
                obj_list,
                key=operator.attrgetter(arg),
                reverse=reverse,
            )

        return obj_list

    def passes_filters(self, task, filters):
        passes = True
        for key, value in filters.items():
            if key not in self.Meta.filter_fields:
                continue
            task_value = getattr(task, key, None)
            if task_value != value:
                passes = False
        return passes

    @requires_task_store
    def obj_get_list(self, bundle, store, **kwargs):
        if hasattr(bundle.request, 'GET'):
            filters = bundle.request.GET.copy()
        filters.update(kwargs)

        objects = []
        for task_json in store.client.filter_tasks({'status': self.TASK_TYPE}):
            task = Task(task_json, store=store)
            if self.passes_filters(task, filters):
                objects.append(task)

        return objects

    @requires_task_store
    def obj_get(self, bundle, store, **kwargs):
        task = store.client.get_task(uuid=kwargs['pk'])[1]
        if not task:
            repository_head = store.repository.head()
            logger.warning(
                'Unable to find task with ID %s in repository %s at %s',
                kwargs['pk'],
                store.local_path,
                repository_head,
                extra={
                    'data': {
                        'store': store,
                        'local_path': store.local_path,
                        'pk': kwargs['pk'],
                        'head': repository_head
                    }
                })
            raise exceptions.NotFound()
        return Task(task, store=store)

    @requires_task_store
    def obj_create(self, bundle, store, **kwargs):
        with git_checkpoint(store, "Creating Task", sync=True):
            if not bundle.data['description']:
                raise exceptions.BadRequest(
                    "You must specify a description for each task.")

            bundle.obj = self.get_empty_task(bundle.request)
            bundle = self.full_hydrate(bundle)
            data = bundle.obj.get_json()

            for k in self.SYNTHETIC_FIELDS:
                if k in data:
                    data.pop(k, None)
            for k, v in TaskwTask.FIELDS.items():
                if k in data and v.read_only:
                    data.pop(k, None)
            for k, v in data.items():
                if not v:
                    data.pop(k)

            bundle.obj = Task(
                store.client.task_add(**data),
                store=store,
            )
            store.log_message(
                "New task created: %s.",
                bundle.obj.get_json(),
            )
            return bundle

    @requires_task_store
    def obj_update(self, bundle, store, **kwargs):
        with git_checkpoint(store, "Updating Task", sync=True):
            if bundle.data['uuid'] != kwargs['pk']:
                raise exceptions.BadRequest(
                    "Changing the UUID of an existing task is not possible.")
            elif not bundle.data['description']:
                raise exceptions.BadRequest(
                    "You must specify a description for each task.")
            original = store.client.get_task(uuid=kwargs['pk'])[1]
            if not original:
                raise exceptions.NotFound()

            bundle.obj = self.get_empty_task(bundle.request)

            bundle = self.full_hydrate(bundle)

            data = bundle.obj.get_json()
            for k in json.loads(bundle.request.body).keys():
                v = data.get(k)
                if ((k in original.FIELDS and original.FIELDS[k].read_only)
                        or k in self.SYNTHETIC_FIELDS):
                    continue
                original[k] = v

            changes = original.get_changes(keep=True)

            store.client.task_update(original)
            store.log_message(
                "Task %s updated: %s.",
                kwargs['pk'],
                changes,
            )
            bundle.obj = Task(
                store.client.get_task(uuid=kwargs['pk'])[1],
                store=store,
            )
            return bundle

    @requires_task_store
    def obj_delete(self, bundle, store, **kwargs):
        with git_checkpoint(store, "Completing Task", sync=True):
            try:
                store.log_message("Task %s completed.", kwargs['pk'])
                store.client.task_done(uuid=kwargs['pk'])
                return bundle
            except ValueError:
                raise exceptions.NotFound()

    def obj_delete_list(self, bundle, store, **kwargs):
        raise exceptions.BadRequest()

    def dispatch(self, request_type, request, *args, **kwargs):
        if request.user.is_authenticated():
            metadata = models.UserMetadata.get_for_user(request.user)
        else:
            metadata = None
        if metadata and not metadata.tos_up_to_date:
            return HttpResponse(json.dumps({
                'error_message': ('Please accept the terms of service at '
                                  'https://inthe.am/terms-of-use.')
            }),
                                status=403)
        return super(TaskResource, self).dispatch(request_type, request, *args,
                                                  **kwargs)

    def get_empty_task(self, request):
        store = self.get_task_store(request)
        return self._meta.object_class(store=store)

    def build_bundle(self,
                     obj=None,
                     data=None,
                     request=None,
                     objects_saved=None):
        """ Builds the bundle!

        Overridden only to properly build the `Task` entry with its object.

        """
        if obj is None and self._meta.object_class:
            obj = self.get_empty_task(request)

        return Bundle(obj=obj,
                      data=data,
                      request=request,
                      objects_saved=objects_saved)

    class Meta:
        always_return_data = True
        authorization = authorization.Authorization()
        authentication = authentication.MultiAuthentication(
            authentication.SessionAuthentication(),
            authentication.ApiKeyAuthentication(),
        )
        list_allowed_methods = ['get', 'put', 'post', 'delete']
        detail_allowed_methods = ['get', 'put', 'post', 'delete']
        filter_fields = [
            'status',
            'due',
            'entry',
            'id',
            'imask',
            'modified',
            'parent',
            'recur',
            'status',
            'urgency',
            'uuid',
            'wait',
        ]
        limit = 100
        max_limit = 400
        object_class = Task
Exemplo n.º 12
0
class DocsResource(ChemblModelResource):

    document_chembl_id = fields.CharField('chembl_id', null=True, blank=True)
    score = fields.FloatField('score', use_in='search', null=True, blank=True)
    src_id = fields.IntegerField('src_id', null=True, blank=True)
    journal_full_title = fields.CharField('journal_id__title',
                                          null=True,
                                          blank=True)

    class Meta(ChemblResourceMeta):
        queryset = Docs.objects.all()
        haystack_queryset = Docs.objects.all().defer('abstract')
        excludes = ['doc_id']
        resource_name = 'document'
        collection_name = 'documents'
        detail_uri_name = 'chembl_id'
        serializer = ChEMBLApiSerializer(resource_name,
                                         {collection_name: resource_name})
        prefetch_related = [
            Prefetch('journal_id',
                     queryset=Journals.objects.only('pk', 'title'))
        ]

        fields = (
            'abstract',
            'authors',
            'doc_type',
            'document_chembl_id',
            'doi',
            'doi_chembl',
            'first_page',
            'issue',
            'journal',
            'last_page',
            'pubmed_id',
            'src_id',
            'title',
            'volume',
            'year',
            'patent_id',
            'journal_full_title',
        )

        filtering = {
            'abstract': CHAR_FILTERS,
            'authors': CHAR_FILTERS,
            'doc_type': CHAR_FILTERS,
            'document_chembl_id': NUMBER_FILTERS,
            'doi': CHAR_FILTERS,
            'doi_chembl': CHAR_FILTERS,
            'first_page': CHAR_FILTERS,
            'issue': CHAR_FILTERS,
            'journal': CHAR_FILTERS,
            'last_page': CHAR_FILTERS,
            'pubmed_id': NUMBER_FILTERS,
            'title': CHAR_FILTERS,
            'volume': CHAR_FILTERS,
            'year': NUMBER_FILTERS,
            'patent_id': CHAR_FILTERS,
            'journal_full_title': CHAR_FILTERS,
        }
        ordering = [
            field for field in filtering.keys()
            if not ('comment' in field or 'description' in field)
        ]

# ----------------------------------------------------------------------------------------------------------------------

    def prepend_urls(self):
        """
        Returns a URL scheme based on the default scheme to specify
        the response format as a file extension, e.g. /api/v1/users.json
        """
        return [
            url(r"^(?P<resource_name>%s)/search%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)/search\.(?P<format>xml|json|jsonp|yaml)$"
                % self._meta.resource_name,
                self.wrap_view('get_search'),
                name="api_get_search"),
            url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_schema'),
                name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/datatables\.(?P<format>\w+)$" %
                self._meta.resource_name,
                self.wrap_view('get_datatables'),
                name="api_get_datatables"),
            url(r"^(?P<resource_name>%s)/set/(?P<%s_list>\w[\w/;-]*)\.(?P<format>\w+)$"
                % (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('get_multiple'),
                name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/(?P<%s>\w[\w/-]*)\.(?P<format>\w+)$" %
                (self._meta.resource_name, self._meta.detail_uri_name),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
        ]
Exemplo n.º 13
0
class StatusResource(Resource):

    detector = fields.CharField(attribute="detector")
    node = fields.CharField(attribute="node")
    datarate = fields.FloatField(attribute="datarate")
    cpu = fields.FloatField(attribute="cpu")
    ram = fields.FloatField(attribute="ram")
    mode = fields.CharField(attribute="mode")
    user = fields.CharField(attribute="user")
    start = fields.DateTimeField()
    bltrate = fields.IntegerField(attribute="bltrate")
    state = fields.CharField(attribute="state")
    alerts = fields.IntegerField(attribute="alerts")

    class Meta:
        resource_name = 'daq_status'
        object_class = DAQStatus
        authorization = ReadOnlyAuthorization()
        authentication = ApiKeyAuthentication()
        throttle = CacheThrottle(throttle_at=10, timeframe=60)

    def _db(self):
        try:
            return (pymongo.MongoClient(
                settings.MONITOR_DB_ADDR)[settings.MONITOR_DB_NAME])
        except:
            return None

    # Needed by tastypie
    def detail_uri_kwargs(self, bundle_or_obj):
        kwargs = {}
        if isinstance(bundle_or_obj, Bundle):
            kwargs['pk'] = bundle_or_obj.obj.detector
        else:
            kwargs['pk'] = bundle_or_obj.detector

        return kwargs

    def get_object_list(self, request):
        self.throttle_check(request)
        self.log_throttled_access(request)
        det = 'tpc'
        if 'det' in request.GET:
            det = request.GET['det']
        return [self._create_obj(det)]

    def obj_get_list(self, bundle, **kwargs):
        return self.get_object_list(bundle.request)

    def obj_get(self, bundle, **kwargs):
        self.throttle_check(bundle.request)
        self.log_throttled_access(bundle.request)
        det = 'tpc'
        if 'det' in bundle.request.GET:
            det = bundle.request.GET['det']
        if 'pk' in kwargs:
            det = kwargs['pk']
        return self._create_obj(det)

    def _create_obj(self, det):
        try:
            doc = self._db()['daq_status'].find({
                "detector": det
            }).sort("_id", -1).limit(1)[0]
            ret = {
                "detector": doc["detector"],
                "node": "all",
                "state": doc['state'],
                "user": doc['startedBy'],
                "start": doc['startTime'],
                "bltrate": 0,
                "cpu": 0,
                "ram": 0,
                "run": doc['currentRun'],
                "datarate": 0,
                "mode": doc['mode'],
                "alerts": 0
            }
        except:
            ret = {
                "error": "error",
                "datarate": 0,
                "bltrate": 0,
                "cpu": 0,
                "alerts": 0,
                "ram": 0
            }

        # Alerts
        # 1: DAQ error 2: DB error 3: MV error 4: trig error 5: MV/trig
        errtxt = ""
        try:
            logcollection = self._db()["log"]
            cursor = logcollection.find({"priority": {"$gt": 2, "$lt": 5}})

            if cursor.count() != 0:
                ret["alerts"] = 1

            # Now try to guess which system done messed up
            breakout = False
            for doc in cursor:
                if breakout:
                    break

                errtext = doc['message']
                erruser = doc['sender']
                errtxt = dumps(doc)

                # TPC DAQ error in readers
                for reader in [
                        'reader0', 'reader1', 'reader2', 'reader3', 'reader4',
                        'reader6', 'reader7'
                ]:
                    if reader in errtext:
                        ret['alerts'] = 1
                        breakout = True

                # MV DAQ is reader5
                if 'reader5' in errtext:
                    if ret['alerts'] == 4 or ret['alerts'] == 5:
                        ret['alerts'] = 5
                        continue
                    ret['alerts'] = 3

                # Super long error means trigger
                if len(errtext) > 500 or erruser == 'trigger':
                    if ret['alerts'] == 3 or ret['alerts'] == 5:
                        ret['alerts'] = 5
                        continue
                    ret['alerts'] = 4

        except Exception as e:
            logger.error(str(e))
            logger.error(errtxt)
            ret['alerts'] = 2

        # This line disables SC alarms!
        #ret['alerts'] = 0

        nodes = ["reader5"]
        if det == "tpc":
            nodes = [
                "reader0", "reader1", "reader2", "reader3", "reader4",
                "reader6", "reader7"
            ]
        for node in nodes:
            cursor = self._db()['daq_rates'].find({
                "node": node
            }).sort("_id", -1).limit(1)
            if cursor.count() > 0:
                ret['datarate'] += cursor[0]['datarate']
                ret['bltrate'] += cursor[0]['bltrate']
                ret['cpu'] += cursor[0]['cpu']
                ret['ram'] += cursor[0]['ram']
        ret_obj = DAQStatus(initial=ret)
        return ret_obj

    def obj_create(self, bundle, **kwargs):
        pass

    def obj_update(self, bundle, **kwargs):
        pass

    def obj_delete_list(self, bundle, **kwargs):
        pass

    def obj_delete(self, bundle, **kwargs):
        pass

    def rollback(self, bundles):
        pass
Exemplo n.º 14
0
class FareResource(Resource):
    base_fare		= fields.FloatField(attribute="base_fare", null=True)
    base_km			= fields.FloatField(attribute="base_km", null=True)
    extra_km_fare	= fields.FloatField(attribute="extra_km_fare", null=True)
    flat_fare		= fields.FloatField(attribute="flat_fare", null=True)
    car_type		= fields.CharField(attribute="car_type", null=True)
    trip_type		= fields.CharField(attribute="trip_type", null=True)
    
    class Meta:
        include_resource_uri = False
        allowed_methods = ['get']
        resource_name = 'fare'
        object_class = DictObject       
        authorization= ReadOnlyAuthorization()
        authentication= BasicAuthentication()

    def get_city(self, name):
        KEY = CITY_KEY.format(name)
        city = cache.get(KEY, None)
        if city is None:
            try:
                city = City.objects.get(name=name)
                cache.set(KEY, city, settings.CACHE_TIMEOUT)
            except City.DoesNotExist:
                city = None        
        return city

    def get_trip(self, type): 
        KEY = TRIP_KEY.format(type)
        trip = cache.get(KEY, None)   
        if trip is None:    
            try:
                trip = TripType.objects.get(type=type)                
                cache.set(KEY, trip, settings.CACHE_TIMEOUT)
            except TripType.DoesNotExist:
                trip = None
        return trip

    def get_car(self, model):
        KEY = CAR_KEY.format(model)
        car = cache.get(KEY, None)   
        if car is None:   
            try:
                car = Car.objects.get(model=model)          
                cache.set(KEY, car, settings.CACHE_TIMEOUT)
            except Car.DoesNotExist:
                car = None
        return car

    def extra_charge(self, time, outside, fare_variation):
        extra_charge = 0.0
        try:
            hours = int(time.split(':')[0])
            assert 0<= hours <=23
        except Exception as e:
            hours = datetime.now().hour

        if hours >= settings.START_NIGHT or hours <= settings.END_NIGHT:
            extra_charge += fare_variation.outside_city
        if outside:
            extra_charge += fare_variation.outside_city
        
        return extra_charge

    def discount(self, date):
        try:
            date = datetime.strptime(date, "%Y-%m-%d")
        except:
            date = datetime.now()
        try:
            offer = Offer.objects.get(date=date.date())
            print offer
            return offer.discount_percent
        except:
            pass
        return 0.0

    def get_object_list(self, request):
        
        object_list = list()

        from_location = request.REQUEST.get('from_location', None)
        to_location = request.REQUEST.get('to_location', None)
        
        city_name = request.REQUEST.get('city', None)
        trip_type = request.REQUEST.get('trip_type', None)
        car_type = request.REQUEST.get('car_type', None)

        time = request.REQUEST.get('time', None)
        date = request.REQUEST.get('date', None)
        outside = request.REQUEST.get('outside', None)

        city = self.get_city(city_name)
        trip_obj = self.get_trip(trip_type)
        car = self.get_car(car_type)

        try:
            # Convert to True or False
            # if 'true' is given first make it 'True' and then convert
            outside = eval(outside.title())
        except:
            outside = False        

        if city and trip_obj:
            is_outside_trip = (trip_type.lower() == 'outstation') or outside
            extra_charges = self.extra_charge(time, is_outside_trip, city.farevariation)
            dicount = self.discount(date)
        
            fare = {'base_fare': city.base_fare, 'base_km': city.base_km, 'extra_km_fare': city.extra_km_fare}
            if car:
                total_extra_charges = extra_charges + car.fare_percent
                obj = self.get_fare_details(fare, total_extra_charges/100.0, dicount/100.0)
                object_list.append(obj)

                if not is_outside_trip:
                    KEY = CITY_TRIP_KEY.format(city.id, trip_obj.id)
                    city_trip = cache.get(KEY, None)
                    if city_trip is None:
                        city_trip = CityTrip.objects.filter(city=city, trip_type=trip_obj) 
                        cache.set(KEY, city_trip, settings.CACHE_TIMEOUT)
                    for ct in city_trip:
                        obj = DictObject()
                        obj.flat_fare = ct.flat_fare + ct.flat_fare*total_extra_charges/100.0 - ct.flat_fare*dicount/100.0
                        object_list.append(obj)
            else:
                cars = cache.get(ALL_CAR, None)
                if cars is None:
                    cars = Car.objects.all()
                    cache.set(ALL_CAR, cars, settings.CACHE_TIMEOUT)
                for car in cars:
                    total_extra_charges = extra_charges + car.fare_percent
                    obj = self.get_fare_details(fare, total_extra_charges/100.0, dicount/100.0)
                    obj.car_type = car.model
                    object_list.append(obj)

        return object_list

    def get_fare_details(self, fare, extra_charges=0.0, dicount=0.0):
        obj = DictObject()
        obj.base_fare       = fare['base_fare'] + fare['base_fare']*extra_charges - fare['base_fare']*dicount
        obj.base_km         = fare['base_km'] + fare['base_km']*extra_charges - fare['base_km']*dicount
        obj.extra_km_fare   = fare['extra_km_fare'] + fare['extra_km_fare']*extra_charges - fare['extra_km_fare']*dicount
        return obj
         
    def obj_get_list(self, bundle, **kwargs):    	
        request = bundle.request
        return self.get_object_list(request)
        
    def clean_bundle(self, bundle):
    	null_keys = [k for k, v in bundle.data.items() if v is None ]
    	for key in null_keys:
    		del bundle.data[key]

    def dehydrate(self, bundle):
        self.clean_bundle(bundle)
        return bundle         


        
Exemplo n.º 15
0
class UsageResource(Resource):
    symbol = fields.CharField(attribute='symbol')
    value = fields.FloatField(attribute='value')

    class Meta:
        object_class = UsageObject
Exemplo n.º 16
0
class CommonModelApi(ModelResource):
    keywords = fields.ToManyField(TagResource, 'keywords', null=True)
    category = fields.ToOneField(TopicCategoryResource,
                                 'category',
                                 null=True,
                                 full=True)
    owner = fields.ToOneField(UserResource, 'owner', full=True)
    absolute__url = fields.CharField()
    rating = fields.FloatField(attribute='rating', null=True)
    thumbnail_url = fields.CharField(null=True)

    def dehydrate_thumbnail_url(self, bundle):
        return bundle.obj.get_thumbnail_url()

    def dehydrate_absolute__url(self, bundle):
        return bundle.obj.get_absolute_url()

    def build_filters(self, filters={}):
        orm_filters = super(CommonModelApi, self).build_filters(filters)
        if 'type__in' in filters and filters['type__in'] in FILTER_TYPES.keys(
        ):
            orm_filters.update({'type': filters.getlist('type__in')})
        if 'extent' in filters:
            orm_filters.update({'extent': filters['extent'].split(',')})
        return orm_filters

    def apply_filters(self, request, applicable_filters):
        types = applicable_filters.pop('type', None)
        extent = applicable_filters.pop('extent', None)
        semi_filtered = super(CommonModelApi,
                              self).apply_filters(request, applicable_filters)
        filtered = None
        if types:
            for the_type in types:
                if the_type == 'vector' or the_type == 'raster':
                    if filtered:
                        filtered = filtered | semi_filtered.filter(
                            Layer___storeType=FILTER_TYPES[the_type])
                    else:
                        filtered = semi_filtered.filter(
                            Layer___storeType=FILTER_TYPES[the_type])
                else:
                    if filtered:
                        filtered = filtered | semi_filtered.instance_of(
                            FILTER_TYPES[the_type])
                    else:
                        filtered = semi_filtered.instance_of(
                            FILTER_TYPES[the_type])
        else:
            filtered = semi_filtered

        if extent:
            filtered = self.filter_bbox(filtered, extent)

        return filtered

    def filter_bbox(self, queryset, bbox):
        '''modify the queryset q to limit to data that intersects with the provided bbox 

        bbox - 4 tuple of floats representing 'southwest_lng,southwest_lat,northeast_lng,northeast_lat'
        returns the modified query
        '''
        bbox = map(str, bbox)  # 2.6 compat - float to decimal conversion
        intersects = ~(Q(bbox_x0__gt=bbox[2]) | Q(bbox_x1__lt=bbox[0])
                       | Q(bbox_y0__gt=bbox[3]) | Q(bbox_y1__lt=bbox[1]))
        return queryset.filter(intersects)
Exemplo n.º 17
0
class TaskResource(resources.Resource):
    TASK_TYPE = 'pending'

    id = fields.IntegerField(attribute='id', null=True)
    uuid = fields.CharField(attribute='uuid')
    status = fields.CharField(attribute='status')
    urgency = fields.FloatField(attribute='urgency')
    description = fields.CharField(attribute='description')
    priority = fields.CharField(attribute='priority', null=True)
    project = fields.CharField(attribute='project', null=True)
    due = fields.DateTimeField(attribute='due', null=True)
    entry = fields.DateTimeField(attribute='entry', null=True)
    modified = fields.DateTimeField(attribute='modified', null=True)
    start = fields.DateTimeField(attribute='start', null=True)
    wait = fields.DateTimeField(attribute='wait', null=True)
    scheduled = fields.DateTimeField(attribute='scheduled', null=True)
    depends = fields.CharField(attribute='depends', null=True)
    annotations = fields.ListField(attribute='annotations', null=True)
    tags = fields.ListField(attribute='tags', null=True)
    imask = fields.IntegerField(attribute='imask', null=True)

    def prepend_urls(self):
        return [
            url(
                r"^(?P<resource_name>%s)/autoconfigure/?$" % (
                    self._meta.resource_name
                ),
                self.wrap_view('autoconfigure')
            ),
            url(
                r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/sms/?$" % (
                    self._meta.resource_name
                ),
                self.wrap_view('incoming_sms'),
                name="incoming_sms"
            ),
            url(
                r"^(?P<resource_name>%s)/(?P<uuid>[\w\d_.-]+)/start/?$" % (
                    self._meta.resource_name
                ),
                self.wrap_view('start_task')
            ),
            url(
                r"^(?P<resource_name>%s)/(?P<uuid>[\w\d_.-]+)/stop/?$" % (
                    self._meta.resource_name
                ),
                self.wrap_view('stop_task')
            ),
            url(
                r"^(?P<resource_name>%s)/(?P<uuid>[\w\d_.-]+)/delete/?$" % (
                    self._meta.resource_name
                ),
                self.wrap_view('delete')
            ),
            url(
                r"^(?P<resource_name>%s)/lock/?$" % (
                    self._meta.resource_name
                ),
                self.wrap_view('manage_lock')
            ),
        ]

    def manage_lock(self, request, **kwargs):
        store = models.TaskStore.get_for_user(request.user)
        lockfile = os.path.join(store.local_path, '.lock')
        if request.method == 'DELETE':
            if os.path.exists(lockfile):
                os.unlink(lockfile)
                store.log_message("Lockfile deleted.")
                return HttpResponse(
                    '',
                    status=200
                )
            store.log_error(
                "Attempted to delete lockfile, but repository was not locked."
            )
            return HttpResponse(
                '',
                status=404
            )
        elif request.method == 'GET':
            if os.path.exists(lockfile):
                return HttpResponse(
                    '',
                    status=200
                )
            return HttpResponse(
                '',
                status=404
            )
        raise HttpResponseNotAllowed(request.method)

    @requires_taskd_sync
    @git_managed("Start task")
    def start_task(self, request, uuid, store, **kwargs):
        if not request.method == 'POST':
            return HttpResponseNotAllowed(request.method)
        try:
            store.client.task_start(uuid=uuid)
        except ValueError:
            raise exceptions.NotFound()
        store.log_message("Task %s started.", uuid)
        return HttpResponse(
            status=200
        )

    @requires_taskd_sync
    @git_managed("Stop task")
    def stop_task(self, request, uuid, store, **kwargs):
        if not request.method == 'POST':
            return HttpResponseNotAllowed(request.method)
        try:
            store.client.task_stop(uuid=uuid)
        except ValueError:
            raise exceptions.NotFound()
        store.log_message("Task %s stopped.", uuid)
        return HttpResponse(
            status=200
        )

    @requires_taskd_sync
    @git_managed("Delete task")
    def delete(self, request, uuid, store, **kwargs):
        if not request.method == 'POST':
            return HttpResponseNotAllowed(request.method)
        try:
            store.client.task_delete(uuid=uuid)
        except ValueError:
            raise exceptions.NotFound()

        store.log_message("Task %s deleted.", uuid)
        return HttpResponse(
            status=200
        )

    def incoming_sms(self, request, username, **kwargs):
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            return HttpResponse(status=404)

        r = Response()
        store = models.TaskStore.get_for_user(user)

        if not store.twilio_auth_token:
            log_args = (
                "Incoming SMS for %s, but no auth token specified.",
                user,
                user,
            )
            logger.warning(*log_args)
            store.log_error(*log_args)
            return HttpResponse(status=404)
        if store.sms_whitelist:
            incoming_number = re.sub('[^0-9]', '', request.POST['From'])
            valid_numbers = [
                re.sub('[^0-9]', '', n)
                for n in store.sms_whitelist.split('\n')
            ]
            if incoming_number not in valid_numbers:
                log_args = (
                    "Incoming SMS for %s, but phone number %s is not "
                    "in the whitelist.",
                    user,
                    incoming_number,
                )
                store.log_error(*log_args)
                logger.warning(
                    *log_args,
                    extra={
                        'data': {
                            'incoming_number': incoming_number,
                            'whitelist': valid_numbers,
                        }
                    }
                )
                return HttpResponseForbidden()
        try:
            validator = RequestValidator(store.twilio_auth_token)
            url = request.build_absolute_uri()
            signature = request.META['HTTP_X_TWILIO_SIGNATURE']
        except (AttributeError, KeyError) as e:
            log_args = (
                "Incoming SMS for %s, but error encountered while "
                "attempting to build request validator: %s.",
                user,
                e,
            )
            logger.warning(*log_args)
            store.log_error(*log_args)
            return HttpResponseForbidden()
        if not validator.validate(url, request.POST, signature):
            log_args = (
                "Incoming SMS for %s, but validator rejected message.",
                user,
            )
            logger.warning(*log_args)
            store.log_error(*log_args)
            return HttpResponseForbidden()

        with git_checkpoint(store, "Incoming SMS", sync=True):
            from_ = request.POST['From']
            body = request.POST['Body']
            task_info = body[4:]

            if not body.lower().startswith('add'):
                r.sms("Bad Request: Unknown command.")
                log_args = (
                    "Incoming SMS from %s had no recognized command: '%s'." % (
                        from_,
                        body,
                    ),
                )
                logger.warning(*log_args)
                store.log_error(*log_args)
            elif not task_info:
                log_args = (
                    "Incoming SMS from %s had no content." % (
                        from_,
                        body,
                    ),
                )
                logger.warning(*log_args)
                store.log_error(*log_args)
                r.sms("Bad Request: Empty task.")
            else:
                task_args = ['add'] + shlex.split(task_info)
                result = store.client._execute_safe(*task_args)
                stdout, stderr = result
                r.sms("Added.")

                log_args = (
                    "Added task from %s; message '%s'; response: '%s'." % (
                        from_,
                        body,
                        stdout,
                    ),
                )
                logger.info(*log_args)
                store.log_message(*log_args)

        return HttpResponse(str(r), content_type='application/xml')

    def autoconfigure(self, request, **kwargs):
        store = models.TaskStore.get_for_user(request.user)
        try:
            store.autoconfigure_taskd()
        except Exception as e:
            err_message = (
                "Error encountered while attempting to autoconfigure."
            )
            logger.exception(err_message)
            store.log_error(err_message)
            return HttpResponse(
                json.dumps({
                    'error': str(e)
                }),
                status=500,
                content_type='application/json',
            )
        store.log_message("Taskstore autoconfiguration completed.")
        return HttpResponse(
            json.dumps({
                'status': 'Successfully configured'
            }),
            status=200,
            content_type='application/json',
        )

    def _get_store(self, user):
        return user.task_stores.get()

    def detail_uri_kwargs(self, bundle_or_obj):
        kwargs = {}

        if isinstance(bundle_or_obj, bundle.Bundle):
            kwargs['pk'] = bundle_or_obj.obj.uuid
        else:
            kwargs['pk'] = bundle_or_obj.uuid

        return kwargs

    def apply_sorting(self, obj_list, options=None):
        if options is None:
            options = {}

        parameter_name = 'order_by'

        if hasattr(options, 'getlist'):
            order_bits = options.getlist(parameter_name)
        else:
            order_bits = options.get(parameter_name)

            if not isinstance(order_bits, list, tuple):
                order_bits = [order_bits]

        if not order_bits:
            order_bits = ['-urgency']

        order_by_args = []
        for order_by in order_bits:
            order_by_bits = order_by.split(',')

            field_name = order_by_bits[0]
            reverse = False

            if order_by_bits[0].startswith('-'):
                field_name = order_by_bits[0][1:]
                reverse = True

            order_by_args.append(
                (field_name, reverse)
            )

        order_by_args.reverse()
        for arg, reverse in order_by_args:
            obj_list = sorted(
                obj_list,
                key=operator.attrgetter(arg),
                reverse=reverse,
            )

        return obj_list

    def passes_filters(self, task, filters):
        passes = True
        for key, value in filters.items():
            if key not in self.Meta.filter_fields:
                continue
            task_value = getattr(task, key, None)
            if task_value != value:
                passes = False
        return passes

    @requires_taskd_sync
    def obj_get_list(self, bundle, store, **kwargs):
        if hasattr(bundle.request, 'GET'):
            filters = bundle.request.GET.copy()
        filters.update(kwargs)

        objects = []
        for task_json in store.client.load_tasks()[self.TASK_TYPE]:
            task = Task(task_json)
            if self.passes_filters(task, filters):
                objects.append(task)

        return objects

    @requires_taskd_sync
    def obj_get(self, bundle, store, **kwargs):
        try:
            return Task(store.client.get_task(uuid=kwargs['pk'])[1])
        except ValueError:
            raise exceptions.NotFound()

    @requires_taskd_sync
    def obj_create(self, bundle, store, **kwargs):
        with git_checkpoint(store, "Creating Task"):
            if not bundle.data['description']:
                raise exceptions.BadRequest(
                    "You must specify a description for each task."
                )
            safe_json = Task.from_serialized(bundle.data).get_safe_json()
            bundle.obj = Task(
                store.client.task_add(**safe_json)
            )
            store.log_message(
                "New task created: %s.", safe_json
            )
            return bundle

    @requires_taskd_sync
    def obj_update(self, bundle, store, **kwargs):
        with git_checkpoint(store, "Updating Task"):
            if bundle.data['uuid'] != kwargs['pk']:
                raise exceptions.BadRequest(
                    "Changing the UUID of an existing task is not possible."
                )
            elif not bundle.data['description']:
                raise exceptions.BadRequest(
                    "You must specify a description for each task."
                )
            bundle.data.pop('id', None)
            serialized = Task.from_serialized(bundle.data).get_safe_json()
            serialized['uuid'] = kwargs['pk']
            store.client.task_update(serialized)
            store.log_message(
                "Task %s updated: %s.",
                kwargs['pk'],
                serialized
            )
            bundle.obj = Task(store.client.get_task(uuid=kwargs['pk'])[1])
            return bundle

    def obj_delete_list(self, bundle, store, **kwargs):
        raise exceptions.BadRequest()

    def dispatch(self, request_type, request, *args, **kwargs):
        metadata = models.UserMetadata.get_for_user(request.user)
        if not metadata.tos_up_to_date:
            return HttpResponse(
                json.dumps(
                    {
                        'error_message': (
                            'Please accept the terms of service at '
                            'https://inthe.am/terms-of-use.'
                        )
                    }
                ),
                status=403
            )
        try:
            return super(TaskResource, self).dispatch(
                request_type, request, *args, **kwargs
            )
        except LockTimeout:
            message = (
                'Your task list is currently locked by another client.'
                'If this error persists, you may try '
                'clearing the lockfile by sending a DELETE request '
                'to http://inthe.am/api/v1/task/lock/. '
                'Please refer to the API documentation for details.'
            )
            store = models.TaskStore.get_for_user(request.user)
            store.log_error(message)
            return HttpResponse(
                json.dumps(
                    {
                        'error_message': message
                    }
                ),
                status=409,
            )

    @requires_taskd_sync
    def obj_delete(self, bundle, store, **kwargs):
        with git_checkpoint(store, "Completing Task"):
            try:
                store.log_message("Task %s completed.", kwargs['pk'])
                store.client.task_done(uuid=kwargs['pk'])
                return bundle
            except ValueError:
                raise exceptions.NotFound()

    class Meta:
        always_return_data = True
        authorization = authorization.Authorization()
        authentication = authentication.MultiAuthentication(
            authentication.SessionAuthentication(),
            authentication.ApiKeyAuthentication(),
        )
        list_allowed_methods = ['get', 'put', 'post', 'delete']
        detail_allowed_methods = ['get', 'put', 'post', 'delete']
        filter_fields = [
            'status',
            'due',
            'entry',
            'id',
            'imask',
            'modified',
            'parent',
            'recur',
            'status',
            'urgency',
            'uuid',
            'wait',
        ]
        limit = 100
        max_limit = 400
Exemplo n.º 18
0
def shotgun_entity_resource_factory(entity_type):
    schema = sg.schema().entityInfo(entity_type)

    class EntityResource(ShotgunEntityResource):
        _entity_type = entity_type
        _schema = schema

        class Meta(ShotgunEntityResource.Meta):
            resource_name = cammel_case_to_slug(entity_type)

    if schema:
        for field_name in sg.defaultEntityQueryFields(entity_type):
            field_info = schema.fieldInfos()[field_name]
            return_type = field_info.returnType()
            resource_field = dehydrate_method = None
            # RETURN_TYPE_CHECKBOX = 0
            if return_type == ShotgunORM.SgField.RETURN_TYPE_CHECKBOX:
                resource_field = fields.BooleanField(attribute=field_name, null=True)
            # RETURN_TYPE_DATE = 3
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_DATE:
                resource_field = fields.DateField(attribute=field_name, null=True)
            # RETURN_TYPE_DATE_TIME = 4
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_DATE_TIME:
                resource_field = fields.DateTimeField(attribute=field_name, null=True)
            # RETURN_TYPE_FLOAT = 6
            elif return_type ==ShotgunORM.SgField.RETURN_TYPE_FLOAT:
                resource_field = fields.FloatField(attribute=field_name, null=True)
            # RETURN_TYPE_INT = 8
            elif return_type ==ShotgunORM.SgField.RETURN_TYPE_INT:
                resource_field = fields.IntegerField(attribute=field_name, null=True)
            # RETURN_TYPE_URL = 16
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_URL:
                resource_field = fields.DictField(attribute=field_name, null=True)
            # RETURN_TYPE_TEXT = 15
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_TEXT:
                resource_field = fields.CharField(attribute=field_name, null=True)
            # RETURN_TYPE_ENTITY = 5
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_ENTITY:
                resource_field = fields.IntegerField(attribute=field_name, null=True)
                #def dehydrate_method_factory(field_name):
                #    def dehydrate_method(self, bundle):
                #        # assert False, bundle.data.keys()
                #        return bundle.data[field_name]
                #    return dehydrate_method
                #setattr(EntityResource, "dehydrate_%s" % field_name, dehydrate_method_factory(field_name))
            # RETURN_TYPE_MULTI_ENTITY = 10
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_MULTI_ENTITY:
                pass
                #resource_field = fields.CharField(attribute=field_name, null=True)
            # RETURN_TYPE_SERIALIZABLE = 11
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_SERIALIZABLE:
                resource_field = fields.DictField(attribute=field_name, null=True)
            # RETURN_TYPE_TAG_LIST = 14
            elif return_type == ShotgunORM.SgField.RETURN_TYPE_TAG_LIST:
                resource_field = fields.ListField(attribute=field_name, null=True)
            # RETURN_TYPE_LIST = 9
            # RETURN_TYPE_STATUS_LIST = 12
            # RETURN_TYPE_SUMMARY = 13
            # RETURN_TYPE_COLOR = 1
            # RETURN_TYPE_COLOR2 = 2
            # RETURN_TYPE_IMAGE = 7
            # RETURN_TYPE_UNSUPPORTED = -1
            elif return_type != ShotgunORM.SgField.RETURN_TYPE_UNSUPPORTED:
                resource_field = fields.CharField(attribute=field_name, null=True)

            if resource_field:
                EntityResource.base_fields[field_name] = resource_field

    return EntityResource