Example #1
0
    def get(self, request, *args, **kwargs):
        '''Process link request as a form post to the project import form'''
        self.request = request
        self.args = args
        self.kwargs = kwargs

        data = self.get_form_data()
        project = (Project.objects.for_admin_user(request.user)
                   .filter(repo=data['repo']).first())
        if project is not None:
            messages.success(
                request, _('The demo project is already imported!'))
        else:
            kwargs = self.get_form_kwargs()
            form = self.form_class(data=data, **kwargs)
            if form.is_valid():
                project = form.save()
                project.save()
                trigger_build(project, basic=True)
                messages.success(
                    request, _('Your demo project is currently being imported'))
            else:
                for (_f, msg) in form.errors.items():
                    log.error(msg)
                messages.error(request,
                               _('There was a problem adding the demo project'))
                return HttpResponseRedirect(reverse('projects_dashboard'))
        return HttpResponseRedirect(reverse('projects_detail',
                                            args=[project.slug]))
Example #2
0
 def handle(self, *args, **options):
     record = options['record']
     force = options['force']
     version = options['version']
     if len(args):
         for slug in args:
             if version and version != "all":
                 log.info("Updating version %s for %s" % (version, slug))
                 for version in Version.objects.filter(project__slug=slug, slug=version):
                     trigger_build(project=version.project, version=version)
             elif version == "all":
                 log.info("Updating all versions for %s" % slug)
                 for version in Version.objects.filter(project__slug=slug,
                                                       active=True,
                                                       uploaded=False):
                     tasks.update_docs(pk=version.project_id,
                                       record=False,
                                       version_pk=version.pk)
             else:
                 p = Project.all_objects.get(slug=slug)
                 log.info("Building %s" % p)
                 trigger_build(project=p, force=force)
     else:
         if version == "all":
             log.info("Updating all versions")
             for version in Version.objects.filter(active=True,
                                                   uploaded=False):
                 tasks.update_docs(pk=version.project_id,
                                   record=record,
                                   force=force,
                                   version_pk=version.pk)
         else:
             log.info("Updating all docs")
             tasks.update_docs_pull(record=record,
                                    force=force)
Example #3
0
def generic_build(request, project_id_or_slug=None):
    try:
        project = Project.objects.get(pk=project_id_or_slug)
    # Allow slugs too
    except (Project.DoesNotExist, ValueError):
        try:
            project = Project.objects.get(slug=project_id_or_slug)
        except (Project.DoesNotExist, ValueError):
            pc_log.error("(Incoming Generic Build) Repo not found:  %s" %
                         (project_id_or_slug))
            return HttpResponseNotFound('Repo not found: %s' %
                                        project_id_or_slug)
    if request.method == 'POST':
        slug = request.POST.get('version_slug', None)
        if slug:
            pc_log.info("(Incoming Generic Build) %s [%s]" %
                        (project.slug, slug))
            _build_version(project, slug)
        else:
            pc_log.info("(Incoming Generic Build) %s [%s]" %
                        (project.slug, LATEST))
            trigger_build(project=project, force=True)
    else:
        return HttpResponse("You must POST to this resource.")
    return redirect('builds_project_list', project.slug)
Example #4
0
def generic_build(request, project_id_or_slug=None):
    try:
        project = Project.objects.get(pk=project_id_or_slug)
    # Allow slugs too
    except (Project.DoesNotExist, ValueError):
        try:
            project = Project.objects.get(slug=project_id_or_slug)
        except (Project.DoesNotExist, ValueError):
            pc_log.error(
                "(Incoming Generic Build) Repo not found:  %s" % (
                    project_id_or_slug))
            return HttpResponseNotFound(
                'Repo not found: %s' % project_id_or_slug)
    if request.method == 'POST':
        slug = request.POST.get('version_slug', None)
        if slug:
            pc_log.info(
                "(Incoming Generic Build) %s [%s]" % (project.slug, slug))
            _build_version(project, slug)
        else:
            pc_log.info(
                "(Incoming Generic Build) %s [%s]" % (project.slug, LATEST))
            trigger_build(project=project, force=True)
    else:
        return HttpResponse("You must POST to this resource.")
    return redirect('builds_project_list', project.slug)
