Пример #1
0
from pybossa.contributions_guard import ContributionsGuard
from pybossa.auth import jwt_authorize_project
from werkzeug.exceptions import MethodNotAllowed, Forbidden
from completed_task import CompletedTaskAPI
from completed_task_run import CompletedTaskRunAPI
from pybossa.cache.helpers import n_available_tasks, n_available_tasks_for_user
from pybossa.sched import (get_project_scheduler_and_timeout,
                           get_scheduler_and_timeout, has_lock, release_lock,
                           Schedulers, get_locks)
from pybossa.api.project_by_name import ProjectByNameAPI
from pybossa.api.pwd_manager import get_pwd_manager
from pybossa.data_access import data_access_levels

blueprint = Blueprint('api', __name__)

error = ErrorStatus()


@blueprint.route('/')
@ratelimit(limit=ratelimits.get('LIMIT'), per=ratelimits.get('PER'))
def index():  # pragma: no cover
    """Return dummy text for welcome page."""
    return 'The %s API' % current_app.config.get('BRAND')


@blueprint.before_request
def _api_authentication_with_api_key():
    """ Allow API access with valid api_key."""
    secure_app_access = current_app.config.get('SECURE_APP_ACCESS', False)
    if secure_app_access:
        grant_access_with_api_key(secure_app_access)
Пример #2
0
class DiscourseClient(object):
    """Discourse client to interact with the Discourse API.

    :param app: The PyBossa application.
    """

    def __init__(self, app=None):
        self.url = app.config['DISCOURSE_URL']
        self.api_key = app.config['DISCOURSE_API_KEY']
        self.api_username = app.config['DISCOURSE_API_USERNAME']
        self.error_status = ErrorStatus()


    def _request(self, verb, endpoint, params):
        """Make a request."""
        url = '{0}{1}'.format(self.url, endpoint)
        params['api_key'] = self.api_key
        params['api_username'] = self.api_username

        try:
            res = requests.request(verb, url, params=params)
        except requests.RequestException as e:  # pragma: no cover
            return self.error_status.format_exception(e, target=endpoint,
                                                      action=verb).json()

        try:
            return res.json()
        except ValueError as e:  # pragma: no cover
            return self.error_status.format_exception(e, target=endpoint,
                                                      action=verb).json()


    def _get(self, endpoint, params=dict()):
        """Make a GET request."""
        return self._request('GET', endpoint, params)


    def _post(self, endpoint, params=dict()):
        """Make a POST request."""
        return self._request('POST', endpoint, params)


    def _put(self, endpoint, params=dict()):
        """Make a PUT request."""
        return self._request('PUT', endpoint, params)


    def _create_user(self):
        """Create a new Discourse user based on the current users email."""
        endpoint = '/users'
        random_name = str(uuid.uuid4().get_hex().upper()[0:15])
        random_username = str(uuid.uuid4().get_hex().upper()[0:15])
        params = {'name': random_name,
                  'username': random_username,
                  'email': current_user.email_addr,
                  'password': '******',
                  'active': 'true',
                  }
        return self._post(endpoint, params)


    def _get_username(self):
        """Return the current user's Discourse username.

        A new Discourse user will be created first, if necessary.
        """
        if current_user.is_anonymous():
            return None

        def get_username_response():
            endpoint = '/admin/users/list/all.json'
            params = {'filter': current_user.email_addr}
            return self._get(endpoint, params)

        res = get_username_response()
        if len(res) == 0:
            self._create_user()
            res = get_username_response()

        return res[0]['username'] if len(res) == 0 else None


    def categories(self):
        """Return all categories."""
        endpoint = '/categories.json'
        return self._get(endpoint)


    def category(self, category_id):
        """Return all topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}.json'.format(category_id)
        return self._get(endpoint)


    def category_topics_latest(self, category_id):
        """Return the latest topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/l/latest.json'.format(category_id)
        return self._get(endpoint)


    def category_topics_new(self, category_id):
        """Return the newest topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/l/new.json'.format(category_id)
        return self._get(endpoint)


    def category_topics_top(self, category_id):
        """Return the top topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/l/top.json'.format(category_id)
        return self._get(endpoint)


    def category_topics_subtopics(self, category_id, p_category_id):
        """Return the topics in a sub-category.

        :param p_category_id: The ID of the parent category.
        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/{1}.json'.format(p_category_id, category_id)
        return self._get(endpoint)


    def topic(self, topic_id):
        """Return a specific topic.

        :param topic_id: The ID of the topic.
        """
        endpoint = '/t/{0}.json'.format(topic_id)
        return self._get(endpoint)


    def topics_latest(self):
        """Return the latest topics."""
        endpoint = '/latest.json'
        return self._get(endpoint)


    def topics_top(self):
        """Return the top topics."""
        endpoint = '/top.json'
        return self._get(endpoint)


    def user_details(self):
        """Return the current user's details."""
        username = self._get_username()
        if not username:
            return None

        endpoint = '/users/{0}.json'.format(username)
        return self._get(endpoint)


    def user_activity(self):
        """Return the current user's recent activity.

        :param username: The user's Discourse username.
        """
        username = self._get_username()
        if not username:
            return None

        endpoint = '/user_actions.json'
        params = {'username': username}
        return self._get(endpoint, params)


    def user_messages(self):
        """Return the current user's private messages."""
        username = self._get_username()
        if not username:
            return None

        endpoint = '/topics/private-messages/{0}.json'.format(username)
        return self._get(endpoint)


    def user_notifications(self):
        """Return the current user's notifications."""
        username = self._get_username()
        if not username:
            return None

        endpoint = '/notifications.json'
        params = {'username': username}
        return self._get(endpoint, params)


    def user_unread_notifications_count(self):
        """Return a count of unread notifications for the current user."""
        username = self._get_username()
        if not username:
            return None

        notifications = self.user_notifications()
        count = sum([1 for n in notifications['notifications']
                     if not n['read']])
        return count


    def user_signout(self):
        """Sign out the current user from Discourse."""
        details = self.user_details()
        if not details:
            return None

        user_id = details['user']['id']
        endpoint = '/admin/users/{0}/log_out'.format(user_id)
        return self._post(endpoint)


    def badges(self):
        """Return all badges."""
        endpoint = '/admin/badges.json'
        return self._get(endpoint)


    def search(self, query):
        """Perform a search.

        :param query: The search query.
        """
        endpoint = '/search.json'
        params = {'q': query, 'order': 'posts', 'ascending': 'true'}
        return self._get(endpoint, params)
