def build_history(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: builds = project.builds.order_by('-started')[:10] except (IndexError, BuildResult.DoesNotExist): return json_response({"build": None}) else: out = [] for build in builds: out.append({ 'uuid': build.uuid, 'state': build.state, 'started': str(build.started), 'finished': str(build.finished) if build.finished else None, 'id': build.id, 'pbw': build.pbw_url, 'log': build.build_log_url, 'debug': build.debug_info_url, 'worker_debug': build.worker_debug_info_url, 'size': { 'total': build.total_size, 'binary': build.binary_size, 'worker': build.worker_size, 'resources': build.resource_size } }) return json_response({"builds": out})
def build_history(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: builds = project.builds.order_by('-started')[:10] except (IndexError, BuildResult.DoesNotExist): return json_response({"build": None}) else: out = [] for build in builds: out.append({ 'uuid': build.uuid, 'state': build.state, 'started': str(build.started), 'finished': str(build.finished) if build.finished else None, 'id': build.id, 'pbw': build.pbw_url, 'log': build.build_log_url, 'debug': build.debug_info_url, 'size': { 'total': build.total_size, 'binary': build.binary_size, 'resources': build.resource_size } }) return json_response({"builds": out})
def launch_emulator(request): user_id = request.user.id platform = request.POST['platform'] oauth = request.POST['token'] tz_offset = request.POST['tz_offset'] versions = { 'aplite': '2.9', 'basalt': '3.0', } version = versions[platform] redis_key = 'qemu-user-%s-%s' % (user_id, platform) qemu_instance = redis_client.get(redis_key) if qemu_instance is not None: qemu_instance = json.loads(qemu_instance) try: response = requests.post(qemu_instance['ping_url'], timeout=2, verify=settings.COMPLETION_CERTS) response.raise_for_status() response = response.json() except (requests.RequestException, ValueError) as e: print "couldn't fetch old instance: %s" % e pass else: if response.get('alive', False): return json_response(qemu_instance) else: print "old instance is dead." token = _generate_token() servers = set(settings.QEMU_URLS) while len(servers) > 0: server = random.choice(list(servers)) servers.remove(server) try: result = requests.post(server + 'qemu/launch', data={'token': token, 'platform': platform, 'version': version, 'oauth': oauth, 'tz_offset': tz_offset}, headers={'Authorization': settings.QEMU_LAUNCH_AUTH_HEADER}, timeout=15, verify=settings.COMPLETION_CERTS) result.raise_for_status() response = result.json() url = urlparse.urlsplit(server) response['host'] = url.hostname response['secure'] = (url.scheme == 'https') response['api_port'] = url.port or (443 if url.scheme == 'https' else 80) response['ping_url'] = '%sqemu/%s/ping' % (server, response['uuid']) response['kill_url'] = '%sqemu/%s/kill' % (server, response['uuid']) response['token'] = token redis_client.set(redis_key, json.dumps(response)) return json_response(response) except requests.HTTPError as e: print e.response.text except (requests.RequestException, ValueError) as e: print e pass return json_failure("Unable to create emulator instance.")
def whats_new(request): # Unauthenticated users never have anything new. if not request.user.is_authenticated(): return json_response({'new': []}) try: user_id = request.user.social_auth.get(provider='pebble').uid if user_id in settings.FREE_WATCH_USERS: if not redis_client.exists("no-free-snowy-%s" % user_id): return json_response({'free_snowy': settings.FREE_WATCH_URL, 'new': []}) except: pass return json_response({'new': get_new_things(request.user)})
def save_project_settings(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: with transaction.commit_on_success(): 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_code = int(request.POST['app_version_code']) project.app_version_label = request.POST['app_version_label'] project.app_is_watchface = bool(int(request.POST['app_is_watchface'])) project.app_capabilities = request.POST['app_capabilities'] project.app_keys = request.POST['app_keys'] project.app_jshint = bool(int(request.POST['app_jshint'])) menu_icon = request.POST['menu_icon'] if menu_icon != '': menu_icon = int(menu_icon) old_icon = project.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() project.save() except IntegrityError as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_save_project_settings', project=project, request=request) return json_response({})
def resource_info(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) resources = resource.get_identifiers() send_keen_event('cloudpebble', 'cloudpebble_open_file', data={ 'data': { 'filename': resource.file_name, 'kind': 'resource', 'resource-kind': resource.kind } }, project=project, request=request) return json_response({ 'resource': { 'resource_ids': [{ 'id': x.resource_id, 'regex': x.character_regex, 'tracking': x.tracking } for x in resources], 'id': resource.id, 'file_name': resource.file_name, 'kind': resource.kind } })
def ping_phone(request): user_id = request.user.social_auth.get(provider='pebble').uid device = request.POST['device'] check_token = uuid.uuid4().hex requests.post( '{0}/api/v1/users/{1}/devices/{2}/push'.format( settings.SOCIAL_AUTH_PEBBLE_ROOT_URL, user_id, device), params={ 'admin_token': settings.PEBBLE_AUTH_ADMIN_TOKEN, # 'silent': True, 'message': "Tap to enable developer mode and install apps from CloudPebble.", 'custom': json.dumps({ 'action': 'sdk_connect', 'token': check_token, 'url': '{0}/ide/update_phone'.format(settings.PUBLIC_URL) }) }) return json_response({'token': check_token})
def load_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) try: content = source_file.get_contents() try: folded_lines = json.loads(source_file.folded_lines) except ValueError: folded_lines = [] send_keen_event('cloudpebble', 'cloudpebble_open_file', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) except Exception as e: return json_failure(str(e)) else: return json_response({ "success": True, "source": content, "modified": time.mktime(source_file.last_modified.utctimetuple()), "folded_lines": folded_lines })
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: return json_failure("You cannot delete the last remaining variant of a resource.") try: variant_to_delete.delete() except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_delete_variant', data={ 'data': { 'filename': resource.file_name, 'kind': 'resource', 'resource-kind': resource.kind, 'variant': variant } }, project=project, request=request) return json_response({'resource': { 'variants': [x.get_tags() for x in resource.variants.all()] }})
def save_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) try: if source_file.was_modified_since(int(request.POST['modified'])): send_td_event('cloudpebble_save_abort_unsafe', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, request=request, project=project) raise Exception(_("Could not save: file has been modified since last save.")) source_file.save_file(request.POST['content'], folded_lines=request.POST['folded_lines']) except Exception as e: return json_failure(str(e)) else: send_td_event('cloudpebble_save_file', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, request=request, project=project) return json_response({"modified": time.mktime(source_file.last_modified.utctimetuple())})
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: return HttpResponse(json.dumps({ "success": False, 'error': _("Invalid Github URL.") }), content_type="application/json") github_user = match.group(1) github_project = match.group(2) try: project = Project.objects.create(owner=request.user, name=name) except IntegrityError as e: return json_failure(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 json_response({'task_id': task.task_id, 'project_id': project.id})
def create_project(request): name = request.POST['name'] template_id = request.POST.get('template', None) project_type = request.POST.get('type', 'native') try: with transaction.commit_on_success(): project = Project.objects.create( name=name, owner=request.user, sdk_version=2, app_company_name=request.user.username, app_short_name=name, app_long_name=name, app_version_code=1, app_version_label='1.0', app_is_watchface=False, app_capabilities='', project_type=project_type ) if template_id is not None and int(template_id) != 0: template = TemplateProject.objects.get(pk=int(template_id)) template.copy_into_project(project) elif project_type == 'simplyjs': f = SourceFile.objects.create(project=project, file_name="app.js") f.save_file(open('{}/src/html/demo.js'.format(settings.SIMPLYJS_ROOT)).read()) except IntegrityError as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_create_project', project=project, request=request) return json_response({"id": project.id})
def save_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) try: expected_modification_time = datetime.datetime.fromtimestamp(int(request.POST['modified'])) if source_file.last_modified.replace(tzinfo=None, microsecond=0) > expected_modification_time: send_keen_event('cloudpebble', 'cloudpebble_save_abort_unsafe', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) raise Exception("Could not save: file has been modified since last save.") source_file.save_file(request.POST['content']) except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_save_file', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) return json_response({"modified": time.mktime(source_file.last_modified.utctimetuple())})
def source_file_is_safe(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) client_modified = datetime.datetime.fromtimestamp(int(request.GET['modified'])) server_modified = source_file.last_modified.replace(tzinfo=None, microsecond=0) is_safe = client_modified >= server_modified return json_response({'safe': is_safe})
def generate_phone_token(request, emulator_id): phone_token = random.randint(100000, 999999) token = request.POST['token'] url = request.POST['url'] redis_key = 'qemu-phone-token-%s' % phone_token redis_client.set(redis_key, json.dumps({'uuid': emulator_id, 'token': token, 'url': url}), ex=300) return json_response({'token': phone_token})
def resource_info(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) resources = resource.get_identifiers() send_keen_event('cloudpebble', 'cloudpebble_open_file', data={ 'data': { 'filename': resource.file_name, 'kind': 'resource', 'resource-kind': resource.kind } }, project=project, request=request) return json_response({ 'resource': { "target_platforms": json.loads(resource.target_platforms) if resource.target_platforms else None, 'resource_ids': [{ 'id': x.resource_id, 'regex': x.character_regex, 'tracking': x.tracking, 'compatibility': x.compatibility } for x in resources], 'id': resource.id, 'file_name': resource.file_name, 'kind': resource.kind, "variants": [x.get_tags() for x in resource.variants.all()], "extra": {y.resource_id: {'regex': y.character_regex, 'tracking': y.tracking, 'compatibility': y.compatibility} for y in resource.identifiers.all()} } })
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']) try: with transaction.commit_on_success(): # 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: regex = r['regex'] if 'regex' in r else None tracking = int(r['tracking']) if 'tracking' in r else None resources.append(ResourceIdentifier.objects.create(resource_file=resource, resource_id=r['id'], character_regex=regex, tracking=tracking)) if 'file' in request.FILES: resource.save_file(request.FILES['file'], request.FILES['file'].size) except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_save_file', data={ 'data': { 'filename': resource.file_name, 'kind': 'source' } }, project=project, request=request) return json_response({"file": { "id": resource.id, "kind": resource.kind, "file_name": resource.file_name, "resource_ids": [{'id': x.resource_id, 'regex': x.character_regex} for x in resources], "identifiers": [x.resource_id for x in resources] }})
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']) file_name = request.FILES['file'].name resources = [] try: with transaction.commit_on_success(): rf = ResourceFile.objects.create(project=project, file_name=file_name, kind=kind) for r in resource_ids: regex = r['regex'] if 'regex' in r else None tracking = int(r['tracking']) if 'tracking' in r else None resources.append(ResourceIdentifier.objects.create(resource_file=rf, resource_id=r['id'], character_regex=regex, tracking=tracking)) rf.save_file(request.FILES['file'], request.FILES['file'].size) except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_create_file', data={ 'data': { 'filename': file_name, 'kind': 'resource', 'resource-kind': kind } }, project=project, request=request) return json_response({"file": { "id": rf.id, "kind": rf.kind, "file_name": rf.file_name, "resource_ids": [{'id': x.resource_id, 'regex': x.character_regex} for x in resources], "identifiers": [x.resource_id for x in resources] }})
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 try: if source_file.file_name != request.POST['old_name']: send_keen_event('cloudpebble', 'cloudpebble_rename_abort_unsafe', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) raise Exception(_("Could not rename, file has been renamed already.")) if source_file.was_modified_since(int(request.POST['modified'])): send_keen_event('cloudpebble', 'cloudpebble_rename_abort_unsafe', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) raise Exception(_("Could not rename, file has been modified since last save.")) source_file.file_name = request.POST['new_name'] source_file.save() except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_rename_file', data={ 'data': { 'old_filename': old_filename, 'new_filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) return json_response({"modified": time.mktime(source_file.last_modified.utctimetuple())})
def transition_accept(request): user_settings = request.user.settings user_settings.accepted_terms = True user_settings.save() send_keen_event('cloudpebble', 'cloudpebble_ownership_transition_accepted', request=request) return json_response({})
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']) file_name = request.FILES['file'].name resources = [] try: with transaction.commit_on_success(): rf = ResourceFile.objects.create(project=project, file_name=file_name, kind=kind) for r in resource_ids: regex = r['regex'] if 'regex' in r else None tracking = int(r['tracking']) if 'tracking' in r else None resources.append( ResourceIdentifier.objects.create(resource_file=rf, resource_id=r['id'], character_regex=regex, tracking=tracking)) rf.save_file(request.FILES['file'], request.FILES['file'].size) except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_create_file', data={ 'data': { 'filename': file_name, 'kind': 'resource', 'resource-kind': kind } }, project=project, request=request) return json_response({ "file": { "id": rf.id, "kind": rf.kind, "file_name": rf.file_name, "resource_ids": [{ 'id': x.resource_id, 'regex': x.character_regex } for x in resources], "identifiers": [x.resource_id for x in resources], "extra": { y.resource_id: { 'regex': y.character_regex, 'tracking': y.tracking } for y in rf.identifiers.all() } } })
def last_build(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: build = project.builds.order_by("-started")[0] except (IndexError, BuildResult.DoesNotExist): return json_response({"build": None}) else: b = { "uuid": build.uuid, "state": build.state, "started": str(build.started), "finished": str(build.finished) if build.finished else None, "id": build.id, "pbw": build.pbw_url, "log": build.build_log_url, "size": {"total": build.total_size, "binary": build.binary_size, "resources": build.resource_size}, } return json_response({"build": b})
def last_build(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: build = project.builds.order_by('-started')[0] except (IndexError, BuildResult.DoesNotExist): return json_response({"build": None}) else: b = { 'uuid': build.uuid, 'state': build.state, 'started': str(build.started), 'finished': str(build.finished) if build.finished else None, 'id': build.id, 'pbw': build.pbw_url, 'log': build.build_log_url, 'build_dir': build.get_url(), 'sizes': build.get_sizes(), } return json_response({"build": b})
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: return json_failure(str(e)) task = do_import_archive.delay(project.id, zip_file.read(), delete_project=True) return json_response({'task_id': task.task_id, 'project_id': project.id})
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 = request.POST.get('sdk', 2) try: with transaction.commit_on_success(): 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, ) 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_file( 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_file( open('{}/src/js/app.js'.format( settings.PEBBLEJS_ROOT)).read()) except IntegrityError as e: return json_failure(str(e)) else: send_keen_event( 'cloudpebble', 'cloudpebble_create_project', {'data': { 'template': { 'id': template_id, 'name': template_name } }}, project=project, request=request) return json_response({"id": project.id})
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)): return json_failure("Not confirmed") try: project.delete() except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_delete_project', project=project, request=request) return json_response({})
def build_history(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: builds = project.builds.order_by('-started')[:10] except (IndexError, BuildResult.DoesNotExist): return json_response({"build": None}) else: out = [] for build in builds: out.append({ 'uuid': build.uuid, 'state': build.state, 'started': str(build.started), 'finished': str(build.finished) if build.finished else None, 'id': build.id, 'pbw': build.pbw_url, 'log': build.build_log_url, 'build_dir': build.get_url(), 'sizes': build.get_sizes() }) return json_response({"builds": out})
def login_action(request): username = request.REQUEST['username'] password = request.REQUEST['password'] user = authenticate(username=username, password=password) if user is None: return json_failure(_("Invalid username or password")) if not user.is_active: return json_failure(_("Account disabled.")) login(request, user) return json_response()
def list_phones(request): user_key = request.user.social_auth.get(provider='pebble').extra_data['access_token'] response = requests.get( '{0}/api/v1/me.json'.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: return json_failure(response.reason) else: devices = response.json()['devices'] return json_response({'devices': devices})
def generate_phone_token(request, emulator_id): phone_token = random.randint(100000, 999999) token = request.POST['token'] url = request.POST['url'] redis_key = 'qemu-phone-token-%s' % phone_token redis_client.set(redis_key, json.dumps({ 'uuid': emulator_id, 'token': token, 'url': url }), ex=300) return json_response({'token': phone_token})
def list_phones(request): user_key = request.user.social_auth.get( provider='pebble').extra_data['access_token'] response = requests.get( '{0}/api/v1/me.json'.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: return json_failure(response.reason) else: devices = response.json()['devices'] return json_response({'devices': devices})
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']) try: with transaction.commit_on_success(): # 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: regex = r['regex'] if 'regex' in r else None tracking = int(r['tracking']) if 'tracking' in r else None resources.append( ResourceIdentifier.objects.create(resource_file=resource, resource_id=r['id'], character_regex=regex, tracking=tracking)) if 'file' in request.FILES: resource.save_file(request.FILES['file'], request.FILES['file'].size) except Exception as e: return json_failure(str(e)) else: send_keen_event( 'cloudpebble', 'cloudpebble_save_file', data={'data': { 'filename': resource.file_name, 'kind': 'source' }}, project=project, request=request) return json_response({ "file": { "id": resource.id, "kind": resource.kind, "file_name": resource.file_name, "resource_ids": [{ 'id': x.resource_id, 'regex': x.character_regex } for x in resources], "identifiers": [x.resource_id for x in resources] } })
def list_phones(request): user_key = request.user.social_auth.get(provider="pebble").extra_data["access_token"] response = requests.get( "{0}/api/v1/me.json".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: return json_failure(response.reason) else: devices = response.json()["devices"] return json_response({"devices": devices})
def build_history(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: builds = project.builds.order_by("-started")[:10] except (IndexError, BuildResult.DoesNotExist): return json_response({"build": None}) else: out = [] for build in builds: out.append( { "uuid": build.uuid, "state": build.state, "started": str(build.started), "finished": str(build.finished) if build.finished else None, "id": build.id, "pbw": build.pbw_url, "log": build.build_log_url, "debug": build.debug_info_url, "size": {"total": build.total_size, "binary": build.binary_size, "resources": build.resource_size}, } ) return json_response({"builds": out})
def delete_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) try: source_file.delete() except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_delete_file', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) return json_response({})
def build_log(request, project_id, build_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) build = get_object_or_404(BuildResult, project=project, pk=build_id) try: log = build.read_build_log() except Exception as e: return json_failure(str(e)) send_keen_event('cloudpebble', 'cloudpebble_view_build_log', data={ 'data': { 'build_state': build.state } }, project=project, request=request) return json_response({"log": log})
def project_info(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) source_files = SourceFile.objects.filter(project=project).order_by('file_name') resources = ResourceFile.objects.filter(project=project).order_by('file_name') output = { 'type': project.project_type, 'success': True, 'name': project.name, 'last_modified': str(project.last_modified), 'app_uuid': project.app_uuid or '', 'app_company_name': project.app_company_name, 'app_short_name': project.app_short_name, 'app_long_name': project.app_long_name, 'app_version_label': project.app_version_label, 'app_is_watchface': project.app_is_watchface, 'app_is_hidden': project.app_is_hidden, 'app_is_shown_on_communication': project.app_is_shown_on_communication, 'app_capabilities': project.app_capabilities, 'app_jshint': project.app_jshint, 'sdk_version': project.sdk_version, 'app_platforms': project.app_platforms, 'app_modern_multi_js': project.app_modern_multi_js, 'menu_icon': project.menu_icon.id if project.menu_icon else None, 'source_files': [{ 'name': f.file_name, 'id': f.id, 'target': f.target, 'lastModified': time.mktime(f.last_modified.utctimetuple()) } for f in source_files], 'resources': [{ 'id': x.id, 'file_name': x.file_name, 'kind': x.kind, 'identifiers': [y.resource_id for y in x.identifiers.all()], 'extra': {y.resource_id: y.get_options_dict(with_id=False) for y in x.identifiers.all()}, 'variants': [y.get_tags() for y in x.variants.all()], } for x in resources], 'github': { 'repo': "github.com/%s" % project.github_repo if project.github_repo is not None else None, 'branch': project.github_branch if project.github_branch is not None else None, 'last_sync': str(project.github_last_sync) if project.github_last_sync is not None else None, 'last_commit': project.github_last_commit, 'auto_build': project.github_hook_build, 'auto_pull': project.github_hook_uuid is not None } } return json_response(output)
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']) f.save_file('') except IntegrityError as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_create_file', data={ 'data': { 'filename': request.POST['name'], 'kind': 'source' } }, project=project, request=request) return json_response({"file": {"id": f.id, "name": f.file_name}})
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']) f.save_file(request.POST.get('content', '')) except IntegrityError as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_create_file', data={ 'data': { 'filename': request.POST['name'], 'kind': 'source' } }, project=project, request=request) return json_response({"file": {"id": f.id, "name": f.file_name}})
def _spin_up_server(request): servers = set(settings.YCM_URLS) while len(servers) > 0: server = random.choice(list(servers)) servers.remove(server) try: result = requests.post('%sspinup' % server, json.dumps(request), headers={'Content-Type': 'application/json'}, verify=settings.COMPLETION_CERTS) if result.ok: response = result.json() if response['success']: return json_response({'uuid': response['uuid'], 'server': server}) except (requests.RequestException, ValueError): pass print "Server %s failed; trying another." % server # If we get out of here, something went wrong. return json_failure({'success': False, 'error': 'No servers'})
def build_log(request, project_id, build_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) build = get_object_or_404(BuildResult, project=project, pk=build_id) try: log = build.read_build_log() except Exception as e: return json_failure(str(e)) send_keen_event('cloudpebble', 'cloudpebble_view_build_log', data={'data': { 'build_state': build.state }}, project=project, request=request) return json_response({"log": log})
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: regex = r['regex'] if 'regex' in r else None tracking = int(r['tracking']) if 'tracking' in r else None resources.append(ResourceIdentifier.objects.create(resource_file=rf, resource_id=r['id'], character_regex=regex, tracking=tracking)) 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) target_platforms = json.loads(request.POST.get('target_platforms', None)) rf.target_platforms = None if target_platforms is None else json.dumps(target_platforms) rf.save() except Exception as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_create_file', data={ 'data': { 'filename': file_name, 'kind': 'resource', 'resource-kind': kind } }, project=project, request=request) return json_response({"file": { "id": rf.id, "kind": rf.kind, "file_name": rf.file_name, "target_platforms": json.loads(rf.target_platforms) if rf.target_platforms else None, "resource_ids": [{'id': x.resource_id, 'regex': x.character_regex} 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: {'regex': y.character_regex, 'tracking': y.tracking} for y in rf.identifiers.all()} }})
def _spin_up_server(request): servers = set(settings.YCM_URLS) print request while len(servers) > 0: server = random.choice(list(servers)) servers.remove(server) try: result = requests.post('%sspinup' % server, json.dumps(request), headers={'Content-Type': 'application/json'}, verify=settings.COMPLETION_CERTS) if result.ok: response = result.json() if response['success']: return json_response({'uuid': response['uuid'], 'server': server}) except (requests.RequestException, ValueError): import traceback traceback.print_exc() print "Server %s failed; trying another." % server # If we get out of here, something went wrong. return json_failure({'success': False, 'error': 'No servers'})
def save_project_settings(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) try: with transaction.commit_on_success(): sdk_version = int(request.POST['sdk_version']) project.name = request.POST['name'] project.sdk_version = sdk_version if sdk_version == 1: project.version_def_name = request.POST['version_def_name'] elif sdk_version > 1: 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_code = int( request.POST['app_version_code']) project.app_version_label = request.POST['app_version_label'] project.app_is_watchface = bool( int(request.POST['app_is_watchface'])) project.app_capabilities = request.POST['app_capabilities'] project.app_keys = request.POST['app_keys'] project.app_jshint = bool(int(request.POST['app_jshint'])) menu_icon = request.POST['menu_icon'] if menu_icon != '': menu_icon = int(menu_icon) old_icon = project.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() project.save() except IntegrityError as e: return json_failure(str(e)) else: send_keen_event('cloudpebble', 'cloudpebble_save_project_settings', project=project, request=request) return json_response({})
def resource_info(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) resources = resource.get_identifiers() send_keen_event('cloudpebble', 'cloudpebble_open_file', data={ 'data': { 'filename': resource.file_name, 'kind': 'resource', 'resource-kind': resource.kind } }, project=project, request=request) return json_response({ 'resource': { 'resource_ids': [{ 'id': x.resource_id, 'regex': x.character_regex, 'tracking': x.tracking, 'compatibility': x.compatibility } for x in resources], 'id': resource.id, 'file_name': resource.file_name, 'kind': resource.kind, "variants": [x.variant for x in resource.variants.all()], "extra": { y.resource_id: { 'regex': y.character_regex, 'tracking': y.tracking, 'compatibility': y.compatibility } for y in resource.identifiers.all() } } })
def load_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) try: content = source_file.get_contents() send_keen_event('cloudpebble', 'cloudpebble_open_file', data={ 'data': { 'filename': source_file.file_name, 'kind': 'source' } }, project=project, request=request) except Exception as e: return json_failure(str(e)) else: return json_response({ "success": True, "source": content, "modified": time.mktime(source_file.last_modified.utctimetuple()) })
def create_project_repo(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) repo = request.POST['repo'] description = request.POST['description'] try: repo = ide.git.create_repo(request.user, repo, description) except Exception as e: return json_failure(str(e)) else: project.github_repo = repo.full_name project.github_branch = "master" project.github_last_sync = None project.github_last_commit = None project.save() send_keen_event('cloudpebble', 'cloudpebble_created_github_repo', project=project, request=request, data={'data': { 'repo': project.github_repo }}) return json_response({"repo": repo.html_url})
def do_import_gist(request): task = import_gist.delay(request.user.id, request.POST['gist_id']) return json_response({'task_id': task.task_id})
def begin_export(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) result = create_archive.delay(project.id) return json_response({'task_id': result.task_id})
def project_info(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) source_files = SourceFile.objects.filter( project=project).order_by('file_name') resources = ResourceFile.objects.filter( project=project).order_by('file_name') output = { 'type': project.project_type, 'success': True, 'name': project.name, 'last_modified': str(project.last_modified), 'app_uuid': project.app_uuid or '', 'app_company_name': project.app_company_name, 'app_short_name': project.app_short_name, 'app_long_name': project.app_long_name, 'app_version_code': project.app_version_code, 'app_version_label': project.app_version_label, 'app_is_watchface': project.app_is_watchface, 'app_capabilities': project.app_capabilities, 'app_jshint': project.app_jshint, 'menu_icon': project.menu_icon.id if project.menu_icon else None, 'source_files': [{ 'name': f.file_name, 'id': f.id, 'target': f.target } for f in source_files], 'resources': [{ 'id': x.id, 'file_name': x.file_name, 'kind': x.kind, 'identifiers': [y.resource_id for y in x.identifiers.all()], 'extra': { y.resource_id: { 'regex': y.character_regex, 'tracking': y.tracking, 'compatibility': y.compatibility } for y in x.identifiers.all() } } for x in resources], 'github': { 'repo': "github.com/%s" % project.github_repo if project.github_repo is not None else None, 'branch': project.github_branch if project.github_branch is not None else None, 'last_sync': str(project.github_last_sync) if project.github_last_sync is not None else None, 'last_commit': project.github_last_commit, 'auto_build': project.github_hook_build, 'auto_pull': project.github_hook_uuid is not None } } return json_response(output)
def update_phone(request): data = json.loads(request.body) redis_client.set('phone-ip-{0}'.format(data['token']), request.body, ex=120) return json_response({})
def compile_project(request, project_id): project = get_object_or_404(Project, pk=project_id, owner=request.user) build = BuildResult.objects.create(project=project) task = run_compile.delay(build.id) return json_response({"build_id": build.id, "task_id": task.task_id})