Example #5
0
    def get(self, request, *args, **kwargs):
        '''Process link request as a form post to the project import form'''
        self.request = request
        self.args = args
        self.kwargs = kwargs

        data = self.get_form_data()
        project = (Project.objects.for_admin_user(
            request.user).filter(repo=data['repo']).first())
        if project is not None:
            messages.success(request,
                             _('The demo project is already imported!'))
        else:
            kwargs = self.get_form_kwargs()
            form = self.form_class(data=data, **kwargs)
            if form.is_valid():
                project = form.save()
                project.save()
                trigger_build(project, basic=True)
                messages.success(
                    request,
                    _('Your demo project is currently being imported'))
            else:
                for (_f, msg) in form.errors.items():
                    log.error(msg)
                messages.error(
                    request, _('There was a problem adding the demo project'))
                return HttpResponseRedirect(reverse('projects_dashboard'))
        return HttpResponseRedirect(
            reverse('projects_detail', args=[project.slug]))
Example #6
0
    def save(self, *args, **kwargs):
        # save the project
        project = super(AdvancedProjectForm, self).save(*args, **kwargs)

        # kick off the celery job
        trigger_build(project=project)

        return project
Example #7
0
    def save(self, *args, **kwargs):
        # save the project
        project = super(AdvancedProjectForm, self).save(*args, **kwargs)

        # kick off the celery job
        trigger_build(project=project)

        return project
Example #8
0
    def save(self, *args, **kwargs):
        # save the project
        project = super(ImportProjectForm, self).save(*args, **kwargs)

        if kwargs.get('commit', True):
            # kick off the celery job
            trigger_build(project=project)

        return project
Example #9
0
    def save(self, *args, **kwargs):
        # save the project
        project = super(ImportProjectForm, self).save(*args, **kwargs)

        if kwargs.get('commit', True):
            # kick off the celery job
            trigger_build(project=project)

        return project
Example #10
0
 def save_version(self, version):
     new_value = self.cleaned_data.get('version-%s' % version.slug, None)
     privacy_level = self.cleaned_data.get('privacy-%s' % version.slug,
                                           None)
     if ((new_value is None or new_value == version.active) and
         (privacy_level is None or privacy_level == version.privacy_level)):
         return
     version.active = new_value
     version.privacy_level = privacy_level
     version.save()
     if version.active and not version.built and not version.uploaded:
         trigger_build(project=self.project, version=version)
Example #11
0
 def save_version(self, version):
     new_value = self.cleaned_data.get('version-%s' % version.slug, None)
     privacy_level = self.cleaned_data.get('privacy-%s' % version.slug,
                                           None)
     if ((new_value is None or
          new_value == version.active)
         and (privacy_level is None or
              privacy_level == version.privacy_level)):
         return
     version.active = new_value
     version.privacy_level = privacy_level
     version.save()
     if version.active and not version.built and not version.uploaded:
         trigger_build(project=self.project, version=version)
Example #12
0
    def done(self, form_list, **kwargs):
        '''Save form data as object instance

        Don't save form data directly, instead bypass documentation building and
        other side effects for now, by signalling a save without commit. Then,
        finish by added the members to the project and saving.
        '''
        # expect the first form
        basics_form = form_list[0]
        # Save the basics form to create the project instance, then alter
        # attributes directly from other forms
        project = basics_form.save()
        for form in form_list[1:]:
            for (field, value) in form.cleaned_data.items():
                setattr(project, field, value)
        project.save()
        trigger_build(project)
        return HttpResponseRedirect(
            reverse('projects_detail', args=[project.slug]))
Example #13
0
    def done(self, form_list, **kwargs):
        '''Save form data as object instance

        Don't save form data directly, instead bypass documentation building and
        other side effects for now, by signalling a save without commit. Then,
        finish by added the members to the project and saving.
        '''
        # expect the first form
        basics_form = form_list[0]
        # Save the basics form to create the project instance, then alter
        # attributes directly from other forms
        project = basics_form.save()
        for form in form_list[1:]:
            for (field, value) in form.cleaned_data.items():
                setattr(project, field, value)
        project.save()
        trigger_build(project)
        return HttpResponseRedirect(reverse('projects_detail',
                                            args=[project.slug]))
