# -*- coding: utf-8 -*- """ (c) 2015 - Copyright Red Hat Inc Authors: Pierre-Yves Chibon """ import flask from sqlalchemy.exc import SQLAlchemyError import pagure import pagure.exceptions import pagure.lib from pagure import SESSION, APP from pagure.api import API, api_method, APIERROR, api_login_required @API.route('//git/tags') @API.route('///git/tags') @API.route('/fork///git/tags') @API.route('/fork////git/tags') @api_method def api_git_tags(repo, username=None, namespace=None): """ Project git tags ---------------- List the tags made on the project Git repository. :: GET /api/0//git/tags GET /api/0///git/tags :: GET /api/0/fork///git/tags GET /api/0/fork////git/tags Sample response ^^^^^^^^^^^^^^^ :: { "total_tags": 2, "tags": ["0.0.1", "0.0.2"] } """ repo = pagure.lib.get_project( SESSION, repo, user=username, namespace=namespace) if repo is None: raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOPROJECT) tags = pagure.lib.git.get_git_tags(repo) jsonout = flask.jsonify({ 'total_tags': len(tags), 'tags': tags }) return jsonout @API.route('/projects') @api_method def api_projects(): """ List projects -------------- Search projects given the specified criterias. :: GET /api/0/projects :: GET /api/0/projects?tags=fedora-infra Parameters ^^^^^^^^^^ +---------------+----------+---------------+--------------------------+ | Key | Type | Optionality | Description | +===============+==========+===============+==========================+ | ``tags`` | string | Optional | | Filters the projects | | | | | returned by their tags | +---------------+----------+---------------+--------------------------+ | ``pattern`` | string | Optional | | Filters the projects | | | | | by the pattern string | +---------------+----------+---------------+--------------------------+ | ``username`` | string | Optional | | Filters the projects | | | | | returned by the users | | | | | having commit rights | | | | | to it | +---------------+----------+---------------+--------------------------+ | ``fork`` | boolean | Optional | | Filters the projects | | | | | returned depending if | | | | | they are forks or not | +---------------+----------+---------------+--------------------------+ Sample response ^^^^^^^^^^^^^^^ :: { "total_projects": 2, "projects": [ { "date_created": "1427441537", "description": "A web-based calendar for Fedora", "id": 7, "name": "fedocal", "parent": null, "user": { "fullname": "Pierre-Yves C", "name": "pingou" } }, { "date_created": "1431666007", "description": "An awesome messaging servicefor everyone", "id": 12, "name": "fedmsg", "parent": { "date_created": "1433423298", "description": "An awesome messaging servicefor everyone", "id": 11, "name": "fedmsg", "parent": null, "user": { "fullname": "Ralph B", "name": "ralph" } }, "user": { "fullname": "Pierre-Yves C", "name": "pingou" } } ] } """ tags = flask.request.values.getlist('tags') username = flask.request.values.get('username', None) fork = flask.request.values.get('fork', None) pattern = flask.request.values.get('pattern', None) if str(fork).lower() in ['1', 'true']: fork = True elif str(fork).lower() in ['0', 'false']: fork = False projects = pagure.lib.search_projects( SESSION, username=username, fork=fork, tags=tags, pattern=pattern) if not projects: raise pagure.exceptions.APIError( 404, error_code=APIERROR.ENOPROJECTS) jsonout = flask.jsonify({ 'total_projects': len(projects), 'projects': [p.to_json(api=True, public=True) for p in projects] }) return jsonout @API.route('/new/', methods=['POST']) @API.route('/new', methods=['POST']) @api_login_required(acls=['create_project']) @api_method def api_new_project(): """ Create a new project -------------------- Create a new project on this pagure instance. :: POST /api/0//new Input ^^^^^ +------------------+---------+--------------+---------------------------+ | Key | Type | Optionality | Description | +==================+=========+==============+===========================+ | ``name`` | string | Mandatory | | The name of the new | | | | | project. | +------------------+---------+--------------+---------------------------+ | ``description`` | string | Mandatory | | A short description of | | | | | the new project. | +------------------+---------+--------------+---------------------------+ | ``namespace`` | string | Optional | | The namespace of the | | | | | project to fork. | +------------------+---------+--------------+---------------------------+ | ``url`` | string | Optional | | An url providing more | | | | | information about the | | | | | project. | +------------------+---------+--------------+---------------------------+ | ``avatar_email`` | string | Optional | | An email address for the| | | | | avatar of the project. | +------------------+---------+--------------+---------------------------+ | ``create_readme``| boolean | Optional | | A boolean to specify if | | | | | there should be a readme| | | | | added to the project on | | | | | creation. | +------------------+---------+--------------+---------------------------+ Sample response ^^^^^^^^^^^^^^^ :: { 'message': 'Project "foo" created' } """ user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username) output = {} if not pagure.APP.config.get('ENABLE_NEW_PROJECTS', True): raise pagure.exceptions.APIError( 404, error_code=APIERROR.ENEWPROJECTDISABLED) namespaces = APP.config['ALLOWED_PREFIX'][:] if user: namespaces.extend([grp for grp in user.groups]) form = pagure.forms.ProjectForm( namespaces=namespaces, csrf_enabled=False) if form.validate_on_submit(): name = form.name.data description = form.description.data namespace = form.namespace.data if namespace: namespace = namespace.strip() url = form.url.data avatar_email = form.avatar_email.data create_readme = form.create_readme.data try: message = pagure.lib.new_project( SESSION, name=name, namespace=namespace, description=description, url=url, avatar_email=avatar_email, user=flask.g.fas_user.username, blacklist=APP.config['BLACKLISTED_PROJECTS'], allowed_prefix=APP.config['ALLOWED_PREFIX'], gitfolder=APP.config['GIT_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], add_readme=create_readme, userobj=user, prevent_40_chars=APP.config.get( 'OLD_VIEW_COMMIT_ENABLED', False), ) SESSION.commit() pagure.lib.git.generate_gitolite_acls() output['message'] = message except pagure.exceptions.PagureException as err: raise pagure.exceptions.APIError( 400, error_code=APIERROR.ENOCODE, error=str(err)) except SQLAlchemyError as err: # pragma: no cover APP.logger.exception(err) SESSION.rollback() raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR) else: raise pagure.exceptions.APIError(400, error_code=APIERROR.EINVALIDREQ) jsonout = flask.jsonify(output) return jsonout @API.route('/fork/', methods=['POST']) @API.route('/fork', methods=['POST']) @api_login_required(acls=['fork_project']) @api_method def api_fork_project(): """ Fork a project -------------------- Fork a project on this pagure instance. :: POST /api/0//fork Input ^^^^^ +------------------+---------+--------------+---------------------------+ | Key | Type | Optionality | Description | +==================+=========+==============+===========================+ | ``repo`` | string | Mandatory | | The name of the project | | | | | to fork. | +------------------+---------+--------------+---------------------------+ | ``namespace`` | string | Optional | | The namespace of the | | | | | project to fork. | +------------------+---------+--------------+---------------------------+ | ``username`` | string | Optional | | The username of the user| | | | | of the fork. | +------------------+---------+--------------+---------------------------+ Sample response ^^^^^^^^^^^^^^^ :: { "message": 'Repo "test" cloned to "pingou/test"' } """ output = {} form = pagure.forms.ForkRepoForm(csrf_enabled=False) if form.validate_on_submit(): repo = form.repo.data username = form.username.data or None namespace = form.namespace.data.strip() or None if namespace == 'None': namespace = None repo = pagure.lib.get_project( SESSION, repo, user=username, namespace=namespace) if repo is None: raise pagure.exceptions.APIError( 404, error_code=APIERROR.ENOPROJECT) try: message = pagure.lib.fork_project( SESSION, user=flask.g.fas_user.username, repo=repo, gitfolder=APP.config['GIT_FOLDER'], docfolder=APP.config['DOCS_FOLDER'], ticketfolder=APP.config['TICKETS_FOLDER'], requestfolder=APP.config['REQUESTS_FOLDER'], ) SESSION.commit() pagure.lib.git.generate_gitolite_acls() output['message'] = message except pagure.exceptions.PagureException as err: raise pagure.exceptions.APIError( 400, error_code=APIERROR.ENOCODE, error=str(err)) except SQLAlchemyError as err: # pragma: no cover APP.logger.exception(err) SESSION.rollback() raise pagure.exceptions.APIError( 400, error_code=APIERROR.EDBERROR) else: raise pagure.exceptions.APIError( 400, error_code=APIERROR.EINVALIDREQ) jsonout = flask.jsonify(output) return jsonout