Exemplo n.º 1
0
def import_github(request):
    name = request.POST['name']
    repo = request.POST['repo']
    branch = request.POST['branch']
    add_remote = (request.POST['add_remote'] == 'true')
    match = re.match(
        r'^(?:https?://|git@|git://)?(?:www\.)?github\.com[/:]([\w.-]+)/([\w.-]+?)(?:\.git|/|$)',
        repo)
    if match is None:
        raise BadRequest(_("Invalid Github URL."))

    github_user = match.group(1)
    github_project = match.group(2)

    try:
        project = Project.objects.create(owner=request.user, name=name)
    except IntegrityError as e:
        raise BadRequest(str(e))

    if add_remote:
        project.github_repo = "%s/%s" % (github_user, github_project)
        project.github_branch = branch
        project.save()

    task = do_import_github.delay(project.id,
                                  github_user,
                                  github_project,
                                  branch,
                                  delete_project=True)
    return {'task_id': task.task_id, 'project_id': project.id}
Exemplo n.º 2
0
def rename_source_file(request, project_id, file_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    source_file = get_object_or_404(SourceFile, pk=file_id, project=project)
    old_filename = source_file.file_name

    if source_file.file_name != request.POST['old_name']:
        send_td_event('cloudpebble_rename_abort_unsafe', data={
            'data': {
                'filename': source_file.file_name,
                'kind': 'source'
            }
        }, request=request, project=project)
        raise BadRequest(_("Could not rename, file has been renamed already."))
    if source_file.was_modified_since(int(request.POST['modified'])):
        send_td_event('cloudpebble_rename_abort_unsafe', data={
            'data': {
                'filename': source_file.file_name,
                'kind': 'source',
                'modified': time.mktime(source_file.last_modified.utctimetuple()),
            }
        }, request=request, project=project)
        raise BadRequest(_("Could not rename, file has been modified since last save."))
    source_file.file_name = request.POST['new_name']
    source_file.save()

    send_td_event('cloudpebble_rename_file', data={
        'data': {
            'old_filename': old_filename,
            'new_filename': source_file.file_name,
            'kind': 'source'
        }
    }, request=request, project=project)
    return {"modified": time.mktime(source_file.last_modified.utctimetuple())}
Exemplo n.º 3
0
def delete_variant(request, project_id, resource_id, variant):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    resource = get_object_or_404(ResourceFile, pk=resource_id, project=project)
    if variant == '0':
        variant = ''
    variant_to_delete = resource.variants.get(tags=variant)

    if resource.variants.count() == 1:
        raise BadRequest(
            _("You cannot delete the last remaining variant of a resource."))

    variant_to_delete.delete()

    send_td_event('cloudpebble_delete_variant',
                  data={
                      'data': {
                          'filename': resource.file_name,
                          'kind': 'resource',
                          'resource-kind': resource.kind,
                          'variant': variant
                      }
                  },
                  request=request,
                  project=project)

    return {
        'resource': {
            'variants': [x.get_tags() for x in resource.variants.all()]
        }
    }
Exemplo n.º 4
0
def create_source_file(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    try:
        f = SourceFile.objects.create(project=project,
                                      file_name=request.POST['name'],
                                      target=request.POST.get('target', 'app'))
        f.save_text(request.POST.get('content', ''))

    except IntegrityError as e:
        raise BadRequest(str(e))

    send_td_event('cloudpebble_create_file', data={
        'data': {
            'filename': request.POST['name'],
            'kind': 'source',
            'target': f.target
        }
    }, request=request, project=project)

    return {
        'file': {
            'id': f.id,
            'name': f.file_name,
            'target': f.target,
            'file_path': f.project_path
        }
    }
Exemplo n.º 5
0
def delete_project(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    if not bool(request.POST.get('confirm', False)):
        raise BadRequest(_("Not confirmed"))
    project.delete()
    send_td_event('cloudpebble_delete_project',
                  request=request,
                  project=project)
Exemplo n.º 6
0
def create_project(request):
    name = request.POST['name']
    template_id = request.POST.get('template', None)
    if template_id is not None:
        template_id = int(template_id)
    project_type = request.POST.get('type', 'native')
    template_name = None
    sdk_version = str(request.POST.get('sdk', '2'))
    try:
        with transaction.atomic():
            app_keys = '{}' if sdk_version == '2' else '[]'
            project = Project.objects.create(
                name=name,
                owner=request.user,
                app_company_name=request.user.username,
                app_short_name=name,
                app_long_name=name,
                app_version_label='1.0',
                app_is_watchface=False,
                app_capabilities='',
                project_type=project_type,
                sdk_version=sdk_version,
                app_keys=app_keys)
            if template_id is not None and template_id != 0:
                template = TemplateProject.objects.get(pk=template_id)
                template_name = template.name
                template.copy_into_project(project)
            elif project_type == 'simplyjs':
                f = SourceFile.objects.create(project=project,
                                              file_name="app.js")
                f.save_text(
                    open('{}/src/html/demo.js'.format(
                        settings.SIMPLYJS_ROOT)).read())
            elif project_type == 'pebblejs':
                f = SourceFile.objects.create(project=project,
                                              file_name="app.js")
                f.save_text(
                    open('{}/src/js/app.js'.format(
                        settings.PEBBLEJS_ROOT)).read())
            # TODO: Default file for Rocky?
            project.full_clean()
            project.save()
    except IntegrityError as e:
        raise BadRequest(str(e))
    else:
        send_td_event(
            'cloudpebble_create_project',
            {'data': {
                'template': {
                    'id': template_id,
                    'name': template_name
                }
            }},
            request=request,
            project=project)

        return {"id": project.id}
Exemplo n.º 7
0
def import_zip(request):
    zip_file = request.FILES['archive']
    name = request.POST['name']
    try:
        project = Project.objects.create(owner=request.user, name=name)
    except IntegrityError as e:
        raise BadRequest(str(e))
    task = do_import_archive.delay(project.id, zip_file.read(), delete_project=True)

    return {'task_id': task.task_id, 'project_id': project.id}
Exemplo n.º 8
0
def save_project_dependencies(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    try:
        project.set_dependencies(json.loads(request.POST['dependencies']))
        project.set_interdependencies([int(x) for x in json.loads(request.POST['interdependencies'])])
        return {'dependencies': project.get_dependencies()}
    except (IntegrityError, ValueError) as e:
        raise BadRequest(str(e))
    else:
        send_td_event('cloudpebble_save_project_settings', request=request, project=project)
Exemplo n.º 9
0
def create_resource(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    kind = request.POST['kind']
    resource_ids = json.loads(request.POST['resource_ids'])
    posted_file = request.FILES.get('file', None)
    file_name = request.POST['file_name']
    new_tags = json.loads(request.POST['new_tags'])
    resources = []
    try:
        with transaction.atomic():
            rf = ResourceFile.objects.create(project=project,
                                             file_name=file_name,
                                             kind=kind)
            for r in resource_ids:
                resource_options = decode_resource_id_options(r)
                resources.append(
                    ResourceIdentifier.objects.create(resource_file=rf,
                                                      **resource_options))
            if posted_file is not None:
                variant = ResourceVariant.objects.create(
                    resource_file=rf,
                    tags=",".join(str(int(t)) for t in new_tags))
                variant.save_file(posted_file, posted_file.size)

            rf.save()
    except IntegrityError as e:
        raise BadRequest(e)

    send_td_event('cloudpebble_create_file',
                  data={
                      'data': {
                          'filename': file_name,
                          'kind': 'resource',
                          'resource-kind': kind
                      }
                  },
                  request=request,
                  project=project)

    return {
        "file": {
            "id": rf.id,
            "kind": rf.kind,
            "file_name": rf.file_name,
            "resource_ids":
            [x.get_options_dict(with_id=True) for x in resources],
            "identifiers": [x.resource_id for x in resources],
            "variants": [x.get_tags() for x in rf.variants.all()],
            "extra": {
                y.resource_id: y.get_options_dict(with_id=False)
                for y in rf.identifiers.all()
            }
        }
    }
Exemplo n.º 10
0
def save_published_media(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    try:
        project.set_published_media(json.loads(
            request.POST['published_media']))
    except (IntegrityError, ValueError) as e:
        raise BadRequest(str(e))
    else:
        send_td_event('cloudpebble_save_published_media',
                      request=request,
                      project=project)
        return {'published_media': project.get_published_media()}
Exemplo n.º 11
0
def list_phones(request):
    user_key = request.user.social_auth.get(provider='pebble').extra_data['access_token']

    response = requests.get(
        '{0}/api/v1/me'.format(settings.SOCIAL_AUTH_PEBBLE_ROOT_URL),
        headers={'Authorization': 'Bearer {0}'.format(user_key)},
        params={'client_id': settings.SOCIAL_AUTH_PEBBLE_KEY})

    if response.status_code != 200:
        if 400 <= response.status_code < 500:
            raise BadRequest(response.reason)
        else:
            raise Exception(response.reason)
    else:
        devices = response.json()['devices']
        return {'devices': devices}
Exemplo n.º 12
0
def save_project_settings(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    try:
        with transaction.atomic():

            project.name = request.POST['name']
            project.app_uuid = request.POST['app_uuid']
            project.app_company_name = request.POST['app_company_name']
            project.app_short_name = request.POST['app_short_name']
            project.app_long_name = request.POST['app_long_name']
            project.app_version_label = request.POST['app_version_label']
            project.app_is_watchface = bool(
                int(request.POST['app_is_watchface']))
            project.app_is_hidden = bool(int(request.POST['app_is_hidden']))
            project.app_is_shown_on_communication = bool(
                int(request.POST['app_is_shown_on_communication']))
            project.app_capabilities = request.POST['app_capabilities']
            project.app_keys = request.POST['app_keys']
            project.app_jshint = bool(int(request.POST['app_jshint']))
            project.sdk_version = request.POST['sdk_version']
            project.app_platforms = request.POST['app_platforms']
            project.app_modern_multi_js = bool(
                int(request.POST['app_modern_multi_js']))

            menu_icon = request.POST['menu_icon']
            old_icon = project.menu_icon
            if menu_icon != '':
                menu_icon = int(menu_icon)
                if old_icon is not None:
                    old_icon.is_menu_icon = False
                    old_icon.save()
                icon_resource = project.resources.filter(id=menu_icon)[0]
                icon_resource.is_menu_icon = True
                icon_resource.save()
            elif old_icon is not None:
                old_icon.is_menu_icon = False
                old_icon.save()

            project.save()
    except IntegrityError as e:
        return BadRequest(str(e))
    else:
        send_td_event('cloudpebble_save_project_settings',
                      request=request,
                      project=project)
Exemplo n.º 13
0
def set_project_repo(request, project_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    repo = request.POST['repo']
    branch = request.POST['branch']
    auto_pull = bool(int(request.POST['auto_pull']))
    auto_build = bool(int(request.POST['auto_build']))

    repo = ide.git.url_to_repo(repo)
    if repo is None:
        raise BadRequest(_("Invalid repo URL."))
    repo = '%s/%s' % repo

    g = ide.git.get_github(request.user)
    try:
        g_repo = g.get_repo(repo)
    except UnknownObjectException:
        return {'exists': False, 'access': False, 'updated': False, 'branch_exists': False}

    # TODO: Validate the branch...give user option to create one?

    with transaction.atomic():
        if repo != project.github_repo:
            if project.github_hook_uuid:
                try:
                    remove_hooks(g.get_repo(project.github_repo), project.github_hook_uuid)
                except:
                    pass

            # Just clear the repo if none specified.
            if repo == '':
                project.github_repo = None
                project.github_branch = None
                project.github_last_sync = None
                project.github_last_commit = None
                project.github_hook_uuid = None
                project.save()
                return {'exists': True, 'access': True, 'updated': True, 'branch_exists': True}

            if not ide.git.git_verify_tokens(request.user):
                raise BadRequest(_("No GitHub tokens on file."))

            try:
                has_access = ide.git.check_repo_access(request.user, repo)
            except UnknownObjectException:
                return {'exists': False, 'access': False, 'updated': False, 'branch_exists': False}

            if has_access:
                project.github_repo = repo
                project.github_branch = branch
                project.github_last_sync = None
                project.github_last_commit = None
                project.github_hook_uuid = None
            else:
                return {'exists': True, 'access': True, 'updated': True, 'branch_exists': True}

        if branch != project.github_branch:
            project.github_branch = branch

        if auto_pull and project.github_hook_uuid is None:
            # Generate a new hook UUID
            project.github_hook_uuid = uuid.uuid4().hex
            # Set it up
            g_repo.create_hook('web', {'url': settings.GITHUB_HOOK_TEMPLATE % {'project': project.id, 'key': project.github_hook_uuid}, 'content_type': 'form'}, ['push'], True)
        elif not auto_pull:
            if project.github_hook_uuid is not None:
                try:
                    remove_hooks(g_repo, project.github_hook_uuid)
                except:
                    pass
                project.github_hook_uuid = None

        project.github_hook_build = auto_build

        project.save()

    send_td_event('cloudpebble_project_github_linked', data={
        'data': {
            'repo': project.github_repo,
            'branch': project.github_branch
        }
    }, request=request, project=project)

    return {'exists': True, 'access': True, 'updated': True, 'branch_exists': True}
Exemplo n.º 14
0
def update_resource(request, project_id, resource_id):
    project = get_object_or_404(Project, pk=project_id, owner=request.user)
    resource = get_object_or_404(ResourceFile, pk=resource_id, project=project)
    resource_ids = json.loads(request.POST['resource_ids'])
    file_name = request.POST.get('file_name', None)
    variant_tags = json.loads(request.POST.get('variants', "[]"))
    new_tags = json.loads(request.POST.get('new_tags', "[]"))
    replacement_map = json.loads(request.POST.get('replacements', "[]"))
    replacement_files = request.FILES.getlist('replacement_files[]')
    try:
        with transaction.atomic():
            # Lazy approach: delete all the resource_ids and recreate them.
            # We could do better.
            resources = []
            ResourceIdentifier.objects.filter(resource_file=resource).delete()
            for r in resource_ids:
                resource_options = decode_resource_id_options(r)
                resources.append(
                    ResourceIdentifier.objects.create(resource_file=resource,
                                                      **resource_options))

            # We get sent a list of (tags_before, tags_after) pairs.
            updated_variants = []
            for tag_update in variant_tags:
                tags_before, tags_after = tag_update
                variant = resource.variants.get(tags=tags_before)
                variant.set_tags(tags_after)
                updated_variants.append(variant)

            for variant in updated_variants:
                variant.save()
            if 'file' in request.FILES:
                variant = resource.variants.create(tags=",".join(
                    str(int(t)) for t in new_tags))
                variant.save_file(request.FILES['file'],
                                  request.FILES['file'].size)

            # We may get sent a list of pairs telling us which variant gets which replacement file
            for tags, file_index in replacement_map:
                variant = resource.variants.get(tags=tags)
                replacement = replacement_files[int(file_index)]
                variant.save_file(replacement, replacement.size)

            if file_name and resource.file_name != file_name:
                resource.file_name = file_name

            resource.save()

    except IntegrityError as e:
        raise BadRequest(str(e))

    send_td_event(
        'cloudpebble_save_file',
        data={'data': {
            'filename': resource.file_name,
            'kind': 'source'
        }},
        request=request,
        project=project)

    return {
        "file": {
            "id": resource.id,
            "kind": resource.kind,
            "file_name": resource.file_name,
            "resource_ids":
            [x.get_options_dict(with_id=True) for x in resources],
            "identifiers": [x.resource_id for x in resources],
            "variants": [x.get_tags() for x in resource.variants.all()],
            "extra": {
                y.resource_id: y.get_options_dict(with_id=False)
                for y in resource.identifiers.all()
            }
        }
    }