コード例 #1
0
ファイル: membership.py プロジェクト: jascoul/caleido
def membership_listing_view(request):
    qs = request.validated['querystring']
    params = dict(offset=qs['offset'],
                  limit=qs['limit'],
                  text_query=qs.get('query'),
                  order_by=qs.get('order_by'),
                  start_date=qs.get('start_date'),
                  end_date=qs.get('end_date'),
                  principals=request.effective_principals)

    if qs.get('person_id'):
        params['person_ids'] = [qs['person_id']]
    if qs.get('group_id'):
        params['group_ids'] = [qs['group_id']]
        params['group_ids'].extend(
            ResourceFactory(GroupResource)(request,
                                           qs['group_id']).child_groups())

    result = request.context.listing(**params)
    result['snippets'] = result.pop('hits')
    result['status'] = 'ok'
    return result
コード例 #2
0
ファイル: blob.py プロジェクト: jascoul/caleido
                                     missing=0)
        limit = colander.SchemaNode(colander.Int(),
                                    default=20,
                                    validator=colander.Range(0, 100),
                                    missing=20)


@resource(name='Blob',
          collection_path='/api/v1/blob/records',
          path='/api/v1/blob/records/{id}',
          tags=['blob'],
          cors_origins=('*', ),
          api_security=[{
              'jwt': []
          }],
          factory=ResourceFactory(BlobResource))
class BlobRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
              '200': BlobResponseSchema(description='Ok'),
              '401': ErrorResponseSchema(description='Unauthorized'),
              '403': ErrorResponseSchema(description='Forbidden'),
              '404': ErrorResponseSchema(description='Not Found'),
          })
    def get(self):
        "Retrieve a Blob"
コード例 #3
0
def work_listing_view(request):
    qs = request.validated['querystring']
    params = dict(offset = qs['offset'],
                  limit = qs['limit'],
                  text_query = qs.get('query'),
                  order_by = qs.get('order_by'),
                  start_date = qs.get('start_date'),
                  end_date = qs.get('end_date'),
                  type = qs.get('filter_type'),
                  principals=request.effective_principals)
    if qs.get('contributor_person_id'):
        params['contributor_person_ids'] = [qs['contributor_person_id']]
    if qs.get('contributor_group_id'):
        params['contributor_group_ids'] = [qs['contributor_group_id']]
    if qs.get('affiliation_group_id'):
        params['affiliation_group_ids'] = [qs['affiliation_group_id']]
        params['affiliation_group_ids'].extend(ResourceFactory(GroupResource)(
            request, qs['affiliation_group_id']).child_groups())
    if qs.get('related_work_id'):
        params['related_work_ids'] = [qs['related_work_id']]

    result = request.context.listing(**params)

    def csl_convert(item):
        issued = datetime.datetime.strptime(item['issued'], '%Y-%m-%d')
        date_parts = [issued.year]
        if not (issued.month == 1 and issued.day == 1):
            date_parts.append(issued.month)
            if issued.day != 1:
                date_parts.append(issued.day)

        authors = []
        editors = []
        for c in item['contributors']:
            contributor = {
                'given': c.get('given_name') or c.get('initials'),
                'family': c.get('family_name'),
                'initials': c.get('initials'),
                'non-dropping-particle': c.get('prefix')}
            if c['role'] == 'editor':
                editors.append(contributor)
            else:
                authors.append(contributor)
        type = 'entry'
        if 'chapter' in item['type'].lower():
            type = 'chapter'
        elif 'book' in item['type'].lower():
            type = 'book'
        elif 'article' in item['type'].lower():
            type = 'article-journal'
        elif 'paper' in item['type'].lower() or 'report' in item['type'].lower():
            type = 'report'

        journal = {}
        for rel in item.get('relations', []):
            if rel['relation_type'] == 'isPartOf' and rel['type'] == 'journal':
                journal['container-title'] = rel['title']
                if rel['issue']:
                    journal['issue'] = rel['issue']
                if rel['volume']:
                    journal['volume'] = rel['volume']
                if rel['starting'] and rel['ending']:
                    journal['page'] = '%s-%s' % (rel['starting'],
                                                 rel['ending'])
                break

        result = {'title': item['title'],
                  'id': str(item['id']),
                  'type': type,
                  'issued': {"date-parts": [date_parts]},
                  'author': authors,
                  'editor': editors}
        result.update(journal)
        return result

    if qs.get('format') == 'csl':
        result['hits'] = [csl_convert(h) for h in result['hits']]
    else:
        for hit in result['hits']:
            hit['csl'] = csl_convert(hit)

    result['snippets'] = result.pop('hits')
    result['status'] = 'ok'
    return result
