Example #1
0
            description=("The user or organization currently owning " "the transfered object"),
        ),
        "recipient": fields.Polymorph(
            person_mapping, readonly=True, description=("The user or organization receiving " "the transfered object")
        ),
        "subject": fields.Polymorph(subject_mapping, readonly=True, description="The transfered object"),
        "comment": fields.String(readonly=True, description="A comment about the transfer request"),
        "created": fields.ISODateTime(description="The transfer request date", readonly=True),
        "status": fields.String(enum=TRANSFER_STATUS.keys(), description="The current transfer request status"),
        "responded": fields.ISODateTime(description="The transfer response date", readonly=True),
        "reponse_comment": fields.String(readonly=True, description="A comment about the transfer response"),
    },
)


ns = api.namespace("transfer")


@ns.route("/", endpoint="transfers")
class TransferRequestAPI(API):
    @api.doc("list_transfers")
    @api.marshal_list_with(transfer_fields)
    def get(self):
        """List all transfer requests"""
        pass

    @api.doc("request_transfer")
    @api.expect(transfer_request_fields)
    @api.marshal_with(transfer_fields)
    def post(self):
        """Initiate transfer request"""
Example #2
0
from __future__ import unicode_literals

from celery import states
from celery.result import AsyncResult
from celery.utils import get_full_cls_name
from celery.utils.encoding import safe_repr
from flask import request

from udata.api import api, API, fields
from udata.auth import admin_permission
from udata.tasks import schedulables, celery

from .forms import CrontabTaskForm, IntervalTaskForm
from .models import PeriodicTask, PERIODS

ns = api.namespace('workers', 'Asynchronous workers related operations', path='')

crontab_fields = api.model('Crontab', {
    'minute': fields.String(description='Cron expression for minute', required=True, default='*'),
    'hour': fields.String(description='Cron expression for hour', required=True, default='*'),
    'day_of_week': fields.String(description='Cron expression for day of week', required=True, default='*'),
    'day_of_month': fields.String(description='Cron expression for day of month', required=True, default='*'),
    'month_of_year': fields.String(description='Cron expression for month of year', required=True, default='*'),
})

interval_fields = api.model('Interval', {
    'every': fields.Integer(description='The interval without unit', required=True),
    'period': fields.String(description='The period/interval type', required=True, enum=PERIODS),
})