Example #14
0
def _build_version(project, slug, already_built=()):
    default = project.default_branch or (project.vcs_repo().fallback_branch)
    if slug == default and slug not in already_built:
        # short circuit versions that are default
        # these will build at "latest", and thus won't be
        # active
        latest_version = project.versions.get(slug='latest')
        trigger_build(project=project, version=latest_version, force=True)
        pc_log.info(("(Version build) Building %s:%s"
                     % (project.slug, latest_version.slug)))
        if project.versions.exclude(active=False).filter(slug=slug).exists():
            # Handle the case where we want to build the custom branch too
            slug_version = project.versions.get(slug=slug)
            trigger_build(project=project, version=slug_version, force=True)
            pc_log.info(("(Version build) Building %s:%s"
                         % (project.slug, slug_version.slug)))
        return "latest"
    elif project.versions.exclude(active=True).filter(slug=slug).exists():
        pc_log.info(("(Version build) Not Building %s" % slug))
        return None
    elif slug not in already_built:
        version = project.versions.get(slug=slug)
        trigger_build(project=project, version=version, force=True)
        pc_log.info(("(Version build) Building %s:%s"
                     % (project.slug, version.slug)))
        return slug
    else:
        pc_log.info(("(Version build) Not Building %s" % slug))
        return None
Example #15
0
def github_build(request):
    """
    A post-commit hook for github.
    """
    if request.method == 'POST':
        try:
            # GitHub RTD integration
            obj = json.loads(request.POST['payload'])
        except:
            # Generic post-commit hook
            obj = json.loads(request.body)
        url = obj['repository']['url']
        ghetto_url = url.replace('http://', '').replace('https://', '')
        branch = obj['ref'].replace('refs/heads/', '')
        pc_log.info("(Incoming Github Build) %s [%s]" % (ghetto_url, branch))
        try:
            return _build_url(ghetto_url, [branch])
        except NoProjectException:
            try:
                name = obj['repository']['name']
                desc = obj['repository']['description']
                homepage = obj['repository']['homepage']
                repo = obj['repository']['url']

                email = obj['repository']['owner']['email']
                user = User.objects.get(email=email)

                proj = Project.objects.create(
                    name=name,
                    description=desc,
                    project_url=homepage,
                    repo=repo,
                )
                proj.users.add(user)
                # Version doesn't exist yet, so use classic build method
                trigger_build(project=proj)
                pc_log.info("Created new project %s" % (proj))
            except Exception, e:
                pc_log.error("Error creating new project %s: %s" % (name, e))
                return HttpResponseNotFound('Repo not found')
Example #16
0
def _build_version(project, slug, already_built=()):
    default = project.default_branch or (project.vcs_repo().fallback_branch)
    if slug == default and slug not in already_built:
        # short circuit versions that are default
        # these will build at "latest", and thus won't be
        # active
        latest_version = project.versions.get(slug=LATEST)
        trigger_build(project=project, version=latest_version, force=True)
        pc_log.info(("(Version build) Building %s:%s" %
                     (project.slug, latest_version.slug)))
        if project.versions.exclude(active=False).filter(slug=slug).exists():
            # Handle the case where we want to build the custom branch too
            slug_version = project.versions.get(slug=slug)
            trigger_build(project=project, version=slug_version, force=True)
            pc_log.info(("(Version build) Building %s:%s" %
                         (project.slug, slug_version.slug)))
        return LATEST
    elif project.versions.exclude(active=True).filter(slug=slug).exists():
        pc_log.info(("(Version build) Not Building %s" % slug))
        return None
    elif slug not in already_built:
        version = project.versions.get(slug=slug)
        trigger_build(project=project, version=version, force=True)
        pc_log.info(
            ("(Version build) Building %s:%s" % (project.slug, version.slug)))
        return slug
    else:
        pc_log.info(("(Version build) Not Building %s" % slug))
        return None