コード例 #4
0
                                    default=20,
                                    validator=colander.Range(0, 100),
                                    missing=20)

class WorkBulkRequestSchema(colander.MappingSchema):
    @colander.instantiate()
    class records(colander.SequenceSchema):
        work = WorkSchema()

@resource(name='Work',
          collection_path='/api/v1/work/records',
          path='/api/v1/work/records/{id}',
          tags=['work'],
          cors_origins=('*', ),
          api_security=[{'jwt':[]}],
          factory=ResourceFactory(WorkResource))
class WorkRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
        '200': WorkResponseSchema(description='Ok'),
        '401': ErrorResponseSchema(description='Unauthorized'),
        '403': ErrorResponseSchema(description='Forbidden'),
        '404': ErrorResponseSchema(description='Not Found'),
        })
    def get(self):
        "Retrieve a Work"
        return WorkSchema().to_json(self.context.model.to_dict())
コード例 #5
0
ファイル: group.py プロジェクト: jascoul/caleido
class GroupBulkRequestSchema(colander.MappingSchema):
    @colander.instantiate()
    class records(colander.SequenceSchema):
        group = GroupSchema()


@resource(name='Group',
          collection_path='/api/v1/group/records',
          path='/api/v1/group/records/{id}',
          tags=['group'],
          cors_origins=('*', ),
          api_security=[{
              'jwt': []
          }],
          factory=ResourceFactory(GroupResource))
class GroupRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
              '200': GroupResponseSchema(description='Ok'),
              '401': ErrorResponseSchema(description='Unauthorized'),
              '403': ErrorResponseSchema(description='Forbidden'),
              '404': ErrorResponseSchema(description='Not Found'),
          })
    def get(self):
        "Retrieve a Group"
        return GroupSchema().to_json(self.context.model.to_dict())
コード例 #6
0
ファイル: membership.py プロジェクト: jascoul/caleido
class MembershipBulkRequestSchema(colander.MappingSchema):
    @colander.instantiate()
    class records(colander.SequenceSchema):
        membership = MembershipSchema()


@resource(name='Membership',
          collection_path='/api/v1/membership/records',
          path='/api/v1/membership/records/{id}',
          tags=['membership'],
          cors_origins=('*', ),
          api_security=[{
              'jwt': []
          }],
          factory=ResourceFactory(MembershipResource))
class MembershipRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
              '200': MembershipResponseSchema(description='Ok'),
              '401': ErrorResponseSchema(description='Unauthorized'),
              '403': ErrorResponseSchema(description='Forbidden'),
              '404': ErrorResponseSchema(description='Not Found'),
          })
    def get(self):
        "Retrieve a Membership"
        return MembershipSchema().to_json(self.context.model.to_dict())