Пример #3
0
class DiscourseClient(object):
    """Discourse class to initialise the Flask-Discourse extension.

    :param app: The PyBossa application.
    """
    def __init__(self, app=None):
        self.url = app.config['DISCOURSE_URL']
        self.api_key = app.config['DISCOURSE_API_KEY']
        self.api_username = app.config['DISCOURSE_API_USERNAME']
        self.error_status = ErrorStatus()

    def _request(self, verb, endpoint, params):
        """Make a request."""
        url = '{0}{1}'.format(self.url, endpoint)
        params['api_key'] = self.api_key
        params['api_username'] = self.api_username

        try:
            res = requests.request(verb, url, params=params)
        except requests.RequestException as e:  # pragma: no cover
            return self.error_status.format_exception(e,
                                                      target=endpoint,
                                                      action=verb)

        if len(res.content.strip()) == 0:  # pragma: no cover
            return None

        try:
            decoded = res.json()
        except ValueError as e:  # pragma: no cover
            return self.error_status.format_exception(e,
                                                      target=endpoint,
                                                      action=verb)

        return decoded

    def _get(self, endpoint, params=dict()):
        """Make a GET request."""
        return self._request('GET', endpoint, params)

    def _post(self, endpoint, params=dict()):
        """Make a POST request."""
        return self._request('POST', endpoint, params)

    def _put(self, endpoint, params=dict()):
        """Make a PUT request."""
        return self._request('PUT', endpoint, params)

    def _create_user(self):
        """Create a new Discourse user based on the current users email."""
        endpoint = '/users'
        random_name = str(uuid.uuid4().get_hex().upper()[0:15])
        random_username = str(uuid.uuid4().get_hex().upper()[0:15])
        params = {
            'name': random_name,
            'username': random_username,
            'email': current_user.email_addr,
            'password': '******',
            'active': 'true',
        }
        return self._post(endpoint, params)

    def _get_username(self):
        """Return the current user's Discourse username.

        A new Discourse user will be created first, if necessary.
        """
        if current_user.is_anonymous():
            return None

        def get_username_response():
            endpoint = '/admin/users/list/all.json'
            params = {'filter': current_user.email_addr}
            return self._get(endpoint, params)

        res = get_username_response()
        if len(res) == 0:
            self._create_user()
            res = get_username_response()

        return res[0]['username']

    def categories(self):
        """Return all categories."""
        endpoint = '/categories.json'
        return self._get(endpoint)

    def category(self, category_id):
        """Return all topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}.json'.format(category_id)
        return self._get(endpoint)

    def category_topics_latest(self, category_id):
        """Return the latest topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/l/latest.json'.format(category_id)
        return self._get(endpoint)

    def category_topics_new(self, category_id):
        """Return the newest topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/l/new.json'.format(category_id)
        return self._get(endpoint)

    def category_topics_top(self, category_id):
        """Return the top topics in a category.

        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/l/top.json'.format(category_id)
        return self._get(endpoint)

    def category_topics_subtopics(self, category_id, p_category_id):
        """Return the topics in a sub-category.

        :param p_category_id: The ID of the parent category.
        :param category_id: The ID of the category.
        """
        endpoint = '/c/{0}/{1}.json'.format(p_category_id, category_id)
        return self._get(endpoint)

    def topic(self, topic_id):
        """Return a specific topic.

        :param topic_id: The ID of the topic.
        """
        endpoint = '/t/{0}.json'.format(topic_id)
        return self._get(endpoint)

    def topics_latest(self):
        """Return the latest topics."""
        endpoint = '/latest.json'
        return self._get(endpoint)

    def topics_top(self):
        """Return the top topics."""
        endpoint = '/top.json'
        return self._get(endpoint)

    def user_details(self):
        """Return the current user's details."""
        username = self._get_username()
        if not username:
            return None

        endpoint = '/users/{0}.json'.format(username)
        return self._get(endpoint)

    def user_activity(self):
        """Return the current user's recent activity.

        :param username: The user's Discourse username.
        """
        username = self._get_username()
        if not username:
            return None

        endpoint = '/user_actions.json'
        params = {'username': username}
        return self._get(endpoint, params)

    def user_messages(self):
        """Return the current user's private messages."""
        username = self._get_username()
        if not username:
            return None

        endpoint = '/topics/private-messages/{0}.json'.format(username)
        return self._get(endpoint)

    def user_notifications(self):
        """Return the current user's notifications."""
        username = self._get_username()
        if not username:
            return None

        endpoint = '/notifications.json'
        params = {'username': username}
        return self._get(endpoint, params)

    def user_unread_notifications_count(self):
        """Return a count of unread notifications for the current user."""
        username = self._get_username()
        if not username:
            return None

        notifications = self.user_notifications()
        count = sum(
            [1 for n in notifications['notifications'] if not n['read']])
        return count

    def user_signout(self):
        """Sign out the current user from Discourse."""
        details = self.user_details()
        if not details:
            return None

        user_id = details['user']['id']
        endpoint = '/admin/users/{0}/log_out'.format(user_id)
        return self._post(endpoint)

    def badges(self):
        """Return all badges."""
        endpoint = '/admin/badges.json'
        return self._get(endpoint)

    def search(self, query):
        """Perform a search.

        :param query: The search query.
        """
        endpoint = '/search.json'
        params = {'q': query, 'order': 'posts', 'ascending': 'true'}
        return self._get(endpoint, params)
Пример #4
0
 def __init__(self, app=None):
     self.url = app.config['DISCOURSE_URL']
     self.api_key = app.config['DISCOURSE_API_KEY']
     self.api_username = app.config['DISCOURSE_API_USERNAME']
     self.error_status = ErrorStatus()
Пример #5
0
 def __init__(self, app=None):
     self.url = app.config['DISCOURSE_URL']
     self.api_key = app.config['DISCOURSE_API_KEY']
     self.api_username = app.config['DISCOURSE_API_USERNAME']
     self.error_status = ErrorStatus()