Example #17
0
 def handle(self, *args, **options):
     make_pdf = options['pdf']
     record = options['record']
     force = options['force']
     version = options['version']
     if len(args):
         for slug in args:
             if version and version != "all":
                 log.info("Updating version %s for %s" % (version, slug))
                 for version in Version.objects.filter(project__slug=slug,
                                                       slug=version):
                     trigger_build(project=version.project, version=version)
             elif version == "all":
                 log.info("Updating all versions for %s" % slug)
                 for version in Version.objects.filter(project__slug=slug,
                                                       active=True,
                                                       uploaded=False):
                     tasks.update_docs(pk=version.project_id,
                                       pdf=make_pdf,
                                       record=False,
                                       version_pk=version.pk)
             else:
                 p = Project.objects.get(slug=slug)
                 log.info("Building %s" % p)
                 trigger_build(project=p, force=force)
     else:
         if version == "all":
             log.info("Updating all versions")
             for version in Version.objects.filter(active=True,
                                                   uploaded=False):
                 tasks.update_docs(pk=version.project_id,
                                   pdf=make_pdf,
                                   record=record,
                                   force=force,
                                   version_pk=version.pk)
         else:
             log.info("Updating all docs")
             tasks.update_docs_pull(pdf=make_pdf,
                                    record=record,
                                    force=force)
Example #18
0
def github_build(request):
    """
    A post-commit hook for github.
    """
    if request.method == 'POST':
        try:
            # GitHub RTD integration
            obj = json.loads(request.POST['payload'])
        except:
            # Generic post-commit hook
            obj = json.loads(request.body)
        url = obj['repository']['url']
        ghetto_url = url.replace('http://', '').replace('https://', '')
        branch = obj['ref'].replace('refs/heads/', '')
        pc_log.info("(Incoming Github Build) %s [%s]" % (ghetto_url, branch))
        try:
            return _build_url(ghetto_url, [branch])
        except NoProjectException:
            try:
                name = obj['repository']['name']
                desc = obj['repository']['description']
                homepage = obj['repository']['homepage']
                repo = obj['repository']['url']

                email = obj['repository']['owner']['email']
                user = User.objects.get(email=email)

                proj = Project.objects.create(
                    name=name,
                    description=desc,
                    project_url=homepage,
                    repo=repo,
                )
                proj.users.add(user)
                # Version doesn't exist yet, so use classic build method
                trigger_build(project=proj)
                pc_log.info("Created new project %s" % (proj))
            except Exception, e:
                pc_log.error("Error creating new project %s: %s" % (name, e))
                return HttpResponseNotFound('Repo not found')
Example #19
0
 def build_version(self, request, **kwargs):
     project = get_object_or_404(Project, slug=kwargs['project_slug'])
     version = kwargs.get('version_slug', LATEST)
     version_obj = project.versions.get(slug=version)
     trigger_build(project=project, version=version_obj)
     return self.create_response(request, {'building': True})
Example #20
0
 def save(self, commit=True):
     '''Trigger build on commit save'''
     project = super(ProjectTriggerBuildMixin, self).save(commit)
     if commit:
         trigger_build(project=project)
     return project
Example #21
0
 def save(self, *args, **kwargs):
     obj = super(VersionForm, self).save(*args, **kwargs)
     if obj.active and not obj.built and not obj.uploaded:
         trigger_build(project=obj.project, version=obj)
Example #22
0
 def save(self, *args, **kwargs):
     obj = super(VersionForm, self).save(*args, **kwargs)
     if obj.active and not obj.built and not obj.uploaded:
         trigger_build(project=obj.project, version=obj)
Example #23
0
 def build_version(self, request, **kwargs):
     project = get_object_or_404(Project, slug=kwargs['project_slug'])
     version = kwargs.get('version_slug', LATEST)
     version_obj = project.versions.get(slug=version)
     trigger_build(project=project, version=version_obj)
     return self.create_response(request, {'building': True})
Example #24
0
 def save(self, commit=True):
     '''Trigger build on commit save'''
     project = super(ProjectTriggerBuildMixin, self).save(commit)
     if commit:
         trigger_build(project=project)
     return project