コード例 #7
0
ファイル: membership.py プロジェクト: jascoul/caleido
    def collection_get(self):
        qs = self.request.validated['querystring']
        offset = qs['offset']
        limit = qs['limit']
        person_id = qs.get('person_id')
        group_id = qs.get('group_id')
        format = qs.get('format')
        order_by = []
        query = qs.get('query')
        filters = []
        if person_id:
            filters.append(Membership.person_id == person_id)
        if qs.get('start_date') or qs.get('end_date'):
            duration = DateInterval([qs.get('start_date'), qs.get('end_date')])
            filters.append(Membership.during.op('&&')(duration))

        if group_id:
            if qs['transitive']:
                # find
                group_ids = [group_id]
                group_ids.extend(
                    ResourceFactory(GroupResource)(self.request,
                                                   group_id).child_groups())
                filters.append(
                    sql.or_(*[Membership.group_id == g for g in group_ids]))
            else:
                filters.append(Membership.group_id == group_id)

        cte_total = None
        from_query = None
        query_callback = None
        if format == 'record':
            format = None
        elif format == 'snippet':
            from_query = self.context.session.query(Membership)

            def query_callback(from_query):
                filtered_members = from_query.cte('filtered_members')
                with_members = self.context.session.query(
                    func.min(
                        func.coalesce(func.lower(filtered_members.c.during),
                                      datetime.date(1900, 1,
                                                    1))).label('earliest'),
                    func.max(
                        func.coalesce(func.upper(filtered_members.c.during),
                                      datetime.date(2100, 1,
                                                    1))).label('latest'),
                    func.count(
                        filtered_members.c.id.distinct()).label('memberships'),
                    func.count(Contributor.work_id.distinct()).label('works'),
                    func.array_agg(Group.id.distinct()).label('group_ids'),
                    func.array_agg(Group.name.distinct()).label('group_names'),
                    func.max(filtered_members.c.id).label('id'),
                    Person.id.label('person_id'),
                    Person.name.label('person_name')).join(Person).join(
                        Group).outerjoin(Person.contributors)
                if query and group_id:
                    with_members = with_members.filter(
                        Person.family_name.ilike('%%%s%%' % query))
                with_members = with_members.group_by(Person.id, Person.name)
                return with_members.order_by(Person.name)

        listing = self.context.search(
            from_query=from_query,
            filters=filters,
            offset=offset,
            limit=limit,
            order_by=order_by,
            post_query_callback=query_callback,
            apply_limits_post_query={'snippet': True}.get(format, False),
            principals=self.request.effective_principals)
        schema = MembershipSchema()
        result = {
            'total': listing['total'] or cte_total,
            'records': [],
            'snippets': [],
            'limit': limit,
            'status': 'ok',
            'offset': offset
        }

        if format == 'snippet':
            snippets = []
            for hit in listing['hits']:
                #start_date, end_date = parse_duration(hit.during,
                #                                      format='%Y-%m-%d')
                earliest = hit.earliest
                if earliest:
                    if earliest.year == 1900:
                        earliest = None
                    else:
                        earliest = earliest.strftime('%Y-%m-%d')

                latest = hit.latest
                if latest:
                    if latest.year == 2100:
                        latest = None
                    else:
                        latest = latest.strftime('%Y-%m-%d')

                groups = [{
                    'id': i[0],
                    'name': i[1]
                } for i in zip(hit.group_ids, hit.group_names)]

                snippets.append({
                    'id': hit.id,
                    'person_id': hit.person_id,
                    'person_name': hit.person_name,
                    'groups': groups,
                    'earliest': earliest,
                    'latest': latest,
                    'works': hit.works,
                    'memberships': hit.memberships
                })
            result['snippets'] = snippets
        else:
            result['records'] = [
                schema.to_json(person.to_dict()) for person in listing['hits']
            ]

        return result
コード例 #8
0
ファイル: contributor.py プロジェクト: jascoul/caleido
    def collection_get(self):
        qs = self.request.validated['querystring']
        offset = qs['offset']
        limit = qs['limit']
        person_id = qs.get('person_id')
        group_id = qs.get('group_id')
        work_id = qs.get('group_id')
        format = qs.get('format')
        order_by = []
        query = qs.get('query')
        filters = []
        if person_id:
            filters.append(Contributor.person_id == person_id)
        if work_id:
            filters.append(Contributor.work_id == work_id)
        if group_id:
            if qs['transitive']:
                # find
                group_ids = [group_id]
                group_ids.extend(
                    ResourceFactory(GroupResource)(self.request,
                                                   group_id).child_groups())
                filters.append(
                    sql.or_(*[Contributor.group_id == g for g in group_ids]))
            else:
                filters.append(Contributor.group_id == group_id)

        cte_total = None
        from_query = None
        query_callback = None
        if format == 'record':
            format = None
        elif format == 'snippet':
            from_query = self.context.session.query(Contributor)

        listing = self.context.search(
            from_query=from_query,
            filters=filters,
            offset=offset,
            limit=limit,
            order_by=order_by,
            post_query_callback=query_callback,
            apply_limits_post_query={'snippet': True}.get(format, False),
            principals=self.request.effective_principals)
        schema = ContributorSchema()
        result = {
            'total': listing['total'] or cte_total,
            'records': [],
            'snippets': [],
            'limit': limit,
            'status': 'ok',
            'offset': offset
        }

        if format == 'snippet':
            snippets = []
            for hit in listing['hits']:
                snippets.append({
                    'id': hit.id,
                    'person_id': hit.person_id,
                    'person_name': hit.person_name,
                    'group_id': hit.group_id,
                    'group_name': hit.group_name,
                    'work_id': hit.work_id,
                    'work_name': hit.work_name
                })
            result['snippets'] = snippets
        else:
            result['records'] = [
                schema.to_json(contributor.to_dict())
                for contributor in listing['hits']
            ]

        return result