job_fields = api.model('Job', {
Example #3
0
from udata.i18n import _
from udata.models import Dataset, TERRITORY_DATASETS
from udata.core.dataset.api_fields import dataset_ref_fields

from .api_fields import (
    level_fields,
    granularity_fields,
    zone_suggestion_fields,
    feature_collection_fields,
)
from .models import GeoZone, GeoLevel, spatial_granularities

GEOM_TYPES = ('Point', 'LineString', 'Polygon', 'MultiPoint',
              'MultiLineString', 'MultiPolygon')

ns = api.namespace('spatial', 'Spatial references')

suggest_parser = api.parser()
suggest_parser.add_argument('q',
                            type=unicode,
                            help='The string to autocomplete/suggest',
                            location='args',
                            required=True)
suggest_parser.add_argument('size',
                            type=int,
                            help='The amount of suggestion to fetch',
                            location='args',
                            default=10)

dataset_parser = api.parser()
dataset_parser.add_argument('dynamic',
Example #4
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from unittest import skip

from flask import url_for

from udata.auth import PermissionDenied
from udata.api import api, API
from udata.api.oauth2 import OAuth2Client, OAuth2Token
from udata.forms import Form, fields, validators

from . import APITestCase
from udata.core.user.factories import UserFactory

ns = api.namespace('fake', 'A Fake namespace')


class FakeForm(Form):
    required = fields.StringField(validators=[validators.required()])
    choices = fields.SelectField(choices=(('first', ''), ('second', '')))
    email = fields.StringField(validators=[validators.Email()])


@ns.route('/', endpoint='fake')
class FakeAPI(API):
    @api.secure
    def post(self):
        return {'success': True}

    def get(self):
Example #5
0
from flask_security import current_user
from flask_restplus.inputs import boolean

from udata.auth import admin_permission
from udata.api import api, API, fields
from udata.core.user.api_fields import user_ref_fields

from .forms import DiscussionCreateForm, DiscussionCommentForm
from .models import Message, Discussion
from .permissions import CloseDiscussionPermission
from .signals import (
    on_new_discussion, on_new_discussion_comment, on_discussion_closed,
    on_discussion_deleted
)

ns = api.namespace('discussions', 'Discussion related operations')

message_fields = api.model('DiscussionMessage', {
    'content': fields.String(description='The message body'),
    'posted_by': fields.Nested(user_ref_fields,
                               description='The message author'),
    'posted_on': fields.ISODateTime(description='The message posting date'),
})

discussion_fields = api.model('Discussion', {
    'id': fields.String(description='The discussion identifier'),
    'subject': fields.Nested(api.model_reference,
                             description='The discussion target object'),
    'class': fields.ClassName(description='The object class',
                              discriminator=True),
    'title': fields.String(description='The discussion title'),
Example #6
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask.ext.security import current_user

from udata.api import api, ModelAPI, API
from udata.models import User, FollowUser, Reuse
from udata.forms import UserProfileForm

from udata.core.followers.api import FollowAPI
from udata.core.reuse.api_fields import reuse_fields

from .api_fields import user_fields

ns = api.namespace('users', 'User related operations')


@api.route('/me/', endpoint='me')
class MeAPI(ModelAPI):
    model = User
    form = UserProfileForm
    fields = user_fields
    decorators = [api.secure]

    def get_or_404(self, **kwargs):
        if not current_user.is_authenticated():
            api.abort(404)
        return current_user._get_current_object()


@api.route('/me/reuses/', endpoint='my_reuses')
Example #7
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals


from udata.api import api, API, ModelAPI, ModelListAPI, SingleObjectAPI
from udata.forms import ReuseForm
from udata.models import Reuse

from udata.core.issues.api import IssuesAPI
from udata.core.followers.api import FollowAPI

from .api_fields import reuse_fields, reuse_page_fields
from .models import ReuseIssue, FollowReuse
from .search import ReuseSearch

ns = api.namespace('reuses', 'Reuse related operations')

common_doc = {
    'params': {'reuse': 'The reuse ID or slug'}
}


@ns.route('/', endpoint='reuses')
@api.doc(get={'model': reuse_page_fields}, post={'model': reuse_fields})
class ReuseListAPI(ModelListAPI):
    model = Reuse
    form = ReuseForm
    fields = reuse_fields
    search_adapter = ReuseSearch

Example #8
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata.api import api, fields, API
from udata.auth import admin_permission


from udata.core.dataset.api_fields import dataset_fields
from udata.core.reuse.api_fields import reuse_fields
from udata.core.user.api_fields import user_ref_fields

from .models import Topic
from .forms import TopicForm

ns = api.namespace('topics', 'Topics related operations')

topic_fields = api.model('Topic', {
    'id': fields.String(description='The topic identifier'),
    'name': fields.String(description='The topic name', required=True),
    'slug': fields.String(
        description='The topic permalink string', readonly=True),
    'description': fields.Markdown(
        description='The topic description in Markdown', required=True),
    'tags': fields.List(
        fields.String, description='Some keywords to help in search', required=True),
    'datasets': fields.List(
        fields.Nested(dataset_fields), description='The topic datasets'),
    'reuses': fields.List(
        fields.Nested(reuse_fields), description='The topic reuses'),
    'featured': fields.Boolean(description='Is the topic featured'),
    'private': fields.Boolean(description='Is the topic private'),
Example #9
0
from .api_fields import (
    level_fields,
    granularity_fields,
    zone_suggestion_fields,
    feature_collection_fields,
)
from .models import GeoZone, GeoLevel, spatial_granularities


GEOM_TYPES = (
    'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString',
    'MultiPolygon'
)


ns = api.namespace('spatial', 'Spatial references')

suggest_parser = api.parser()
suggest_parser.add_argument(
    'q', type=unicode, help='The string to autocomplete/suggest',
    location='args', required=True)
suggest_parser.add_argument(
    'size', type=int, help='The amount of suggestion to fetch',
    location='args', default=10)

dataset_parser = api.parser()
dataset_parser.add_argument(
    'dynamic', type=inputs.boolean, help='Append dynamic datasets',
    location='args', required=False)
dataset_parser.add_argument(
    'size', type=int, help='The amount of datasets to fetch',
Example #10
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata.api import api, API, fields
from udata.search import es

DEFAULT_SIZE = 8

ns = api.namespace('suggest', 'Completion suggester APIs')

parser = api.parser()
parser.add_argument('q', type=str, help='The string to autocomplete/suggest', location='args', required=True)
parser.add_argument('size', type=int, help='The amount of suggestion to fetch', location='args', default=DEFAULT_SIZE)


@ns.route('/tags', endpoint='suggest_tags', doc={'parser': parser})
class SuggestTagsAPI(API):
    def get(self):
        '''Suggest tags'''
        args = parser.parse_args()
        result = es.suggest(index=es.index_name, body={
            'tags': {
                'text': args['q'],
                'completion': {
                    'field': 'tag_suggest',
                    'size': args['size'],
                }
            }
        })
        if 'tags' not in result:
            return []
Example #11
0
from udata.api import api, fields, API
from udata.auth import current_user

from .actions import get_notifications

notifs = api.namespace('notifications', 'Notifications API')

notifications_fields = api.model(
    'Notification', {
        'type':
        fields.String(description='The notification type', readonly=True),
        'created_on':
        fields.ISODateTime(description='The notification creation datetime',
                           readonly=True),
        'details':
        fields.Raw(
            description='Key-Value details depending on notification type',
            readonly=True)
    })


@notifs.route('/', endpoint='notifications')
class NotificationsAPI(API):
    @api.secure
    @api.doc('get_notifications')
    @api.marshal_list_with(notifications_fields)
    def get(self):
        '''List all current user pending notifications'''
        user = current_user._get_current_object()
        return get_notifications(user)
Example #12
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata.api import api, fields, API
from udata.auth import current_user

from .actions import get_notifications

notifs = api.namespace('notifications', 'Notifications API')

notifications_fields = api.model('Notification', {
    'type': fields.String(description='The notification type', readonly=True),
    'created_on': fields.ISODateTime(
        description='The notification creation datetime', readonly=True),
    'details': fields.Raw(
        description='Key-Value details depending on notification type',
        readonly=True)
})


@notifs.route('/', endpoint='notifications')
class NotificationsAPI(API):
    @api.secure
    @api.doc('get_notifications')
    @api.marshal_list_with(notifications_fields)
    def get(self):
        '''List all current user pending notifications'''
        user = current_user._get_current_object()
        return get_notifications(user)
Example #13
0
from udata.api import api
from udata.models import db

from udata.core.metrics.models import WithMetrics
from udata.core.user.views import blueprint as user_bp

from udata.core.issues.models import Issue, Message, ISSUE_TYPES
from udata.core.issues.metrics import IssuesMetric
from udata.core.issues.api import IssuesAPI

from .api import APITestCase
from .frontend import FrontTestCase
from .factories import faker, UserFactory, AdminFactory

bp = Blueprint('test_issues', __name__)
ns = api.namespace('test', 'A test namespace')


class Fake(WithMetrics, db.Document):
    name = db.StringField()


class FakeIssue(Issue):
    subject = db.ReferenceField(Fake)


class FakeIssuesMetric(IssuesMetric):
    model = Fake


@ns.route('/<id>/issues/', endpoint='fake_issues')
Example #14
0
    request_fields,
    member_fields,
    refuse_membership_fields,
)

from udata.core.dataset.api_fields import dataset_full_fields
from udata.core.dataset.models import Dataset
from udata.core.discussions.api import discussion_fields
from udata.core.discussions.models import Discussion
from udata.core.issues.api import issue_fields
from udata.core.issues.models import Issue
from udata.core.reuse.api_fields import reuse_fields
from udata.core.reuse.models import Reuse
from udata.core.storages.api import uploaded_image_fields, image_parser, parse_uploaded_image

ns = api.namespace("organizations", "Organization related operations")
search_parser = api.search_parser(OrganizationSearch)

common_doc = {"params": {"org": "The organization ID or slug"}}


@ns.route("/", endpoint="organizations")
class OrganizationListAPI(API):
    """Organizations collection endpoint"""

    @api.doc("list_organizations", parser=search_parser)
    @api.marshal_with(org_page_fields)
    def get(self):
        """List or search all organizations"""
        return search.query(OrganizationSearch, **multi_to_dict(request.args))
Example #15
0
from udata.core.storages.api import (
    uploaded_image_fields, image_parser, parse_uploaded_image
)

from .api_fields import (
    apikey_fields,
    me_fields,
    me_metrics_fields,
    user_fields,
    user_page_fields,
    user_suggestion_fields,
)
from .forms import UserProfileForm
from .search import UserSearch

ns = api.namespace('users', 'User related operations')
me = api.namespace('me', 'Connected user related operations')
search_parser = api.search_parser(UserSearch)
filter_parser = api.parser()
filter_parser.add_argument(
    'q', type=str, help='The string to filter items',
    location='args', required=False)


@me.route('/', endpoint='me')
class MeAPI(API):
    @api.secure
    @api.doc('get_me')
    @api.marshal_with(me_fields)
    def get(self):
        '''Fetch the current user (me) identity'''
Example #16
0
from udata.api import api, API, fields
from udata.auth import admin_permission

from udata.core.dataset.api_fields import dataset_ref_fields, dataset_fields
from udata.core.organization.api_fields import org_ref_fields
from udata.core.organization.permissions import EditOrganizationPermission
from udata.core.user.api_fields import user_ref_fields

from . import actions
from .forms import HarvestSourceForm, HarvestSourceValidationForm
from .models import (
    HARVEST_JOB_STATUS, HARVEST_ITEM_STATUS, HarvestJob,
    VALIDATION_STATES, VALIDATION_ACCEPTED
)

ns = api.namespace('harvest', 'Harvest related operations')

backends_ids = [b.name for b in actions.list_backends()]

error_fields = api.model('HarvestError', {
    'created_at': fields.ISODateTime(description='The error creation date',
                                     required=True),
    'message': fields.String(description='The error short message',
                             required=True),
    'details': fields.String(description='Optionnal details (ie. stacktrace)'),
})

item_fields = api.model('HarvestItem', {
    'remote_id': fields.String(description='The item remote ID to process',
                               required=True),
    'dataset': fields.Nested(dataset_ref_fields,
Example #17
0
from datetime import datetime

from flask_security import current_user
from flask_restplus.inputs import boolean

from udata.auth import admin_permission
from udata.api import api, API, fields
from udata.core.user.api_fields import user_ref_fields

from .forms import DiscussionCreateForm, DiscussionCommentForm
from .models import Message, Discussion
from .permissions import CloseDiscussionPermission
from .signals import (on_new_discussion, on_new_discussion_comment,
                      on_discussion_closed, on_discussion_deleted)

ns = api.namespace('discussions', 'Discussion related operations')

message_fields = api.model(
    'DiscussionMessage', {
        'content':
        fields.String(description='The message body'),
        'posted_by':
        fields.Nested(user_ref_fields, description='The message author'),
        'posted_on':
        fields.ISODateTime(description='The message posting date'),
    })

discussion_fields = api.model(
    'Discussion', {
        'id':
        fields.String(description='The discussion identifier'),
Example #18
0
from udata.api import api, API


from . import backends

ns = api.namespace('avatars', 'Avatars')


@ns.route('/<identifier>/<int:size>', endpoint='avatar')
class IdenticonAPI(API):
    @api.doc('avatars')
    def get(self, identifier, size):
        '''Get a deterministic avatar given an identifier at a given size'''
        return backends.get_identicon(identifier, size)
Example #19
0
from udata.api import api
from udata.models import db

from udata.core.metrics.models import WithMetrics
from udata.core.user.views import blueprint as user_bp

from udata.core.issues.models import Issue, Message, ISSUE_TYPES
from udata.core.issues.metrics import IssuesMetric
from udata.core.issues.api import IssuesAPI

from .api import APITestCase
from .factories import faker, UserFactory


bp = Blueprint('test_issues', __name__)
ns = api.namespace('test', 'A test namespace')


class Fake(WithMetrics, db.Document):
    name = db.StringField()


class FakeIssue(Issue):
    subject = db.ReferenceField(Fake)


class FakeIssuesMetric(IssuesMetric):
    model = Fake


@ns.route('/<id>/issues/', endpoint='fake_issues')
Example #20
0
from udata.api import api, fields, API
from udata.auth import admin_permission

from udata.core.dataset.api_fields import dataset_fields
from udata.core.reuse.api_fields import reuse_fields
from udata.core.user.api_fields import user_ref_fields

from .models import Topic
from .forms import TopicForm

ns = api.namespace('topics', 'Topics related operations')

topic_fields = api.model(
    'Topic', {
        'id':
        fields.String(description='The topic identifier'),
        'name':
        fields.String(description='The topic name', required=True),
        'slug':
        fields.String(description='The topic permalink string', readonly=True),
        'description':
        fields.Markdown(description='The topic description in Markdown',
                        required=True),
        'tags':
        fields.List(fields.String,
                    description='Some keywords to help in search',
                    required=True),
        'datasets':
        fields.List(fields.Nested(dataset_fields),
                    description='The topic datasets'),
        'reuses':
Example #21
0
                      description='A comment about the transfer request'),
        'created':
        fields.ISODateTime(description='The transfer request date',
                           readonly=True),
        'status':
        fields.String(enum=TRANSFER_STATUS.keys(),
                      description='The current transfer request status'),
        'responded':
        fields.ISODateTime(description='The transfer response date',
                           readonly=True),
        'reponse_comment':
        fields.String(readonly=True,
                      description='A comment about the transfer response'),
    })

ns = api.namespace('transfer')


@ns.route('/', endpoint='transfers')
class TransferRequestsAPI(API):
    @api.doc('list_transfers')
    @api.marshal_list_with(transfer_fields)
    def get(self):
        '''List all transfer requests'''
        pass

    @api.doc('request_transfer')
    @api.expect(transfer_request_fields)
    @api.marshal_with(transfer_fields)
    def post(self):
        '''Initiate transfer request'''
Example #22
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata import search
from udata.api import api, API

from udata.tags import normalize  # TODO: merge this into this package

DEFAULT_SIZE = 8

ns = api.namespace('tags', 'Tags related operations')

parser = api.parser()
parser.add_argument(
    'q', type=unicode, help='The string to autocomplete/suggest',
    location='args', required=True)
parser.add_argument(
    'size', type=int, help='The amount of suggestion to fetch',
    location='args', default=DEFAULT_SIZE)


@ns.route('/suggest/', endpoint='suggest_tags')
class SuggestTagsAPI(API):
    @api.doc('suggest_tags')
    @api.expect(parser)
    def get(self):
        '''Suggest tags'''
        args = parser.parse_args()
        q = normalize(args['q'])
        result = search.suggest(q, 'tag_suggest', args['size'])
        return sorted(result, key=lambda o: len(o['text']))
Example #23
0
    }

    @staticmethod
    def parse_filters(organizations, args):
        if args.get('q'):
            # Following code splits the 'q' argument by spaces to surround
            # every word in it with quotes before rebuild it.
            # This allows the search_text method to tokenise with an AND
            # between tokens whereas an OR is used without it.
            phrase_query = ' '.join(
                [f'"{elem}"' for elem in args['q'].split(' ')])
            organizations = organizations.search_text(phrase_query)
        return organizations


ns = api.namespace('organizations', 'Organization related operations')

organization_parser = OrgApiParser()

common_doc = {'params': {'org': 'The organization ID or slug'}}


@ns.route('/', endpoint='organizations')
class OrganizationListAPI(API):
    '''Organizations collection endpoint'''
    @api.doc('list_organizations')
    @api.expect(organization_parser.parser)
    @api.marshal_with(org_page_fields)
    def get(self):
        '''List or search all organizations'''
        args = organization_parser.parse()
Example #24
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from datetime import datetime

from flask.ext.security import current_user

from udata.api import api, API, marshal, fields

from udata.core.user.api_fields import user_ref_fields

from .forms import IssueCreateForm, IssueCommentForm
from .models import Issue, Message, ISSUE_TYPES
from .signals import on_new_issue, on_new_issue_comment, on_issue_closed

ns = api.namespace('issues', 'Issue related operations')

message_fields = api.model(
    'IssueMessage', {
        'content':
        fields.String(description='The message body', required=True),
        'posted_by':
        fields.Nested(
            user_ref_fields, description='The message author', required=True),
        'posted_on':
        fields.ISODateTime(description='The message posting date',
                           required=True),
    })

issue_fields = api.model(
    'Issue', {
Example #25
0
from udata.core.user.models import Role
from udata.utils import multi_to_dict

from .api_fields import (
    apikey_fields,
    me_fields,
    me_metrics_fields,
    user_fields,
    user_page_fields,
    user_suggestion_fields,
    user_role_fields,
)
from .forms import UserProfileForm, UserProfileAdminForm
from .search import UserSearch

ns = api.namespace('users', 'User related operations')
me = api.namespace('me', 'Connected user related operations')
search_parser = UserSearch.as_request_parser()
filter_parser = api.parser()
filter_parser.add_argument('q',
                           type=str,
                           help='The string to filter items',
                           location='args',
                           required=False)


@me.route('/', endpoint='me')
class MeAPI(API):
    @api.secure
    @api.doc('get_me')
    @api.marshal_with(me_fields)
Example #26
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from flask import url_for

from udata.api import api, API
from udata.forms import Form, fields

from . import APITestCase

ns = api.namespace('fake-ns', 'A Fake namespace')


@ns.route('/options', endpoint='fake-options')
class FakeAPI(API):
    def get(self):
        return {'success': True}


@ns.route('/fake-form', endpoint='fake-form')
class FakeFormAPI(API):
    def post(self):
        class FakeForm(Form):
            pass
        api.validate(FakeForm)
        return {'success': True}


class OptionsCORSTest(APITestCase):
    def test_should_allow_options_and_cors(self):
        '''Should allow OPTIONS operation and give cors parameters'''
Example #27
0
    upload_fields,
)
from udata.linkchecker.checker import check_resource
from .models import (
    Dataset, Resource, Checksum, License, UPDATE_FREQUENCIES,
    CommunityResource, RESOURCE_TYPES
)
from .permissions import DatasetEditPermission, ResourceEditPermission
from .forms import (
    ResourceForm, DatasetForm, CommunityResourceForm, ResourcesListForm
)
from .search import DatasetSearch

log = logging.getLogger(__name__)

ns = api.namespace('datasets', 'Dataset related operations')
search_parser = DatasetSearch.as_request_parser()
community_parser = api.parser()
community_parser.add_argument(
    'sort', type=str, default='-created', location='args',
    help='The sorting attribute')
community_parser.add_argument(
    'page', type=int, default=1, location='args', help='The page to fetch')
community_parser.add_argument(
    'page_size', type=int, default=20, location='args',
    help='The page size to fetch')
community_parser.add_argument(
    'organization', type=str,
    help='Filter activities for that particular organization',
    location='args')
community_parser.add_argument(
Example #28
0
File: api.py Project: grouan/udata
from udata.core.reuse.api_fields import reuse_fields

from udata.features.transfer.models import Transfer

from .api_fields import (
    me_fields,
    user_fields,
    user_page_fields,
    user_suggestion_fields,
    notifications_fields,
    avatar_fields,
)
from .forms import UserProfileForm
from .search import UserSearch

ns = api.namespace("users", "User related operations")
me = api.namespace("me", "Connected user related operations")
search_parser = api.search_parser(UserSearch)


@me.route("/", endpoint="me")
class MeAPI(API):
    @api.secure
    @api.doc("get_me")
    @api.marshal_with(me_fields)
    def get(self):
        """Fetch the current user (me) identity"""
        return current_user._get_current_object()

    @api.secure
    @api.marshal_with(user_fields)
Example #29
0
    upload_fields,
    schema_fields,
)
from udata.linkchecker.checker import check_resource
from .models import (Dataset, Resource, Checksum, License, UPDATE_FREQUENCIES,
                     CommunityResource, RESOURCE_TYPES, ResourceSchema)
from .permissions import DatasetEditPermission, ResourceEditPermission
from .forms import (ResourceForm, DatasetForm, CommunityResourceForm,
                    ResourcesListForm)
from .search import DatasetSearch
from .exceptions import (SchemasCatalogNotFoundException,
                         SchemasCacheUnavailableException)

log = logging.getLogger(__name__)

ns = api.namespace('datasets', 'Dataset related operations')
search_parser = DatasetSearch.as_request_parser()
community_parser = api.parser()
community_parser.add_argument('sort',
                              type=str,
                              default='-created',
                              location='args',
                              help='The sorting attribute')
community_parser.add_argument('page',
                              type=int,
                              default=1,
                              location='args',
                              help='The page to fetch')
community_parser.add_argument('page_size',
                              type=int,
                              default=20,
Example #30
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from datetime import datetime

from udata.api import api, ModelAPI, ModelListAPI, API, marshal
from udata.auth import current_user
from udata.forms import OrganizationForm, MembershipRequestForm, MembershipRefuseForm
from udata.models import Organization, MembershipRequest, Member, FollowOrg

from udata.core.followers.api import FollowAPI

from .search import OrganizationSearch
from .api_fields import org_fields, org_page_fields, request_fields, member_fields

ns = api.namespace('organizations', 'Organization related operations')

common_doc = {
    'params': {'org': 'The organization ID or slug'}
}


@ns.route('/', endpoint='organizations')
@api.doc(get={'model': org_page_fields}, post={'model': org_fields})
class OrganizationListAPI(ModelListAPI):
    model = Organization
    fields = org_fields
    form = OrganizationForm
    search_adapter = OrganizationSearch

Example #31
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata.api import api, fields, API
from udata.auth import admin_permission

from udata.core.dataset.api_fields import dataset_ref_fields
from udata.core.reuse.api_fields import reuse_ref_fields
from udata.core.user.api_fields import user_ref_fields

from .models import Post
from .forms import PostForm

ns = api.namespace('posts', 'Posts related operations')

post_fields = api.model(
    'Post', {
        'id':
        fields.String(description='The post identifier'),
        'name':
        fields.String(description='The post name', required=True),
        'slug':
        fields.String(description='The post permalink string', readonly=True),
        'headline':
        fields.String(description='The post headline', required=True),
        'content':
        fields.Markdown(description='The post content in Markdown',
                        required=True),
        'image':
        fields.ImageField(description='The post image'),
        'credit_to':
Example #32
0
from datetime import datetime

from flask.ext.security import current_user
from flask_restful.inputs import boolean

from udata.api import api, API, fields
from udata.models import Dataset, DatasetIssue, Reuse, ReuseIssue
from udata.core.user.api_fields import user_ref_fields

from .forms import IssueCommentForm, IssueCreateForm
from .models import Message, Issue
from .permissions import CloseIssuePermission
from .signals import on_new_issue, on_new_issue_comment, on_issue_closed

ns = api.namespace('issues', 'Issue related operations')

message_fields = api.model('IssueMessage', {
    'content': fields.String(description='The message body', required=True),
    'posted_by': fields.Nested(
        user_ref_fields, description='The message author', required=True),
    'posted_on': fields.ISODateTime(
        description='The message posting date', required=True),
})

issue_fields = api.model('Issue', {
    'id': fields.String(description='The issue identifier', readonly=True),
    'subject': fields.String(
        attribute='subject.id',
        description='The issue target object identifier', required=True),
    'class': fields.ClassName(description='The object class',
Example #33
0
from udata.core.badges import api as badges_api
from udata.core.dataset.api_fields import dataset_ref_fields
from udata.core.followers.api import FollowAPI
from udata.core.storages.api import (uploaded_image_fields, image_parser,
                                     parse_uploaded_image)

from .api_fields import (reuse_fields, reuse_page_fields,
                         reuse_suggestion_fields, reuse_type_fields,
                         reuse_topic_fields)
from .forms import ReuseForm
from .models import Reuse, REUSE_TYPES, REUSE_TOPICS
from .permissions import ReuseEditPermission
from .search import ReuseSearch

ns = api.namespace('reuses', 'Reuse related operations')

common_doc = {'params': {'reuse': 'The reuse ID or slug'}}
search_parser = ReuseSearch.as_request_parser()


@ns.route('/', endpoint='reuses')
class ReuseListAPI(API):
    @api.doc('list_reuses')
    @api.expect(search_parser)
    @api.marshal_with(reuse_page_fields)
    def get(self):
        search_parser.parse_args()
        return search.query(ReuseSearch, **multi_to_dict(request.args))

    @api.secure
Example #34
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata import search
from udata.api import api, API

from udata.tags import normalize  # TODO: merge this into this package

DEFAULT_SIZE = 8

ns = api.namespace('tags', 'Tags related operations')

parser = api.parser()
parser.add_argument('q',
                    type=unicode,
                    help='The string to autocomplete/suggest',
                    location='args',
                    required=True)
parser.add_argument('size',
                    type=int,
                    help='The amount of suggestion to fetch',
                    location='args',
                    default=DEFAULT_SIZE)


@ns.route('/suggest/', endpoint='suggest_tags')
class SuggestTagsAPI(API):
    @api.doc('suggest_tags')
    @api.expect(parser)
    def get(self):
        '''Suggest tags'''
Example #35
0
from __future__ import unicode_literals

from udata.api import api, API, fields
from udata.auth import admin_permission

from udata.core.dataset.api_fields import dataset_ref_fields, dataset_fields
from udata.core.organization.api_fields import org_ref_fields
from udata.core.organization.permissions import EditOrganizationPermission
from udata.core.user.api_fields import user_ref_fields

from . import actions
from .forms import HarvestSourceForm, HarvestSourceValidationForm
from .models import (HARVEST_JOB_STATUS, HARVEST_ITEM_STATUS, HarvestJob,
                     VALIDATION_STATES, VALIDATION_ACCEPTED)

ns = api.namespace('harvest', 'Harvest related operations')


def backends_ids():
    return [b.name for b in actions.list_backends()]


error_fields = api.model(
    'HarvestError', {
        'created_at':
        fields.ISODateTime(description='The error creation date',
                           required=True),
        'message':
        fields.String(description='The error short message', required=True),
        'details':
        fields.String(description='Optionnal details (ie. stacktrace)'),
Example #36
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata.api import api, fields, API
from udata.auth import admin_permission


from udata.core.dataset.api_fields import dataset_ref_fields
from udata.core.reuse.api_fields import reuse_ref_fields
from udata.core.user.api_fields import user_ref_fields

from .models import Post
from .forms import PostForm

ns = api.namespace('posts', 'Posts related operations')

post_fields = api.model('Post', {
    'id': fields.String(description='The post identifier'),
    'name': fields.String(description='The post name', required=True),
    'slug': fields.String(description='The post permalink string', readonly=True),
    'headline': fields.String(description='The post headline', required=True),
    'content': fields.Markdown(description='The post content in Markdown', required=True),

    'image': fields.ImageField(description='The post image'),
    'credit_to': fields.String(description='An optionnal credit line (associated to the image)'),
    'credit_url': fields.String(description='An optionnal link associated to the credits'),

    'tags': fields.List(fields.String, description='Some keywords to help in search'),
    'datasets': fields.List(fields.Nested(dataset_ref_fields), description='The post datasets'),
    'reuses': fields.List(fields.Nested(reuse_ref_fields), description='The post reuses'),
Example #37
0
        subject_mapping, readonly=True, description='The transfered object'),
    'comment': fields.String(
        readonly=True, description='A comment about the transfer request'),
    'created': fields.ISODateTime(
        description='The transfer request date', readonly=True),
    'status': fields.String(
        enum=TRANSFER_STATUS.keys(),
        description='The current transfer request status'),
    'responded': fields.ISODateTime(
        description='The transfer response date', readonly=True),
    'reponse_comment': fields.String(
        readonly=True, description='A comment about the transfer response'),
})


ns = api.namespace('transfer')


@ns.route('/', endpoint='transfers')
class TransferRequestAPI(API):
    @api.doc('list_transfers')
    @api.marshal_list_with(transfer_fields)
    def get(self):
        '''List all transfer requests'''
        pass

    @api.doc('request_transfer')
    @api.expect(transfer_request_fields)
    @api.marshal_with(transfer_fields)
    def post(self):
        '''Initiate transfer request'''
Example #38
0
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from udata import search
from udata.api import api, API

DEFAULT_SIZE = 8

ns = api.namespace("tags", "Tags related operations")

parser = api.parser()
parser.add_argument("q", type=str, help="The string to autocomplete/suggest", location="args", required=True)
parser.add_argument("size", type=int, help="The amount of suggestion to fetch", location="args", default=DEFAULT_SIZE)


@ns.route("/suggest/", endpoint="suggest_tags")
class SuggestTagsAPI(API):
    @api.doc(id="suggest_tags", parser=parser)
    def get(self):
        """Suggest tags"""
        args = parser.parse_args()
        result = search.suggest(args["q"], "tag_suggest", args["size"])
        return sorted(result, key=lambda o: len(o["text"]))