Example #25
0
class ProjectViewSet(viewsets.ModelViewSet):
    permission_classes = [APIPermission]
    renderer_classes = (JSONRenderer, JSONPRenderer, BrowsableAPIRenderer)
    serializer_class = ProjectSerializer
    filter_class = ProjectFilter
    model = Project
    paginate_by = 100
    paginate_by_param = 'page_size'
    max_paginate_by = 1000

    def get_queryset(self):
        return self.model.objects.api(self.request.user)

    @decorators.detail_route()
    def valid_versions(self, request, **kwargs):
        """
        Maintain state of versions that are wanted.
        """
        project = get_object_or_404(
            Project.objects.api(self.request.user), pk=kwargs['pk'])
        if not project.num_major or not project.num_minor or not project.num_point:
            return Response({'error': 'Project does not support point version control'}, status=status.HTTP_400_BAD_REQUEST)
        version_strings = project.supported_versions()
        # Disable making old versions inactive for now.
        # project.versions.exclude(verbose_name__in=version_strings).update(active=False)
        project.versions.filter(
            verbose_name__in=version_strings).update(active=True)
        return Response({
            'flat': version_strings,
        })

    @detail_route()
    def translations(self, request, pk):
        translations = self.get_object().translations.all()
        return Response({
            'translations': ProjectSerializer(translations, many=True).data
        })

    @detail_route()
    def subprojects(self, request, **kwargs):
        project = get_object_or_404(
            Project.objects.api(self.request.user), pk=kwargs['pk'])
        rels = project.subprojects.all()
        children = [rel.child for rel in rels]
        return Response({
            'subprojects': ProjectSerializer(children, many=True).data
        })

    @decorators.detail_route(permission_classes=[permissions.IsAdminUser])
    def token(self, request, **kwargs):
        project = get_object_or_404(
            Project.objects.api(self.request.user), pk=kwargs['pk'])
        token = oauth_utils.get_token_for_project(project, force_local=True)
        return Response({
            'token': token
        })

    @decorators.detail_route(permission_classes=[permissions.IsAdminUser], methods=['post'])
    def sync_versions(self, request, **kwargs):
        """
        Sync the version data in the repo (on the build server) with what we have in the database.

        Returns the identifiers for the versions that have been deleted.
        """
        project = get_object_or_404(
            Project.objects.api(self.request.user), pk=kwargs['pk'])

        # If the currently highest non-prerelease version is active, then make
        # the new latest version active as well.
        old_highest_version = determine_stable_version(project.versions.all())
        if old_highest_version is not None:
            activate_new_stable = old_highest_version.active
        else:
            activate_new_stable = False

        try:
            # Update All Versions
            data = request.DATA
            added_versions = set()
            if 'tags' in data:
                ret_set = api_utils.sync_versions(
                    project=project, versions=data['tags'], type='tag')
                added_versions.update(ret_set)
            if 'branches' in data:
                ret_set = api_utils.sync_versions(
                    project=project, versions=data['branches'], type='branch')
                added_versions.update(ret_set)
            deleted_versions = api_utils.delete_versions(project, data)
        except Exception, e:
            log.exception("Sync Versions Error: %s" % e.message)
            return Response({'error': e.message}, status=status.HTTP_400_BAD_REQUEST)

        try:
            old_stable = project.get_stable_version()
            promoted_version = project.update_stable_version()
            if promoted_version:
                new_stable = project.get_stable_version()
                log.info(
                    "Triggering new stable build: {project}:{version}".format(
                        project=project.slug,
                        version=new_stable.identifier))
                trigger_build(project=project, version=new_stable)

                # Marking the tag that is considered the new stable version as
                # active and building it if it was just added.
                if (
                        activate_new_stable and
                        promoted_version.slug in added_versions):
                    promoted_version.active = True
                    promoted_version.save()
                    trigger_build(project=project, version=promoted_version)
        except:
            log.exception("Stable Version Failure", exc_info=True)

        return Response({
            'added_versions': added_versions,
            'deleted_versions': deleted_versions,
        })