コード例 #9
0
ファイル: contributor.py プロジェクト: jascoul/caleido
class ContributorBulkRequestSchema(colander.MappingSchema):
    @colander.instantiate()
    class records(colander.SequenceSchema):
        contributor = ContributorSchema()


@resource(name='Contributor',
          collection_path='/api/v1/contributor/records',
          path='/api/v1/contributor/records/{id}',
          tags=['contributor'],
          cors_origins=('*', ),
          api_security=[{
              'jwt': []
          }],
          factory=ResourceFactory(ContributorResource))
class ContributorRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
              '200': ContributorResponseSchema(description='Ok'),
              '401': ErrorResponseSchema(description='Unauthorized'),
              '403': ErrorResponseSchema(description='Forbidden'),
              '404': ErrorResponseSchema(description='Not Found'),
          })
    def get(self):
        "Retrieve a Contributor"
        return ContributorSchema().to_json(self.context.model.to_dict())
コード例 #10
0
ファイル: user.py プロジェクト: jascoul/caleido
                                    missing=20)
        format = colander.SchemaNode(colander.String(),
                                     validator=colander.OneOf(
                                         ['record', 'snippet']),
                                     missing=colander.drop)


@resource(name='User',
          collection_path='/api/v1/user/records',
          path='/api/v1/user/records/{id}',
          tags=['user'],
          cors_origins=('*', ),
          api_security=[{
              'jwt': []
          }],
          factory=ResourceFactory(UserResource))
class UserAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          cors_origins=('*', ),
          response_schemas={
              '200': UserResponseSchema(description='Ok'),
              '401': ErrorResponseSchema(description='Unauthorized'),
              '403': ErrorResponseSchema(description='Forbidden'),
              '404': ErrorResponseSchema(description='Not Found'),
          })
    def get(self):
        "Retrieve a User"
コード例 #11
0
                                    default=20,
                                    validator=colander.Range(0, 100),
                                    missing=20)

class PersonBulkRequestSchema(colander.MappingSchema):
    @colander.instantiate()
    class records(colander.SequenceSchema):
        person = PersonSchema()

@resource(name='Person',
          collection_path='/api/v1/person/records',
          path='/api/v1/person/records/{id}',
          tags=['person'],
          cors_origins=('*', ),
          api_security=[{'jwt':[]}],
          factory=ResourceFactory(PersonResource))
class PersonRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
        '200': PersonResponseSchema(description='Ok'),
        '401': ErrorResponseSchema(description='Unauthorized'),
        '403': ErrorResponseSchema(description='Forbidden'),
        '404': ErrorResponseSchema(description='Not Found'),
        })
    def get(self):
        "Retrieve a Person"
        return PersonSchema().to_json(self.context.model.to_dict())
コード例 #12
0
class AffiliationBulkRequestSchema(colander.MappingSchema):
    @colander.instantiate()
    class records(colander.SequenceSchema):
        affiliation = AffiliationSchema()


@resource(name='Affiliation',
          collection_path='/api/v1/affiliation/records',
          path='/api/v1/affiliation/records/{id}',
          tags=['affiliation'],
          cors_origins=('*', ),
          api_security=[{
              'jwt': []
          }],
          factory=ResourceFactory(AffiliationResource))
class AffiliationRecordAPI(object):
    def __init__(self, request, context):
        self.request = request
        self.context = context

    @view(permission='view',
          response_schemas={
              '200': AffiliationResponseSchema(description='Ok'),
              '401': ErrorResponseSchema(description='Unauthorized'),
              '403': ErrorResponseSchema(description='Forbidden'),
              '404': ErrorResponseSchema(description='Not Found'),
          })
    def get(self):
        "Retrieve an Affiliation"
        return AffiliationSchema().to_json(self.context.model.to_dict())