Example #26
0
class ProjectViewSet(viewsets.ModelViewSet):
    permission_classes = [APIPermission]
    renderer_classes = (JSONRenderer, JSONPRenderer, BrowsableAPIRenderer)
    serializer_class = ProjectSerializer
    filter_class = ProjectFilter
    model = Project
    paginate_by = 100
    paginate_by_param = 'page_size'
    max_paginate_by = 1000

    def get_queryset(self):
        return self.model.objects.api(self.request.user)

    @decorators.link()
    def valid_versions(self, request, **kwargs):
        """
        Maintain state of versions that are wanted.
        """
        project = get_object_or_404(Project.objects.api(self.request.user),
                                    pk=kwargs['pk'])
        if not project.num_major or not project.num_minor or not project.num_point:
            return Response(
                {'error': 'Project does not support point version control'},
                status=status.HTTP_400_BAD_REQUEST)
        version_strings = project.supported_versions(flat=True)
        # Disable making old versions inactive for now.
        # project.versions.exclude(verbose_name__in=version_strings).update(active=False)
        project.versions.filter(verbose_name__in=version_strings).update(
            active=True)
        return Response({
            'flat': version_strings,
        })

    @decorators.link()
    def translations(self, request, **kwargs):
        project = get_object_or_404(Project.objects.api(self.request.user),
                                    pk=kwargs['pk'])
        queryset = project.translations.all()
        return Response(
            {'translations': ProjectSerializer(queryset, many=True).data})

    @decorators.link()
    def subprojects(self, request, **kwargs):
        project = get_object_or_404(Project.objects.api(self.request.user),
                                    pk=kwargs['pk'])
        rels = project.subprojects.all()
        children = [rel.child for rel in rels]
        return Response(
            {'subprojects': ProjectSerializer(children, many=True).data})

    @decorators.link(permission_classes=[permissions.IsAdminUser])
    def token(self, request, **kwargs):
        project = get_object_or_404(Project.objects.api(self.request.user),
                                    pk=kwargs['pk'])
        token = oauth_utils.get_token_for_project(project, force_local=True)
        return Response({'token': token})

    @decorators.action(permission_classes=[permissions.IsAdminUser])
    def sync_versions(self, request, **kwargs):
        """
        Sync the version data in the repo (on the build server) with what we have in the database.

        Returns the identifiers for the versions that have been deleted.
        """
        project = get_object_or_404(Project.objects.api(self.request.user),
                                    pk=kwargs['pk'])
        try:
            # Update All Versions
            data = request.DATA
            added_versions = set()
            if 'tags' in data:
                ret_set = api_utils.sync_versions(project=project,
                                                  versions=data['tags'],
                                                  type='tag')
                added_versions.update(ret_set)
            if 'branches' in data:
                ret_set = api_utils.sync_versions(project=project,
                                                  versions=data['branches'],
                                                  type='branch')
                added_versions.update(ret_set)
            deleted_versions = api_utils.delete_versions(project, data)
        except Exception, e:
            log.exception("Sync Versions Error: %s" % e.message)
            return Response({'error': e.message},
                            status=status.HTTP_400_BAD_REQUEST)

        try:
            # Update Stable Version
            version_strings = project.supported_versions(flat=True)
            if version_strings:
                new_stable_slug = version_strings[-1]
                new_stable = project.versions.get(verbose_name=new_stable_slug)

                # Update stable version
                stable = project.versions.filter(slug='stable')
                if stable.exists():
                    stable_obj = stable[0]
                    if (new_stable.identifier != stable_obj.identifier) and (
                            stable_obj.machine is True):
                        stable_obj.identifier = new_stable.identifier
                        stable_obj.save()
                        log.info(
                            "Triggering new stable build: {project}:{version}".
                            format(project=project.slug,
                                   version=stable_obj.identifier))
                        trigger_build(project=project, version=stable_obj)
                else:
                    log.info(
                        "Creating new stable version: {project}:{version}".
                        format(project=project.slug,
                               version=stable_obj.identifier))
                    version = project.versions.create(
                        slug='stable',
                        verbose_name='stable',
                        machine=True,
                        type=new_stable.type,
                        active=True,
                        identifier=new_stable.identifier)
                    trigger_build(project=project, version=version)

                # Build new tag if enabled
                old_largest_slug = version_strings[-2]
                old_largest = project.versions.get(
                    verbose_name=old_largest_slug)
                if old_largest.active and new_stable_slug in added_versions:
                    new_stable.active = True
                    new_stable.save()
                    trigger_build(project=project, version=new_stable)

        except:
            log.exception("Supported Versions Failure", exc_info=True)

        return Response({
            'added_versions': added_versions,
            'deleted_versions': deleted_versions,
        })
Example #27
0
 def build_version(self, request, **kwargs):
     project = get_object_or_404(Project, slug=kwargs["project_slug"])
     version = kwargs.get("version_slug", "latest")
     version_obj = project.versions.get(slug=version)
     trigger_build(project=project, version=version_obj)
     return self.create_response(request, {"building": True})