diff --git a/.gitignore b/.gitignore index 9c17deae..32122baa 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ src/ .env/ .idea/ bower_components +staticfiles diff --git a/Dockerfile b/Dockerfile index ef54ecc7..3b8749b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM python:2.7.11 MAINTAINER Katharine Berry -ENV NPM_CONFIG_LOGLEVEL=info NODE_VERSION=4.2.3 DJANGO_VERSION=1.6 +ENV NPM_CONFIG_LOGLEVEL=info NODE_VERSION=4.2.3 DJANGO_VERSION=1.9.7 # Node stuff. @@ -41,6 +41,11 @@ EXPOSE 8000 # CloudPebble stuff RUN npm install -g bower && echo '{"allow_root": true}' > ~/.bowerrc +ADD package.json /tmp/package.json +RUN cd /tmp && npm install +RUN mkdir -p /opt/npm && cp -a /tmp/node_modules /opt/npm/ +ENV NODE_MODULES_PATH /opt/npm/node_modules + # Grab the toolchain RUN curl -o /tmp/arm-cs-tools.tar https://cloudpebble-vagrant.s3.amazonaws.com/arm-cs-tools-stripped.tar && \ tar -xf /tmp/arm-cs-tools.tar -C / && rm /tmp/arm-cs-tools.tar @@ -55,8 +60,8 @@ RUN mkdir /sdk2 && \ curl -L "https://s3.amazonaws.com/assets.getpebble.com/sdk3/sdk-core/sdk-core-${SDK_TWO_VERSION}.tar.bz2" | \ tar --strip-components=1 -xj -C /sdk2 -ENV SDK_THREE_CHANNEL=beta -ENV SDK_THREE_VERSION=4.0-beta16 +ENV SDK_THREE_CHANNEL=release +ENV SDK_THREE_VERSION=4.0.1 # Install SDK 3 RUN mkdir /sdk3 && \ @@ -70,5 +75,6 @@ WORKDIR /code RUN rm -rf bower_components && cd /tmp && python /code/manage.py bower install && mv bower_components /code/ RUN python manage.py compilemessages +RUN python manage.py collectstatic --noinput CMD ["sh", "docker_start.sh"] diff --git a/Procfile b/Procfile index 6a91e975..201b7b72 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ web: newrelic-admin run-program gunicorn -c gunicorn.py cloudpebble.wsgi -celery: newrelic-admin run-program python manage.py celeryd -E -l info +celery: newrelic-admin run-program celery worker -A cloudpebble -E -l info diff --git a/README.md b/README.md index 961b45e0..6e1cad10 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ appropriate values there. Setting environment variables also works. Note that you won't be able to set up integration with certain Pebble systems (e.g. Pebble SSO). This shouldn't usually matter; whenever these are used, an alternative route is provided and should be invoked in its absence. +In order to run locally with `DEBUG=False` set, add the setting `STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'` +to `cloudpebble/settings_local.py`. + Contributing ------------ diff --git a/app.json b/app.json index f30bf30e..46a7136d 100644 --- a/app.json +++ b/app.json @@ -16,7 +16,7 @@ "required": true }, "BROKER_POOL_LIMIT": "1", - "BUILDPACK_URL": "https://github.com/pebble/cloudpebble-buildpack", + "BUILDPACK_URL": "https://github.com/pebble/cloudpebble-buildpack.git#pipeline", "COMPLETION_CERTS": "/app/completion-certs.crt", "ENABLE_KEEN": "yes", "FROM_EMAIL": "noreply@cloudpebble.net", diff --git a/bin/post_compile b/bin/post_compile index 4edb9bbe..04127e73 100644 --- a/bin/post_compile +++ b/bin/post_compile @@ -35,8 +35,7 @@ rm /tmp/*.tar.* # Make sure the database is up to date. echo "Performing database migration." -python manage.py syncdb --noinput -python manage.py migrate +python manage.py migrate --fake-initial echo "Compiling gettext files" python manage.py compilemessages diff --git a/bootstrap.sh b/bootstrap.sh index fdb4b37c..9979fdaa 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -40,7 +40,6 @@ easy_install requests==2.7.0 # Make sure we have a useful database and our JS dependencies. pushd /vagrant - sudo -u vagrant python manage.py syncdb --noinput sudo -u vagrant python manage.py migrate sudo -u vagrant python manage.py bower install popd @@ -169,7 +168,8 @@ console log script export PATH="$PATH:/home/vagrant/arm-cs-tools/bin:/home/vagrant/sdk2/bin" export DEBUG=yes - exec /usr/bin/python manage.py celery worker --autoreload --loglevel=info --no-color + # The following line is untested after move to Django 1.9 + exec celery worker --autoreload --loglevel=info --no-color end script EOF diff --git a/cloudpebble/__init__.py b/cloudpebble/__init__.py index e69de29b..b64e43e8 100644 --- a/cloudpebble/__init__.py +++ b/cloudpebble/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +# This will make sure the app is always imported when +# Django starts so that shared_task will use this app. +from .celery import app as celery_app diff --git a/cloudpebble/celery.py b/cloudpebble/celery.py new file mode 100644 index 00000000..c3f85a5d --- /dev/null +++ b/cloudpebble/celery.py @@ -0,0 +1,22 @@ +from __future__ import absolute_import + +import os + +from celery import Celery + +# set the default Django settings module for the 'celery' program. +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cloudpebble.settings') + +from django.conf import settings # noqa + +app = Celery('cloudpebble') + +# Using a string here means the worker will not have to +# pickle the object when using Windows. +app.config_from_object('django.conf:settings') +app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) + + +@app.task(bind=True) +def debug_task(self): + print('Request: {0!r}'.format(self.request)) diff --git a/cloudpebble/compressors.py b/cloudpebble/compressors.py new file mode 100644 index 00000000..22e16c0b --- /dev/null +++ b/cloudpebble/compressors.py @@ -0,0 +1,53 @@ +from __future__ import unicode_literals + +import codecs +import tempfile + +from django.contrib.staticfiles.storage import staticfiles_storage + +from pipeline.conf import settings +from pipeline.compressors import SubProcessCompressor +from pipeline.utils import source_map_re, path_depth + + +class ConcatenatingUglifyJSCompressor(SubProcessCompressor): + def compress_js(self, js): + command = [settings.UGLIFYJS_BINARY, settings.UGLIFYJS_ARGUMENTS] + if self.verbose: + command.append(' --verbose') + return self.execute_command(command, js) + + def concatenate_files(self, paths, out_path): + args = [settings.CONCATENATOR_BINARY] + args += [staticfiles_storage.path(p) for p in paths] + args += ['-o', out_path] + args += ['-d', staticfiles_storage.base_location] + self.execute_command(args) + + def compress_js_with_source_map(self, paths): + concatenated_js_file = tempfile.NamedTemporaryFile() + source_map_file = tempfile.NamedTemporaryFile() + try: + self.concatenate_files(paths, concatenated_js_file.name) + args = [settings.UGLIFYJS_BINARY] + args += [concatenated_js_file.name] + args += ["--in-source-map", concatenated_js_file.name + ".map"] + args += ["--source-map", source_map_file.name] + args += ["--source-map-root", staticfiles_storage.base_url] + args += ["--prefix", "%s" % path_depth(staticfiles_storage.base_location)] + args += settings.UGLIFYJS_ARGUMENTS + if self.verbose: + args.append('--verbose') + + js = self.execute_command(args) + + with codecs.open(source_map_file.name, encoding='utf-8') as f: + source_map = f.read() + + # Strip out existing source map comment (it will be re-added with packaging) + js = source_map_re.sub('', js) + + return js, source_map + finally: + concatenated_js_file.close() + source_map_file.close() diff --git a/cloudpebble/settings.py b/cloudpebble/settings.py index 2b616993..b741a215 100644 --- a/cloudpebble/settings.py +++ b/cloudpebble/settings.py @@ -12,27 +12,27 @@ VERBOSE = DEBUG or (_environ.get('VERBOSE', '') != '') TESTING = 'test' in sys.argv TRAVIS = 'TRAVIS' in _environ and os.environ["TRAVIS"] == "true" -TEMPLATE_DEBUG = DEBUG + +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) ADMINS = ( ('Administrator', 'example@example.com'), ) +MANAGERS = ADMINS DEFAULT_FROM_EMAIL = _environ.get('FROM_EMAIL', 'CloudPebble ') SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -MANAGERS = ADMINS - if TRAVIS: DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'travisci', - 'USER': 'postgres', + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'travisci', + 'USER': 'postgres', 'PASSWORD': '', - 'HOST': 'localhost', - 'PORT': '', + 'HOST': 'localhost', + 'PORT': '', } } elif 'DATABASE_URL' not in _environ: @@ -54,18 +54,6 @@ LANGUAGE_COOKIE_NAME = 'cloudpebble_language' -TEMPLATE_CONTEXT_PROCESSORS = ( - "django.contrib.auth.context_processors.auth", - "django.core.context_processors.debug", - "django.core.context_processors.i18n", - "django.core.context_processors.media", - "django.core.context_processors.static", - "django.core.context_processors.tz", - "django.contrib.messages.context_processors.messages", - "social.apps.django_app.context_processors.backends", - "social.apps.django_app.context_processors.login_redirect", -) - # Hosts/domain names that are valid for this site; required if DEBUG is False # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts ALLOWED_HOSTS = ['*'] @@ -120,29 +108,46 @@ # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/var/www/example.com/static/" -STATIC_ROOT = 'staticfiles' +STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # URL prefix for static files. # Example: "http://example.com/static/", "http://static.example.com/" STATIC_URL = '/static/' -PUBLIC_URL = _environ.get('PUBLIC_URL', 'http://localhost:8000/') # This default is completely useless. +PUBLIC_URL = _environ.get('PUBLIC_URL', 'http://localhost:8000/') # This default is completely useless. -# Additional locations of static files -STATICFILES_DIRS = ( - # Put strings here, like "/home/html/static" or "C:/www/django/static". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) +NODE_MODULES_PATH = _environ.get('NODE_MODULES_PATH', os.path.join(os.getcwd(), 'node_modules')) -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', - 'djangobower.finders.BowerFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', -) + +def _node_bin(name): + return os.path.join(NODE_MODULES_PATH, '.bin', name) + + +if DEBUG or TESTING: + # Additional locations of static files + STATICFILES_DIRS = ( + # This is used instead of django-bower's finder, because django-pipeline + # is actually better than django-bower at filtering out unneeded static + # files. + os.path.join(os.path.dirname(__file__), '..', 'bower_components'), + ) + STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + 'pipeline.finders.CachedFileFinder', + 'pipeline.finders.PipelineFinder', + ) + STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage' + +else: + STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + 'djangobower.finders.BowerFinder', + 'pipeline.finders.CachedFileFinder', + 'pipeline.finders.PipelineFinder', + ) + STATICFILES_STORAGE = 'cloudpebble.storage.CompressedManifestPipelineStorage' BOWER_INSTALLED_APPS = ( 'https://github.com/krisk/Fuse.git#2ec2f2c40059e135cabf2b01c8c3f96f808b8809', @@ -161,18 +166,30 @@ # Make this unique, and don't share it with anybody. SECRET_KEY = _environ.get('SECRET_KEY', 'y_!-!-i!_txo$v5j(@c7m4uk^jyg)l4bf*0yqrztmax)l2027j') -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - -if not DEBUG: - STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.CachedStaticFilesStorage' - +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.template.context_processors.request', + 'django.contrib.messages.context_processors.messages', + "social.apps.django_app.context_processors.backends", + "social.apps.django_app.context_processors.login_redirect", + ] + } + } +] MIDDLEWARE_CLASSES = ( + 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', @@ -184,7 +201,7 @@ ) AUTHENTICATION_BACKENDS = ( - 'auth.pebble.PebbleOAuth2', + 'site_auth.pebble.PebbleOAuth2', 'django.contrib.auth.backends.ModelBackend', ) @@ -192,11 +209,11 @@ 'social.pipeline.social_auth.social_details', 'social.pipeline.social_auth.social_uid', 'social.pipeline.social_auth.auth_allowed', - 'auth.pebble.merge_user', # formerly social.pipeline.social_auth.social_user + 'site_auth.pebble.merge_user', # formerly social.pipeline.social_auth.social_user 'social.pipeline.user.get_username', 'social.pipeline.user.create_user', 'social.pipeline.social_auth.associate_user', - 'auth.pebble.clear_old_login', + 'site_auth.pebble.clear_old_login', 'social.pipeline.social_auth.load_extra_data', 'social.pipeline.user.user_details' ) @@ -220,12 +237,6 @@ # Python dotted path to the WSGI application used by Django's runserver. WSGI_APPLICATION = 'cloudpebble.wsgi.application' -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', @@ -234,20 +245,132 @@ 'django.contrib.messages', 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: - #'django.contrib.admin', + # 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', 'social.apps.django_app.default', 'ide', - 'auth', + 'site_auth', + 'pipeline', 'root', 'qr', - 'south', - 'djcelery', 'registration', 'djangobower', ) +# Configuration for django-pipeline, used to concatenate and compress JS and CSS sources and +# output source-maps. +PIPELINE = { + 'OUTPUT_SOURCEMAPS': True, + 'JS_COMPRESSOR': 'cloudpebble.compressors.ConcatenatingUglifyJSCompressor', + 'CSS_COMPRESSOR': 'pipeline.compressors.cleancss.CleanCSSCompressor', + 'CLEANCSS_BINARY': _node_bin('cleancss'), + 'UGLIFYJS_BINARY': _node_bin('uglifyjs'), + 'CONCATENATOR_BINARY': _node_bin('source-map-concat'), + 'DISABLE_WRAPPER': True, + 'VERBOSE': True, + 'STYLESHEETS': { + 'codemirror': { + 'source_filenames': ( + 'CodeMirror/addon/hint/show-hint.css', + 'CodeMirror/addon/dialog/dialog.css', + 'CodeMirror/lib/codemirror.css', + 'CodeMirror/theme/monokai.css', + 'CodeMirror/theme/eclipse.css', + 'CodeMirror/theme/blackboard.css', + 'CodeMirror/theme/solarized.css', + 'CodeMirror/addon/fold/foldgutter.css', + ), + 'output_filename': 'build/codemirror.css' + }, + 'textext': { + 'source_filenames': ( + 'jquery-textext/src/css/textext.core.css', + 'jquery-textext/src/css/textext.plugin.tags.css', + 'jquery-textext/src/css/textext.plugin.autocomplete.css', + 'jquery-textext/src/css/textext.plugin.focus.css', + 'jquery-textext/src/css/textext.plugin.prompt.css', + 'jquery-textext/src/css/textext.plugin.arrow.css', + ), + 'output_filename': 'build/textext.css' + }, + 'ide': { + 'source_filenames': ( + 'ide/css/ide.css', + 'ide/css/ib.css', + 'ide/css/codemirror-default.css', + ), + 'output_filename': 'build/ide.css' + }, + 'base': { + 'source_filenames': ( + 'common/fonts/fonts.css', + 'common/css/progress.css', + 'common/css/common.css', + 'ide/css/base.css', + ), + 'output_filename': 'build/base.css' + } + }, + 'JAVASCRIPT': { + 'ide': { + 'source_filenames': ( + 'ide/js/cloudpebble.js', + 'ide/js/editor.js', + 'ide/js/ib/ib.js', + 'ide/js/ib/registry.js', + 'ide/js/*.js', + 'ide/js/*/*.js', + ), + 'output_filename': 'build/ide.js', + }, + 'lib': { + 'source_filenames': ( + 'react/react.js', + 'react/react-dom.js', + 'classnames/index.js', + 'CodeMirror/lib/codemirror.js', + 'CodeMirror/addon/dialog/dialog.js', + 'CodeMirror/addon/search/searchcursor.js', + 'CodeMirror/addon/search/search.js', + 'CodeMirror/addon/edit/matchbrackets.js', + 'CodeMirror/addon/edit/closebrackets.js', + 'CodeMirror/addon/comment/comment.js', + 'CodeMirror/addon/fold/foldgutter.js', + 'CodeMirror/addon/fold/foldcode.js', + 'CodeMirror/addon/fold/brace-fold.js', + 'CodeMirror/addon/fold/comment-fold.js', + 'CodeMirror/addon/runmode/runmode.js', + 'ide/external/codemirror.hint.js', + 'fuse.js/src/fuse.js', + 'CodeMirror/mode/clike/clike.js', + 'CodeMirror/mode/javascript/javascript.js', + 'CodeMirror/keymap/emacs.js', + 'CodeMirror/keymap/vim.js', + 'ide/external/uuid.js', + 'jshint/dist/jshint.js', + 'html.sortable/dist/html.sortable.min.js', + 'text-encoding/lib/encoding.js', + 'noVNC/include/util.js', + 'jquery-textext/src/js/*.js', + ), + 'output_filename': 'build/textext.js', + }, + 'base': { + 'source_filenames': ( + 'jquery/dist/jquery.min.js', + 'common/js/modal.js', + 'bluebird/js/browser/bluebird.js', + 'underscore/underscore-min.js', + 'backbone/backbone-min.js', + 'common/js/whats_new.js', + 'common/js/ajax.js' + ), + 'output_filename': 'build/base.js', + } + } +} + # This logging config prints: # INFO logs from django # INFO or DEBUG logs from 'ide', depending on whether DEBUG=True @@ -366,9 +489,6 @@ WAF_NODE_PATH = _environ.get('WAF_NODE_PATH', None) -import djcelery -djcelery.setup_loader() - # import local settings try: from settings_local import * diff --git a/cloudpebble/storage.py b/cloudpebble/storage.py new file mode 100644 index 00000000..8be2b884 --- /dev/null +++ b/cloudpebble/storage.py @@ -0,0 +1,8 @@ +from pipeline.storage import PipelineMixin, PipelineStorage +from whitenoise.storage import CompressedManifestStaticFilesStorage, HelpfulExceptionMixin, CompressedStaticFilesMixin + +class CompressedManifestPipelineStorage(PipelineMixin, CompressedManifestStaticFilesStorage): + pass + +class CompressedPipelineStorage(HelpfulExceptionMixin, CompressedStaticFilesMixin, PipelineStorage): + pass diff --git a/cloudpebble/urls.py b/cloudpebble/urls.py index 0539ce6c..e1540aa4 100644 --- a/cloudpebble/urls.py +++ b/cloudpebble/urls.py @@ -1,12 +1,10 @@ -from django.conf.urls import patterns, include, url -from django.conf.urls.static import static -from django.conf import settings +from django.conf.urls import include, url # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() -urlpatterns = patterns('', +urlpatterns = [ # Examples: # url(r'^$', 'cloudpebble.views.home', name='home'), # url(r'^cloudpebble/', include('cloudpebble.foo.urls')), @@ -17,9 +15,9 @@ # Uncomment the next line to enable the admin: #url(r'^admin/', include(admin.site.urls)), url(r'^ide/', include('ide.urls', namespace='ide')), - url(r'^accounts/', include('auth.urls')), # Namespacing this breaks things. + url(r'^accounts/', include('site_auth.urls')), # Namespacing this breaks things. url(r'^qr/', include('qr.urls', namespace='qr')), - url(r'^$', include('root.urls', namespace='root')), + url(r'^', include('root.urls', namespace='root')), url(r'', include('social.apps.django_app.urls', namespace='social')), url(r'^i18n/', include('django.conf.urls.i18n')) -) +] diff --git a/cloudpebble/wsgi.py b/cloudpebble/wsgi.py index 79c44ca2..75e8ea0b 100644 --- a/cloudpebble/wsgi.py +++ b/cloudpebble/wsgi.py @@ -1,33 +1,16 @@ """ WSGI config for cloudpebble project. -This module contains the WSGI application used by Django's development server -and any production WSGI deployments. It should expose a module-level variable -named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover -this application via the ``WSGI_APPLICATION`` setting. - -Usually you will have the standard Django WSGI application here, but it also -might make sense to replace the whole Django WSGI application with a custom one -that later delegates to the Django one. For example, you could introduce WSGI -middleware here, or combine a Django application with an application of another -framework. +It exposes the WSGI callable as a module-level variable named ``application``. +For more information on this file, see +https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ """ -import os -# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks -# if running multiple sites in the same mod_wsgi process. To fix this, use -# mod_wsgi daemon mode with each site in its own daemon process, or use -# os.environ["DJANGO_SETTINGS_MODULE"] = "cloudpebble.settings" -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cloudpebble.settings") +import os -# This application object is used by any WSGI server configured to use this -# file. This includes Django's development server, if the WSGI_APPLICATION -# setting points here. from django.core.wsgi import get_wsgi_application -from dj_static import Cling -application = Cling(get_wsgi_application()) -# Apply WSGI middleware here. -# from helloworld.wsgi import HelloWorldApplication -# application = HelloWorldApplication(application) +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cloudpebble.settings") + +application = get_wsgi_application() diff --git a/docker_start.sh b/docker_start.sh index 4a293d16..01bfa123 100644 --- a/docker_start.sh +++ b/docker_start.sh @@ -3,13 +3,12 @@ sleep 1 if [ ! -z "$RUN_WEB" ]; then # Make sure the database is up to date. echo "Performing database migration." - python manage.py syncdb --noinput - python manage.py migrate + python manage.py migrate --fake-initial python manage.py runserver 0.0.0.0:$PORT elif [ ! -z "$RUN_CELERY" ]; then sleep 2 - C_FORCE_ROOT=true python manage.py celery worker --autoreload --loglevel=info + C_FORCE_ROOT=true celery -A cloudpebble worker --autoreload --loglevel=info else echo "Doing nothing!" exit 1 diff --git a/ide/api/phone.py b/ide/api/phone.py index 61c6b50b..b07c1c84 100644 --- a/ide/api/phone.py +++ b/ide/api/phone.py @@ -1,7 +1,7 @@ import uuid from django.conf import settings from django.contrib.auth.decorators import login_required -from django.utils import simplejson as json, simplejson +import json from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_safe, require_POST from django.utils.translation import ugettext as _ diff --git a/ide/api/ycm.py b/ide/api/ycm.py index f0a17f86..2706fa2a 100644 --- a/ide/api/ycm.py +++ b/ide/api/ycm.py @@ -3,6 +3,8 @@ import random import requests + +from django.utils.translation import ugettext as _ from django.conf import settings from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404 diff --git a/ide/migrations/0001_initial.py b/ide/migrations/0001_initial.py index d5e6ec78..6f07fe99 100644 --- a/ide/migrations/0001_initial.py +++ b/ide/migrations/0001_initial.py @@ -1,191 +1,240 @@ # -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'Project' - db.create_table(u'ide_project', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('owner', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), - ('name', self.gf('django.db.models.fields.CharField')(max_length=50)), - ('last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('version_def_name', self.gf('django.db.models.fields.CharField')(default='APP_RESOURCES', max_length=50)), - )) - db.send_create_signal(u'ide', ['Project']) - - # Adding unique constraint on 'Project', fields ['owner', 'name'] - db.create_unique(u'ide_project', ['owner_id', 'name']) - - # Adding model 'TemplateProject' - db.create_table(u'ide_templateproject', ( - (u'project_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ide.Project'], unique=True, primary_key=True)), - ('template_kind', self.gf('django.db.models.fields.IntegerField')(db_index=True)), - )) - db.send_create_signal(u'ide', ['TemplateProject']) - - # Adding model 'BuildResult' - db.create_table(u'ide_buildresult', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='builds', to=orm['ide.Project'])), - ('uuid', self.gf('django.db.models.fields.CharField')(default='8277f892d4d84a69ba21c3989a02c61c', max_length=32)), - ('state', self.gf('django.db.models.fields.IntegerField')(default=1)), - ('started', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)), - ('finished', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), - )) - db.send_create_signal(u'ide', ['BuildResult']) - - # Adding model 'ResourceFile' - db.create_table(u'ide_resourcefile', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='resources', to=orm['ide.Project'])), - ('file_name', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('kind', self.gf('django.db.models.fields.CharField')(max_length=9)), - )) - db.send_create_signal(u'ide', ['ResourceFile']) - - # Adding unique constraint on 'ResourceFile', fields ['project', 'file_name'] - db.create_unique(u'ide_resourcefile', ['project_id', 'file_name']) - - # Adding model 'ResourceIdentifier' - db.create_table(u'ide_resourceidentifier', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('resource_file', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', to=orm['ide.ResourceFile'])), - ('resource_id', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('character_regex', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)), - )) - db.send_create_signal(u'ide', ['ResourceIdentifier']) - - # Adding unique constraint on 'ResourceIdentifier', fields ['resource_file', 'resource_id'] - db.create_unique(u'ide_resourceidentifier', ['resource_file_id', 'resource_id']) - - # Adding model 'SourceFile' - db.create_table(u'ide_sourcefile', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='source_files', to=orm['ide.Project'])), - ('file_name', self.gf('django.db.models.fields.CharField')(max_length=100)), - )) - db.send_create_signal(u'ide', ['SourceFile']) - - # Adding unique constraint on 'SourceFile', fields ['project', 'file_name'] - db.create_unique(u'ide_sourcefile', ['project_id', 'file_name']) - - - def backwards(self, orm): - # Removing unique constraint on 'SourceFile', fields ['project', 'file_name'] - db.delete_unique(u'ide_sourcefile', ['project_id', 'file_name']) - - # Removing unique constraint on 'ResourceIdentifier', fields ['resource_file', 'resource_id'] - db.delete_unique(u'ide_resourceidentifier', ['resource_file_id', 'resource_id']) - - # Removing unique constraint on 'ResourceFile', fields ['project', 'file_name'] - db.delete_unique(u'ide_resourcefile', ['project_id', 'file_name']) - - # Removing unique constraint on 'Project', fields ['owner', 'name'] - db.delete_unique(u'ide_project', ['owner_id', 'name']) - - # Deleting model 'Project' - db.delete_table(u'ide_project') - - # Deleting model 'TemplateProject' - db.delete_table(u'ide_templateproject') - - # Deleting model 'BuildResult' - db.delete_table(u'ide_buildresult') - - # Deleting model 'ResourceFile' - db.delete_table(u'ide_resourcefile') - - # Deleting model 'ResourceIdentifier' - db.delete_table(u'ide_resourceidentifier') - - # Deleting model 'SourceFile' - db.delete_table(u'ide_sourcefile') - - - models = { - u'auth.group': { - 'Meta': {'object_name': 'Group'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - u'auth.permission': { - 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - u'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - u'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - u'ide.buildresult': { - 'Meta': {'object_name': 'BuildResult'}, - 'finished': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'builds'", 'to': u"orm['ide.Project']"}), - 'started': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), - 'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}), - 'uuid': ('django.db.models.fields.CharField', [], {'default': "'7d2901ebedec4f708e706c6424a71e73'", 'max_length': '32'}) - }, - u'ide.project': { - 'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'Project'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), - 'version_def_name': ('django.db.models.fields.CharField', [], {'default': "'APP_RESOURCES'", 'max_length': '50'}) - }, - u'ide.resourcefile': { - 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'ResourceFile'}, - 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'kind': ('django.db.models.fields.CharField', [], {'max_length': '9'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'resources'", 'to': u"orm['ide.Project']"}) - }, - u'ide.resourceidentifier': { - 'Meta': {'unique_together': "(('resource_file', 'resource_id'),)", 'object_name': 'ResourceIdentifier'}, - 'character_regex': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'resource_file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': u"orm['ide.ResourceFile']"}), - 'resource_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - u'ide.sourcefile': { - 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'SourceFile'}, - 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source_files'", 'to': u"orm['ide.Project']"}) - }, - u'ide.templateproject': { - 'Meta': {'object_name': 'TemplateProject', '_ormbases': [u'ide.Project']}, - u'project_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ide.Project']", 'unique': 'True', 'primary_key': 'True'}), - 'template_kind': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}) - } - } - - complete_apps = ['ide'] \ No newline at end of file +# Generated by Django 1.9.7 on 2016-09-07 00:05 +from __future__ import unicode_literals + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import ide.models.build +import ide.models.dependency +import ide.models.project +import ide.utils +import ide.utils.whatsnew + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0007_alter_validators_add_error_messages'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='BuildResult', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uuid', models.CharField(default=ide.models.build.make_uuid, max_length=36, validators=[django.core.validators.RegexValidator(b'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$', message='Invalid UUID.')])), + ('state', models.IntegerField(choices=[(1, 'Pending'), (2, 'Failed'), (3, 'Succeeded')], default=1)), + ('started', models.DateTimeField(auto_now_add=True, db_index=True)), + ('finished', models.DateTimeField(blank=True, null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='BuildSize', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('platform', models.CharField(max_length=20)), + ('total_size', models.IntegerField(blank=True, null=True)), + ('binary_size', models.IntegerField(blank=True, null=True)), + ('resource_size', models.IntegerField(blank=True, null=True)), + ('worker_size', models.IntegerField(blank=True, null=True)), + ('build', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sizes', to='ide.BuildResult')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Dependency', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('version', models.CharField(max_length=2000, validators=[ide.models.dependency.validate_dependency_version])), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Project', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50)), + ('last_modified', models.DateTimeField(auto_now_add=True)), + ('project_type', models.CharField(choices=[(b'native', 'Pebble C SDK'), (b'simplyjs', 'Simply.js'), (b'pebblejs', 'Pebble.js (beta)'), (b'package', 'Pebble Package'), (b'rocky', 'Rocky.js')], default=b'native', max_length=10)), + ('sdk_version', models.CharField(choices=[(b'2', 'SDK 2 (obsolete)'), (b'3', 'SDK 4 beta')], default=b'2', max_length=6)), + ('app_uuid', models.CharField(blank=True, default=ide.utils.generate_half_uuid, max_length=36, null=True, validators=[django.core.validators.RegexValidator(b'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$', message='Invalid UUID.')])), + ('app_company_name', models.CharField(blank=True, max_length=100, null=True)), + ('app_short_name', models.CharField(blank=True, max_length=100, null=True)), + ('app_long_name', models.CharField(blank=True, max_length=100, null=True)), + ('app_version_label', models.CharField(blank=True, default=b'1.0', max_length=40, null=True, validators=[ide.models.project.version_validator])), + ('app_is_watchface', models.BooleanField(default=False)), + ('app_is_hidden', models.BooleanField(default=False)), + ('app_is_shown_on_communication', models.BooleanField(default=False)), + ('app_capabilities', models.CharField(blank=True, max_length=255, null=True)), + ('app_keys', models.TextField(default=b'{}')), + ('app_jshint', models.BooleanField(default=True)), + ('app_platforms', models.TextField(blank=True, max_length=255, null=True)), + ('app_modern_multi_js', models.BooleanField(default=True)), + ('app_keywords', models.TextField(default=b'[]')), + ('optimisation', models.CharField(choices=[(b'0', b'None'), (b'1', b'Limited'), (b's', b'Prefer smaller'), (b'2', b'Prefer faster'), (b'3', b'Aggressive (faster, bigger)')], default=b's', max_length=1)), + ('github_repo', models.CharField(blank=True, max_length=100, null=True)), + ('github_branch', models.CharField(blank=True, max_length=100, null=True)), + ('github_last_sync', models.DateTimeField(blank=True, null=True)), + ('github_last_commit', models.CharField(blank=True, max_length=40, null=True)), + ('github_hook_uuid', models.CharField(blank=True, max_length=36, null=True)), + ('github_hook_build', models.BooleanField(default=False)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='ResourceFile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file_name', models.CharField(max_length=100, validators=[django.core.validators.RegexValidator(b'^[/a-zA-Z0-9_(). -]+$', message='Invalid filename.')])), + ('kind', models.CharField(choices=[(b'raw', 'Binary blob'), (b'bitmap', 'Bitmap Image'), (b'png', '1-bit PNG'), (b'png-trans', '1-bit PNG with transparency'), (b'font', 'True-Type Font'), (b'pbi', '1-bit Pebble image')], max_length=9)), + ('is_menu_icon', models.BooleanField(default=False)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='ResourceIdentifier', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('resource_id', models.CharField(max_length=100, validators=[django.core.validators.RegexValidator(b'^\\w+$', message='Invalid resource ID.')])), + ('character_regex', models.CharField(blank=True, max_length=100, null=True)), + ('tracking', models.IntegerField(blank=True, null=True)), + ('compatibility', models.CharField(blank=True, max_length=10, null=True)), + ('target_platforms', models.CharField(blank=True, default=None, max_length=100, null=True)), + ('memory_format', models.CharField(blank=True, choices=[(b'Smallest', 'Smallest'), (b'SmallestPalette', 'Smallest Palette'), (b'1Bit', '1-bit'), (b'8Bit', '8-bit'), (b'1BitPalette', '1-bit Palette'), (b'2BitPalette', '2-bit Palette'), (b'4BitPalette', '4-bit Palette')], max_length=15, null=True)), + ('storage_format', models.CharField(blank=True, choices=[(b'pbi', '1 bit Pebble Image'), (b'png', 'PNG')], max_length=3, null=True)), + ('space_optimisation', models.CharField(blank=True, choices=[(b'storage', 'Storage'), (b'memory', 'Memory')], max_length=7, null=True)), + ('resource_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='identifiers', to='ide.ResourceFile')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='ResourceVariant', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tags', models.CommaSeparatedIntegerField(blank=True, max_length=50)), + ('is_legacy', models.BooleanField(default=False)), + ('resource_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='variants', to='ide.ResourceFile')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='SourceFile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('last_modified', models.DateTimeField(auto_now=True, null=True)), + ('folded_lines', models.TextField(default=b'[]')), + ('file_name', models.CharField(max_length=100, validators=[django.core.validators.RegexValidator(b'^[/a-zA-Z0-9_.-]+\\.(c|h|js|json)$', message='Invalid file name.')])), + ('target', models.CharField(choices=[(b'app', 'App'), (b'pkjs', 'PebbleKit JS'), (b'worker', 'Worker'), (b'public', 'Public Header File'), (b'common', 'Shared JS')], default=b'app', max_length=10)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='UserGithub', + fields=[ + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='github', serialize=False, to=settings.AUTH_USER_MODEL)), + ('token', models.CharField(blank=True, max_length=50, null=True)), + ('nonce', models.CharField(blank=True, max_length=36, null=True)), + ('username', models.CharField(blank=True, max_length=50, null=True)), + ('avatar', models.CharField(blank=True, max_length=255, null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='UserSettings', + fields=[ + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), + ('autocomplete', models.IntegerField(choices=[(1, 'As-you-type'), (2, 'When pressing Ctrl-Space'), (3, 'Never')], default=1, verbose_name='Autocompletion')), + ('keybinds', models.CharField(choices=[(b'default', 'Standard'), (b'vim', 'vim-like'), (b'emacs', 'emacs-like')], default=b'default', max_length=20, verbose_name='Keybinds')), + ('theme', models.CharField(choices=[(b'cloudpebble', b'CloudPebble'), (b'monokai', b'Monokai (Sublime Text)'), (b'blackboard', b'Blackboard (TextMate)'), (b'eclipse', b'Eclipse'), (b'solarized light', b'Solarized (light)'), (b'solarized dark', b'Solarized (dark)')], default=b'cloudpebble', max_length=50, verbose_name='Theme')), + ('use_spaces', models.BooleanField(choices=[(True, 'Using spaces'), (False, 'Using tabs')], default=True, verbose_name='Indents')), + ('tab_width', models.PositiveSmallIntegerField(default=2, verbose_name='Tab width')), + ('accepted_terms', models.BooleanField(default=True)), + ('whats_new', models.PositiveIntegerField(default=ide.utils.whatsnew.count_things)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='TemplateProject', + fields=[ + ('project_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='ide.Project')), + ('template_kind', models.IntegerField(choices=[(1, 'Template'), (2, 'SDK Demo')], db_index=True)), + ], + options={ + 'abstract': False, + }, + bases=('ide.project',), + ), + migrations.AddField( + model_name='sourcefile', + name='project', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='source_files', to='ide.Project'), + ), + migrations.AddField( + model_name='resourcefile', + name='project', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resources', to='ide.Project'), + ), + migrations.AddField( + model_name='project', + name='owner', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='project', + name='project_dependencies', + field=models.ManyToManyField(to='ide.Project'), + ), + migrations.AddField( + model_name='dependency', + name='project', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dependencies', to='ide.Project'), + ), + migrations.AddField( + model_name='buildresult', + name='project', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='builds', to='ide.Project'), + ), + migrations.AlterUniqueTogether( + name='sourcefile', + unique_together=set([('project', 'file_name', 'target')]), + ), + migrations.AlterUniqueTogether( + name='resourcevariant', + unique_together=set([('resource_file', 'tags')]), + ), + migrations.AlterUniqueTogether( + name='resourcefile', + unique_together=set([('project', 'file_name')]), + ), + migrations.AlterUniqueTogether( + name='dependency', + unique_together=set([('project', 'name')]), + ), + ] diff --git a/ide/migrations/0046_auto__add_dependency.py b/ide/migrations/0046_auto__add_dependency.py deleted file mode 100644 index 0edc3ccb..00000000 --- a/ide/migrations/0046_auto__add_dependency.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- coding: utf-8 -*- -from south.utils import datetime_utils as datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'Dependency' - db.create_table(u'ide_dependency', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='dependencies', to=orm['ide.Project'])), - ('name', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('version', self.gf('django.db.models.fields.CharField')(max_length=100)), - )) - db.send_create_signal('ide', ['Dependency']) - - # Adding unique constraint on 'Dependency', fields ['project', 'name'] - db.create_unique(u'ide_dependency', ['project_id', 'name']) - - # Adding field 'Project.app_keywords' - db.add_column(u'ide_project', 'app_keywords', - self.gf('django.db.models.fields.TextField')(default='[]'), - keep_default=False) - - - def backwards(self, orm): - # Removing unique constraint on 'Dependency', fields ['project', 'name'] - db.delete_unique(u'ide_dependency', ['project_id', 'name']) - - # Deleting model 'Dependency' - db.delete_table(u'ide_dependency') - - # Deleting field 'Project.app_keywords' - db.delete_column(u'ide_project', 'app_keywords') - - - models = { - u'auth.group': { - 'Meta': {'object_name': 'Group'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - u'auth.permission': { - 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - u'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - u'contenttypes.contenttype': { - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ide.buildresult': { - 'Meta': {'object_name': 'BuildResult'}, - 'finished': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'builds'", 'to': "orm['ide.Project']"}), - 'started': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), - 'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}), - 'uuid': ('django.db.models.fields.CharField', [], {'default': "'91bfe649-bbc6-404d-b9e2-5245b3ab41b9'", 'max_length': '36'}) - }, - 'ide.buildsize': { - 'Meta': {'object_name': 'BuildSize'}, - 'binary_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sizes'", 'to': "orm['ide.BuildResult']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'platform': ('django.db.models.fields.CharField', [], {'max_length': '20'}), - 'resource_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'total_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), - 'worker_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ide.dependency': { - 'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Dependency'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependencies'", 'to': "orm['ide.Project']"}), - 'version': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'ide.project': { - 'Meta': {'object_name': 'Project'}, - 'app_capabilities': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'app_company_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'app_is_hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'app_is_shown_on_communication': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'app_is_watchface': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'app_jshint': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'app_keys': ('django.db.models.fields.TextField', [], {'default': "'{}'"}), - 'app_keywords': ('django.db.models.fields.TextField', [], {'default': "'[]'"}), - 'app_long_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'app_modern_multi_js': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'app_platforms': ('django.db.models.fields.TextField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'app_short_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'app_uuid': ('django.db.models.fields.CharField', [], {'default': "'3d189e75-50d6-4e17-aa07-3ac28c399c3b'", 'max_length': '36', 'null': 'True', 'blank': 'True'}), - 'app_version_label': ('django.db.models.fields.CharField', [], {'default': "'1.0'", 'max_length': '40', 'null': 'True', 'blank': 'True'}), - 'github_branch': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'github_hook_build': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'github_hook_uuid': ('django.db.models.fields.CharField', [], {'max_length': '36', 'null': 'True', 'blank': 'True'}), - 'github_last_commit': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), - 'github_last_sync': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'github_repo': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'optimisation': ('django.db.models.fields.CharField', [], {'default': "'s'", 'max_length': '1'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), - 'project_type': ('django.db.models.fields.CharField', [], {'default': "'native'", 'max_length': '10'}), - 'sdk_version': ('django.db.models.fields.CharField', [], {'default': "'2'", 'max_length': '6'}) - }, - 'ide.resourcefile': { - 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'ResourceFile'}, - 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_menu_icon': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'kind': ('django.db.models.fields.CharField', [], {'max_length': '9'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'resources'", 'to': "orm['ide.Project']"}) - }, - 'ide.resourceidentifier': { - 'Meta': {'object_name': 'ResourceIdentifier'}, - 'character_regex': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), - 'compatibility': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'memory_format': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), - 'resource_file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['ide.ResourceFile']"}), - 'resource_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'space_optimisation': ('django.db.models.fields.CharField', [], {'max_length': '7', 'null': 'True', 'blank': 'True'}), - 'storage_format': ('django.db.models.fields.CharField', [], {'max_length': '3', 'null': 'True', 'blank': 'True'}), - 'target_platforms': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '30', 'null': 'True', 'blank': 'True'}), - 'tracking': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) - }, - 'ide.resourcevariant': { - 'Meta': {'unique_together': "(('resource_file', 'tags'),)", 'object_name': 'ResourceVariant'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_legacy': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'resource_file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variants'", 'to': "orm['ide.ResourceFile']"}), - 'tags': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'max_length': '50', 'blank': 'True'}) - }, - 'ide.sourcefile': { - 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'SourceFile'}, - 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'folded_lines': ('django.db.models.fields.TextField', [], {'default': "'[]'"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), - 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source_files'", 'to': "orm['ide.Project']"}), - 'target': ('django.db.models.fields.CharField', [], {'default': "'app'", 'max_length': '10'}) - }, - 'ide.templateproject': { - 'Meta': {'object_name': 'TemplateProject', '_ormbases': ['ide.Project']}, - u'project_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['ide.Project']", 'unique': 'True', 'primary_key': 'True'}), - 'template_kind': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}) - }, - 'ide.usergithub': { - 'Meta': {'object_name': 'UserGithub'}, - 'avatar': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), - 'nonce': ('django.db.models.fields.CharField', [], {'max_length': '36', 'null': 'True', 'blank': 'True'}), - 'token': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), - 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'github'", 'unique': 'True', 'primary_key': 'True', 'to': u"orm['auth.User']"}), - 'username': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}) - }, - 'ide.usersettings': { - 'Meta': {'object_name': 'UserSettings'}, - 'accepted_terms': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'autocomplete': ('django.db.models.fields.IntegerField', [], {'default': '1'}), - 'keybinds': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '20'}), - 'tab_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '2'}), - 'theme': ('django.db.models.fields.CharField', [], {'default': "'cloudpebble'", 'max_length': '50'}), - 'use_spaces': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}), - 'whats_new': ('django.db.models.fields.PositiveIntegerField', [], {'default': '21'}) - } - } - - complete_apps = ['ide'] \ No newline at end of file diff --git a/ide/models/build.py b/ide/models/build.py index f365212b..fc52ba2f 100644 --- a/ide/models/build.py +++ b/ide/models/build.py @@ -15,6 +15,10 @@ __author__ = 'katharine' +def make_uuid(): + return str(uuid.uuid4()) + + class BuildResult(IdeModel): STATE_WAITING = 1 @@ -37,7 +41,7 @@ class BuildResult(IdeModel): DEBUG_WORKER = 1 project = models.ForeignKey(Project, related_name='builds') - uuid = models.CharField(max_length=36, default=lambda: str(uuid.uuid4()), validators=regexes.validator('uuid', _('Invalid UUID.'))) + uuid = models.CharField(max_length=36, default=make_uuid, validators=regexes.validator('uuid', _('Invalid UUID.'))) state = models.IntegerField(choices=STATE_CHOICES, default=STATE_WAITING) started = models.DateTimeField(auto_now_add=True, db_index=True) finished = models.DateTimeField(blank=True, null=True) diff --git a/ide/south_migrations/0001_initial.py b/ide/south_migrations/0001_initial.py new file mode 100644 index 00000000..d5e6ec78 --- /dev/null +++ b/ide/south_migrations/0001_initial.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Project' + db.create_table(u'ide_project', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('owner', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + ('name', self.gf('django.db.models.fields.CharField')(max_length=50)), + ('last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('version_def_name', self.gf('django.db.models.fields.CharField')(default='APP_RESOURCES', max_length=50)), + )) + db.send_create_signal(u'ide', ['Project']) + + # Adding unique constraint on 'Project', fields ['owner', 'name'] + db.create_unique(u'ide_project', ['owner_id', 'name']) + + # Adding model 'TemplateProject' + db.create_table(u'ide_templateproject', ( + (u'project_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['ide.Project'], unique=True, primary_key=True)), + ('template_kind', self.gf('django.db.models.fields.IntegerField')(db_index=True)), + )) + db.send_create_signal(u'ide', ['TemplateProject']) + + # Adding model 'BuildResult' + db.create_table(u'ide_buildresult', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='builds', to=orm['ide.Project'])), + ('uuid', self.gf('django.db.models.fields.CharField')(default='8277f892d4d84a69ba21c3989a02c61c', max_length=32)), + ('state', self.gf('django.db.models.fields.IntegerField')(default=1)), + ('started', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)), + ('finished', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + )) + db.send_create_signal(u'ide', ['BuildResult']) + + # Adding model 'ResourceFile' + db.create_table(u'ide_resourcefile', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='resources', to=orm['ide.Project'])), + ('file_name', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('kind', self.gf('django.db.models.fields.CharField')(max_length=9)), + )) + db.send_create_signal(u'ide', ['ResourceFile']) + + # Adding unique constraint on 'ResourceFile', fields ['project', 'file_name'] + db.create_unique(u'ide_resourcefile', ['project_id', 'file_name']) + + # Adding model 'ResourceIdentifier' + db.create_table(u'ide_resourceidentifier', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('resource_file', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', to=orm['ide.ResourceFile'])), + ('resource_id', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('character_regex', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True)), + )) + db.send_create_signal(u'ide', ['ResourceIdentifier']) + + # Adding unique constraint on 'ResourceIdentifier', fields ['resource_file', 'resource_id'] + db.create_unique(u'ide_resourceidentifier', ['resource_file_id', 'resource_id']) + + # Adding model 'SourceFile' + db.create_table(u'ide_sourcefile', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='source_files', to=orm['ide.Project'])), + ('file_name', self.gf('django.db.models.fields.CharField')(max_length=100)), + )) + db.send_create_signal(u'ide', ['SourceFile']) + + # Adding unique constraint on 'SourceFile', fields ['project', 'file_name'] + db.create_unique(u'ide_sourcefile', ['project_id', 'file_name']) + + + def backwards(self, orm): + # Removing unique constraint on 'SourceFile', fields ['project', 'file_name'] + db.delete_unique(u'ide_sourcefile', ['project_id', 'file_name']) + + # Removing unique constraint on 'ResourceIdentifier', fields ['resource_file', 'resource_id'] + db.delete_unique(u'ide_resourceidentifier', ['resource_file_id', 'resource_id']) + + # Removing unique constraint on 'ResourceFile', fields ['project', 'file_name'] + db.delete_unique(u'ide_resourcefile', ['project_id', 'file_name']) + + # Removing unique constraint on 'Project', fields ['owner', 'name'] + db.delete_unique(u'ide_project', ['owner_id', 'name']) + + # Deleting model 'Project' + db.delete_table(u'ide_project') + + # Deleting model 'TemplateProject' + db.delete_table(u'ide_templateproject') + + # Deleting model 'BuildResult' + db.delete_table(u'ide_buildresult') + + # Deleting model 'ResourceFile' + db.delete_table(u'ide_resourcefile') + + # Deleting model 'ResourceIdentifier' + db.delete_table(u'ide_resourceidentifier') + + # Deleting model 'SourceFile' + db.delete_table(u'ide_sourcefile') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'ide.buildresult': { + 'Meta': {'object_name': 'BuildResult'}, + 'finished': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'builds'", 'to': u"orm['ide.Project']"}), + 'started': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'uuid': ('django.db.models.fields.CharField', [], {'default': "'7d2901ebedec4f708e706c6424a71e73'", 'max_length': '32'}) + }, + u'ide.project': { + 'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'Project'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}), + 'version_def_name': ('django.db.models.fields.CharField', [], {'default': "'APP_RESOURCES'", 'max_length': '50'}) + }, + u'ide.resourcefile': { + 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'ResourceFile'}, + 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.CharField', [], {'max_length': '9'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'resources'", 'to': u"orm['ide.Project']"}) + }, + u'ide.resourceidentifier': { + 'Meta': {'unique_together': "(('resource_file', 'resource_id'),)", 'object_name': 'ResourceIdentifier'}, + 'character_regex': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'resource_file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': u"orm['ide.ResourceFile']"}), + 'resource_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'ide.sourcefile': { + 'Meta': {'unique_together': "(('project', 'file_name'),)", 'object_name': 'SourceFile'}, + 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source_files'", 'to': u"orm['ide.Project']"}) + }, + u'ide.templateproject': { + 'Meta': {'object_name': 'TemplateProject', '_ormbases': [u'ide.Project']}, + u'project_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['ide.Project']", 'unique': 'True', 'primary_key': 'True'}), + 'template_kind': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}) + } + } + + complete_apps = ['ide'] \ No newline at end of file diff --git a/ide/migrations/0002_auto__add_usersettings.py b/ide/south_migrations/0002_auto__add_usersettings.py similarity index 100% rename from ide/migrations/0002_auto__add_usersettings.py rename to ide/south_migrations/0002_auto__add_usersettings.py diff --git a/ide/migrations/0003_auto__add_field_resourceidentifier_tracking.py b/ide/south_migrations/0003_auto__add_field_resourceidentifier_tracking.py similarity index 100% rename from ide/migrations/0003_auto__add_field_resourceidentifier_tracking.py rename to ide/south_migrations/0003_auto__add_field_resourceidentifier_tracking.py diff --git a/ide/migrations/0004_auto__add_usergithub.py b/ide/south_migrations/0004_auto__add_usergithub.py similarity index 100% rename from ide/migrations/0004_auto__add_usergithub.py rename to ide/south_migrations/0004_auto__add_usergithub.py diff --git a/ide/migrations/0005_auto__add_project_github_fields.py b/ide/south_migrations/0005_auto__add_project_github_fields.py similarity index 100% rename from ide/migrations/0005_auto__add_project_github_fields.py rename to ide/south_migrations/0005_auto__add_project_github_fields.py diff --git a/ide/migrations/0006_auto__add_field_project_github_hook.py b/ide/south_migrations/0006_auto__add_field_project_github_hook.py similarity index 100% rename from ide/migrations/0006_auto__add_field_project_github_hook.py rename to ide/south_migrations/0006_auto__add_field_project_github_hook.py diff --git a/ide/migrations/0007_auto__add_field_project_optimisation.py b/ide/south_migrations/0007_auto__add_field_project_optimisation.py similarity index 100% rename from ide/migrations/0007_auto__add_field_project_optimisation.py rename to ide/south_migrations/0007_auto__add_field_project_optimisation.py diff --git a/ide/migrations/0008_auto__add_field_buildresult_sizes.py b/ide/south_migrations/0008_auto__add_field_buildresult_sizes.py similarity index 100% rename from ide/migrations/0008_auto__add_field_buildresult_sizes.py rename to ide/south_migrations/0008_auto__add_field_buildresult_sizes.py diff --git a/ide/migrations/0009_auto__add_field_project_sdk_version__add_field_project_app_uuid__add_f.py b/ide/south_migrations/0009_auto__add_field_project_sdk_version__add_field_project_app_uuid__add_f.py similarity index 100% rename from ide/migrations/0009_auto__add_field_project_sdk_version__add_field_project_app_uuid__add_f.py rename to ide/south_migrations/0009_auto__add_field_project_sdk_version__add_field_project_app_uuid__add_f.py diff --git a/ide/migrations/0010_auto__add_field_project_app_keys.py b/ide/south_migrations/0010_auto__add_field_project_app_keys.py similarity index 100% rename from ide/migrations/0010_auto__add_field_project_app_keys.py rename to ide/south_migrations/0010_auto__add_field_project_app_keys.py diff --git a/ide/migrations/0011_auto__add_field_resourcefile_is_menu_icon.py b/ide/south_migrations/0011_auto__add_field_resourcefile_is_menu_icon.py similarity index 100% rename from ide/migrations/0011_auto__add_field_resourcefile_is_menu_icon.py rename to ide/south_migrations/0011_auto__add_field_resourcefile_is_menu_icon.py diff --git a/ide/migrations/0012_auto__add_field_usersettings_accepted_terms.py b/ide/south_migrations/0012_auto__add_field_usersettings_accepted_terms.py similarity index 100% rename from ide/migrations/0012_auto__add_field_usersettings_accepted_terms.py rename to ide/south_migrations/0012_auto__add_field_usersettings_accepted_terms.py diff --git a/ide/migrations/0013_auto__chg_field_buildresult_uuid__chg_field_usergithub_nonce__chg_fiel.py b/ide/south_migrations/0013_auto__chg_field_buildresult_uuid__chg_field_usergithub_nonce__chg_fiel.py similarity index 100% rename from ide/migrations/0013_auto__chg_field_buildresult_uuid__chg_field_usergithub_nonce__chg_fiel.py rename to ide/south_migrations/0013_auto__chg_field_buildresult_uuid__chg_field_usergithub_nonce__chg_fiel.py diff --git a/ide/migrations/0014_auto__add_field_project_app_jshint.py b/ide/south_migrations/0014_auto__add_field_project_app_jshint.py similarity index 100% rename from ide/migrations/0014_auto__add_field_project_app_jshint.py rename to ide/south_migrations/0014_auto__add_field_project_app_jshint.py diff --git a/ide/migrations/0015_auto__add_field_project_github_branch.py b/ide/south_migrations/0015_auto__add_field_project_github_branch.py similarity index 100% rename from ide/migrations/0015_auto__add_field_project_github_branch.py rename to ide/south_migrations/0015_auto__add_field_project_github_branch.py diff --git a/ide/migrations/0016_auto__add_field_usersettings_use_spaces__add_field_usersettings_tab_wi.py b/ide/south_migrations/0016_auto__add_field_usersettings_use_spaces__add_field_usersettings_tab_wi.py similarity index 100% rename from ide/migrations/0016_auto__add_field_usersettings_use_spaces__add_field_usersettings_tab_wi.py rename to ide/south_migrations/0016_auto__add_field_usersettings_use_spaces__add_field_usersettings_tab_wi.py diff --git a/ide/migrations/0017_auto__add_field_sourcefile_last_modified.py b/ide/south_migrations/0017_auto__add_field_sourcefile_last_modified.py similarity index 100% rename from ide/migrations/0017_auto__add_field_sourcefile_last_modified.py rename to ide/south_migrations/0017_auto__add_field_sourcefile_last_modified.py diff --git a/ide/migrations/0018_auto__add_field_project_project_type.py b/ide/south_migrations/0018_auto__add_field_project_project_type.py similarity index 100% rename from ide/migrations/0018_auto__add_field_project_project_type.py rename to ide/south_migrations/0018_auto__add_field_project_project_type.py diff --git a/ide/migrations/0019_auto__add_field_usersettings_whats_new.py b/ide/south_migrations/0019_auto__add_field_usersettings_whats_new.py similarity index 100% rename from ide/migrations/0019_auto__add_field_usersettings_whats_new.py rename to ide/south_migrations/0019_auto__add_field_usersettings_whats_new.py diff --git a/ide/migrations/0020_auto__del_unique_project_owner_name.py b/ide/south_migrations/0020_auto__del_unique_project_owner_name.py similarity index 100% rename from ide/migrations/0020_auto__del_unique_project_owner_name.py rename to ide/south_migrations/0020_auto__del_unique_project_owner_name.py diff --git a/ide/migrations/0021_auto__del_field_project_sdk_version__del_field_project_version_def_nam.py b/ide/south_migrations/0021_auto__del_field_project_sdk_version__del_field_project_version_def_nam.py similarity index 100% rename from ide/migrations/0021_auto__del_field_project_sdk_version__del_field_project_version_def_nam.py rename to ide/south_migrations/0021_auto__del_field_project_sdk_version__del_field_project_version_def_nam.py diff --git a/ide/migrations/0022_auto__add_field_sourcefile_target.py b/ide/south_migrations/0022_auto__add_field_sourcefile_target.py similarity index 100% rename from ide/migrations/0022_auto__add_field_sourcefile_target.py rename to ide/south_migrations/0022_auto__add_field_sourcefile_target.py diff --git a/ide/migrations/0023_auto__add_field_buildresult_worker_size.py b/ide/south_migrations/0023_auto__add_field_buildresult_worker_size.py similarity index 100% rename from ide/migrations/0023_auto__add_field_buildresult_worker_size.py rename to ide/south_migrations/0023_auto__add_field_buildresult_worker_size.py diff --git a/ide/migrations/0024_auto__add_field_resourceidentifier_compatibility.py b/ide/south_migrations/0024_auto__add_field_resourceidentifier_compatibility.py similarity index 100% rename from ide/migrations/0024_auto__add_field_resourceidentifier_compatibility.py rename to ide/south_migrations/0024_auto__add_field_resourceidentifier_compatibility.py diff --git a/ide/migrations/0025_auto__add_field_project_sdk_version.py b/ide/south_migrations/0025_auto__add_field_project_sdk_version.py similarity index 100% rename from ide/migrations/0025_auto__add_field_project_sdk_version.py rename to ide/south_migrations/0025_auto__add_field_project_sdk_version.py diff --git a/ide/migrations/0026_auto__add_buildsize.py b/ide/south_migrations/0026_auto__add_buildsize.py similarity index 100% rename from ide/migrations/0026_auto__add_buildsize.py rename to ide/south_migrations/0026_auto__add_buildsize.py diff --git a/ide/migrations/0027_migrate_build_sizes_to_table.py b/ide/south_migrations/0027_migrate_build_sizes_to_table.py similarity index 100% rename from ide/migrations/0027_migrate_build_sizes_to_table.py rename to ide/south_migrations/0027_migrate_build_sizes_to_table.py diff --git a/ide/migrations/0028_auto__del_field_buildresult_worker_size__del_field_buildresult_binary_.py b/ide/south_migrations/0028_auto__del_field_buildresult_worker_size__del_field_buildresult_binary_.py similarity index 100% rename from ide/migrations/0028_auto__del_field_buildresult_worker_size__del_field_buildresult_binary_.py rename to ide/south_migrations/0028_auto__del_field_buildresult_worker_size__del_field_buildresult_binary_.py diff --git a/ide/migrations/0029_auto__add_field_project_app_platforms.py b/ide/south_migrations/0029_auto__add_field_project_app_platforms.py similarity index 100% rename from ide/migrations/0029_auto__add_field_project_app_platforms.py rename to ide/south_migrations/0029_auto__add_field_project_app_platforms.py diff --git a/ide/migrations/0030_auto__add_resourcevariant__add_unique_resourcevariant_resource_file_va.py b/ide/south_migrations/0030_auto__add_resourcevariant__add_unique_resourcevariant_resource_file_va.py similarity index 100% rename from ide/migrations/0030_auto__add_resourcevariant__add_unique_resourcevariant_resource_file_va.py rename to ide/south_migrations/0030_auto__add_resourcevariant__add_unique_resourcevariant_resource_file_va.py diff --git a/ide/migrations/0031_create_resource_variants.py b/ide/south_migrations/0031_create_resource_variants.py similarity index 100% rename from ide/migrations/0031_create_resource_variants.py rename to ide/south_migrations/0031_create_resource_variants.py diff --git a/ide/migrations/0032_auto__del_field_project_app_version_code.py b/ide/south_migrations/0032_auto__del_field_project_app_version_code.py similarity index 100% rename from ide/migrations/0032_auto__del_field_project_app_version_code.py rename to ide/south_migrations/0032_auto__del_field_project_app_version_code.py diff --git a/ide/migrations/0033_migrate_pebblejs_to_sdk3.py b/ide/south_migrations/0033_migrate_pebblejs_to_sdk3.py similarity index 100% rename from ide/migrations/0033_migrate_pebblejs_to_sdk3.py rename to ide/south_migrations/0033_migrate_pebblejs_to_sdk3.py diff --git a/ide/migrations/0034_auto__add_field_sourcefile_folded_lines.py b/ide/south_migrations/0034_auto__add_field_sourcefile_folded_lines.py similarity index 100% rename from ide/migrations/0034_auto__add_field_sourcefile_folded_lines.py rename to ide/south_migrations/0034_auto__add_field_sourcefile_folded_lines.py diff --git a/ide/migrations/0035_auto__add_field_project_app_is_hidden__add_field_project_app_is_shown_.py b/ide/south_migrations/0035_auto__add_field_project_app_is_hidden__add_field_project_app_is_shown_.py similarity index 100% rename from ide/migrations/0035_auto__add_field_project_app_is_hidden__add_field_project_app_is_shown_.py rename to ide/south_migrations/0035_auto__add_field_project_app_is_hidden__add_field_project_app_is_shown_.py diff --git a/ide/migrations/0035_auto__add_field_resourcefile_target_platforms.py b/ide/south_migrations/0035_auto__add_field_resourcefile_target_platforms.py similarity index 100% rename from ide/migrations/0035_auto__add_field_resourcefile_target_platforms.py rename to ide/south_migrations/0035_auto__add_field_resourcefile_target_platforms.py diff --git a/ide/migrations/0036_auto__add_field_resourcevariant_tags__chg_field_resourcevariant_varian.py b/ide/south_migrations/0036_auto__add_field_resourcevariant_tags__chg_field_resourcevariant_varian.py similarity index 100% rename from ide/migrations/0036_auto__add_field_resourcevariant_tags__chg_field_resourcevariant_varian.py rename to ide/south_migrations/0036_auto__add_field_resourcevariant_tags__chg_field_resourcevariant_varian.py diff --git a/ide/migrations/0037_convert_suffixes_to_tags.py b/ide/south_migrations/0037_convert_suffixes_to_tags.py similarity index 100% rename from ide/migrations/0037_convert_suffixes_to_tags.py rename to ide/south_migrations/0037_convert_suffixes_to_tags.py diff --git a/ide/migrations/0038_auto__del_field_resourcevariant_variant__chg_field_resourcevariant_tag.py b/ide/south_migrations/0038_auto__del_field_resourcevariant_variant__chg_field_resourcevariant_tag.py similarity index 100% rename from ide/migrations/0038_auto__del_field_resourcevariant_variant__chg_field_resourcevariant_tag.py rename to ide/south_migrations/0038_auto__del_field_resourcevariant_variant__chg_field_resourcevariant_tag.py diff --git a/ide/migrations/0039_auto__add_field_resourceidentifier_target_platforms.py b/ide/south_migrations/0039_auto__add_field_resourceidentifier_target_platforms.py similarity index 100% rename from ide/migrations/0039_auto__add_field_resourceidentifier_target_platforms.py rename to ide/south_migrations/0039_auto__add_field_resourceidentifier_target_platforms.py diff --git a/ide/migrations/0040_fix_target_platforms.py b/ide/south_migrations/0040_fix_target_platforms.py similarity index 100% rename from ide/migrations/0040_fix_target_platforms.py rename to ide/south_migrations/0040_fix_target_platforms.py diff --git a/ide/migrations/0041_auto__del_field_resourcefile_target_platforms__del_unique_resourceiden.py b/ide/south_migrations/0041_auto__del_field_resourcefile_target_platforms__del_unique_resourceiden.py similarity index 100% rename from ide/migrations/0041_auto__del_field_resourcefile_target_platforms__del_unique_resourceiden.py rename to ide/south_migrations/0041_auto__del_field_resourcefile_target_platforms__del_unique_resourceiden.py diff --git a/ide/migrations/0042_auto__add_field_resourceidentifier_memory_format__add_field_resourceid.py b/ide/south_migrations/0042_auto__add_field_resourceidentifier_memory_format__add_field_resourceid.py similarity index 100% rename from ide/migrations/0042_auto__add_field_resourceidentifier_memory_format__add_field_resourceid.py rename to ide/south_migrations/0042_auto__add_field_resourceidentifier_memory_format__add_field_resourceid.py diff --git a/ide/migrations/0043_convert_resource_kinds_to_bitmap.py b/ide/south_migrations/0043_convert_resource_kinds_to_bitmap.py similarity index 100% rename from ide/migrations/0043_convert_resource_kinds_to_bitmap.py rename to ide/south_migrations/0043_convert_resource_kinds_to_bitmap.py diff --git a/ide/migrations/0044_auto__add_field_project_app_modern_multi_js.py b/ide/south_migrations/0044_auto__add_field_project_app_modern_multi_js.py similarity index 100% rename from ide/migrations/0044_auto__add_field_project_app_modern_multi_js.py rename to ide/south_migrations/0044_auto__add_field_project_app_modern_multi_js.py diff --git a/ide/migrations/0045_migrate_pebblejs_add_platforms.py b/ide/south_migrations/0045_migrate_pebblejs_add_platforms.py similarity index 100% rename from ide/migrations/0045_migrate_pebblejs_add_platforms.py rename to ide/south_migrations/0045_migrate_pebblejs_add_platforms.py diff --git a/ide/migrations/0047_remove_pebblejs_dependencies.py b/ide/south_migrations/0047_remove_pebblejs_dependencies.py similarity index 100% rename from ide/migrations/0047_remove_pebblejs_dependencies.py rename to ide/south_migrations/0047_remove_pebblejs_dependencies.py diff --git a/ide/migrations/0048_create_pkjs_target.py b/ide/south_migrations/0048_create_pkjs_target.py similarity index 100% rename from ide/migrations/0048_create_pkjs_target.py rename to ide/south_migrations/0048_create_pkjs_target.py diff --git a/ide/migrations/0049_add_project_dependencies.py b/ide/south_migrations/0049_add_project_dependencies.py similarity index 100% rename from ide/migrations/0049_add_project_dependencies.py rename to ide/south_migrations/0049_add_project_dependencies.py diff --git a/ide/migrations/0050_auto__del_unique_sourcefile_project_file_name__add_unique_sourcefile_p.py b/ide/south_migrations/0050_auto__del_unique_sourcefile_project_file_name__add_unique_sourcefile_p.py similarity index 100% rename from ide/migrations/0050_auto__del_unique_sourcefile_project_file_name__add_unique_sourcefile_p.py rename to ide/south_migrations/0050_auto__del_unique_sourcefile_project_file_name__add_unique_sourcefile_p.py diff --git a/ide/migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py b/ide/south_migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py similarity index 100% rename from ide/migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py rename to ide/south_migrations/0051_auto__chg_field_resourceidentifier_target_platforms.py diff --git a/auth/__init__.py b/ide/south_migrations/__init__.py similarity index 100% rename from auth/__init__.py rename to ide/south_migrations/__init__.py diff --git a/ide/tasks/archive.py b/ide/tasks/archive.py index 7cc7624b..8bf8d9da 100644 --- a/ide/tasks/archive.py +++ b/ide/tasks/archive.py @@ -7,7 +7,7 @@ import uuid import zipfile -from celery import task +from celery import shared_task from django.conf import settings from django.contrib.auth.models import User from django.core.exceptions import SuspiciousOperation @@ -48,7 +48,7 @@ def add_project_to_archive(z, project, prefix='', suffix=''): z.writestr('%s/jshintrc' % prefix, generate_jshint_file(project)) -@task(acks_late=True) +@shared_task(acks_late=True) def create_archive(project_id): project = Project.objects.get(pk=project_id) prefix = re.sub(r'[^\w]+', '_', project.name).strip('_').lower() @@ -74,7 +74,7 @@ def create_archive(project_id): return '%s%s' % (settings.EXPORT_ROOT, outfile) -@task(acks_late=True) +@shared_task(acks_late=True) def export_user_projects(user_id): user = User.objects.get(pk=user_id) projects = Project.objects.filter(owner=user) @@ -135,11 +135,7 @@ def path(self): return self.entry.filename -def ends_with_any(s, options): - return any(s.endswith(end) for end in options) - - -@task(acks_late=True) +@shared_task(acks_late=True) def do_import_archive(project_id, archive, delete_project=False): project = Project.objects.get(pk=project_id) try: diff --git a/ide/tasks/build.py b/ide/tasks/build.py index 7bd09dd7..a985b4de 100644 --- a/ide/tasks/build.py +++ b/ide/tasks/build.py @@ -6,7 +6,7 @@ import tempfile import zipfile -from celery import task +from celery import shared_task from django.conf import settings from django.utils.timezone import now @@ -27,6 +27,7 @@ def _set_resource_limits(): resource.setrlimit(resource.RLIMIT_RSS, (30 * 1024 * 1024, 30 * 1024 * 1024)) # 30 MB of memory resource.setrlimit(resource.RLIMIT_FSIZE, (20 * 1024 * 1024, 20 * 1024 * 1024)) # 20 MB output files. + def save_debug_info(base_dir, build_result, kind, platform, elf_file): path = os.path.join(base_dir, 'build', elf_file) if os.path.exists(path): @@ -59,7 +60,7 @@ def store_size_info(project, build_result, platform, zip_file): pass -@task(ignore_result=True, acks_late=True) +@shared_task(ignore_result=True, acks_late=True) def run_compile(build_result): build_result = BuildResult.objects.get(pk=build_result) project = build_result.project diff --git a/ide/tasks/gist.py b/ide/tasks/gist.py index 496b518c..cddaba6b 100644 --- a/ide/tasks/gist.py +++ b/ide/tasks/gist.py @@ -1,7 +1,9 @@ import json +import urllib2 +from collections import defaultdict import github -from celery import task +from celery import shared_task from django.db import transaction from django.conf import settings @@ -12,11 +14,9 @@ from ide.utils.project import APPINFO_MANIFEST, PACKAGE_MANIFEST from ide.utils import generate_half_uuid from utils.td_helper import send_td_event -from collections import defaultdict -import urllib2 -@task(acks_late=True) +@shared_task(acks_late=True) def import_gist(user_id, gist_id): user = User.objects.get(pk=user_id) g = github.Github() diff --git a/ide/tasks/git.py b/ide/tasks/git.py index 96b22018..75b162a4 100644 --- a/ide/tasks/git.py +++ b/ide/tasks/git.py @@ -4,7 +4,7 @@ import os import logging -from celery import task +from celery import shared_task from django.conf import settings from django.utils.timezone import now from github.GithubObject import NotSet @@ -24,7 +24,7 @@ logger = logging.getLogger(__name__) -@task(acks_late=True) +@shared_task(acks_late=True) def do_import_github(project_id, github_user, github_project, github_branch, delete_project=False): try: url = "https://github.com/%s/%s/archive/%s.zip" % (github_user, github_project, github_branch) @@ -311,19 +311,19 @@ def github_pull(user, project): return import_result -@task +@shared_task def do_github_push(project_id, commit_message): project = Project.objects.select_related('owner__github').get(pk=project_id) return github_push(project.owner, commit_message, project.github_repo, project) -@task +@shared_task def do_github_pull(project_id): project = Project.objects.select_related('owner__github').get(pk=project_id) return github_pull(project.owner, project) -@task +@shared_task def hooked_commit(project_id, target_commit): project = Project.objects.select_related('owner__github').get(pk=project_id) did_something = False diff --git a/ide/tasks/td_task.py b/ide/tasks/td_task.py index 7efd976b..abad92c3 100644 --- a/ide/tasks/td_task.py +++ b/ide/tasks/td_task.py @@ -1,4 +1,4 @@ -from celery import task +from celery import shared_task from django.conf import settings import requests @@ -6,7 +6,7 @@ __author__ = 'katharine' -@task(ignore_result=True) +@shared_task(ignore_result=True) def td_add_events(event): result = requests.post(settings.TD_URL, data=event) result.raise_for_status() diff --git a/ide/templates/ide/project.html b/ide/templates/ide/project.html index be295c8f..6000c14a 100644 --- a/ide/templates/ide/project.html +++ b/ide/templates/ide/project.html @@ -1,34 +1,20 @@ {% extends "common/base.html" %} {% load staticfiles %} {% load i18n %} - +{% load pipeline %} {% block title %}CloudPebble – {{ project.name }}{% endblock %} {% block head %} - - - - - - - - +{% stylesheet 'codemirror' %} {% if font_css %} {% endif %} - - - - - - +{% stylesheet 'textext' %} - - - +{% stylesheet 'ide' %} {% endblock %} @@ -553,76 +539,11 @@

{% trans 'Compass and Accelerometer' %}

var REGEXES = _.mapObject(JSON.parse('{{regexes_json|escapejs}}'), function(v) { return new RegExp(v)}); - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +{% javascript 'lib' %} +{% javascript 'ide' %} - - - - - - - - - - - {% endblock %} diff --git a/ide/urls.py b/ide/urls.py index 98565fa9..2ff32086 100644 --- a/ide/urls.py +++ b/ide/urls.py @@ -17,9 +17,8 @@ from ide.views.index import index from ide.views.project import view_project, github_hook, build_status, import_gist, qemu_config, enter_phone_token from ide.views.settings import settings_page, start_github_auth, remove_github_auth, complete_github_auth - -urlpatterns = patterns( - '', +from django.views.i18n import javascript_catalog +urlpatterns = [ url(r'^$', index, name='index'), url(r'^import/github/(?P.+?)/(?P.+?)$', index, name='index'), url(r'^projects', get_projects, name='get_projects'), @@ -80,5 +79,5 @@ url(r'^whats_new', whats_new, name='whats_new'), url(r'^gist/(?P[0-9a-f]+)$', import_gist), url(r'^heartbeat$', heartbeat), - url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', name='jsi18n'), -) + url(r'^jsi18n/$', javascript_catalog, name='jsi18n'), +] diff --git a/package.json b/package.json index 88d18b8b..97738359 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,10 @@ { + "private": true, "name": "cloudpebble", "version": "1.0.0", + "author": "Katharine Berry ", "description": "It clouds pebbles.", + "license": "MIT", "dependencies": { "json-loader": "^0.5.4", "restrict-resource-webpack-plugin": "^1.0.0", @@ -11,4 +14,4 @@ "webpack-fail-plugin": "^1.0.5" }, "engines": {"node": "6.2.1"} -} \ No newline at end of file +} diff --git a/qr/urls.py b/qr/urls.py index 6abd572b..452d645d 100644 --- a/qr/urls.py +++ b/qr/urls.py @@ -2,7 +2,6 @@ from qr import views -urlpatterns = patterns( - '', +urlpatterns = [ url('$^', views.render, name='render') -) +] diff --git a/requirements.txt b/requirements.txt index cbb4122e..279cfb50 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,28 +1,29 @@ -Django==1.6.2 -django-registration==1.0 -amqp==1.4.4 +Django==1.9.7 +django-registration==2.0.4 +-e git://github.com/pebble/django-pipeline.git@7c1bb9f4a90a5911c94e24bee79dfed48602a19f#egg=pipeline +amqp==1.4.9 celery==3.1.23 -django-celery==3.1.17 flup==1.0.3.dev-20110405 -psycopg2==2.4.5 +psycopg2==2.6.1 South==1.0.2 qrcode==4.0.4 Pillow==2.9.0 -pygithub==1.14.2 -python-social-auth==0.1.23 +pygithub==1.26.0 +python-social-auth==0.2.16 redis==2.10.5 boto==2.39.0 gevent==1.1 psycogreen==1.0 -requests==2.7.0 -oauth2client==1.3 -django-bower==5.0.4 +requests==2.9.1 +oauth2client==1.5.2 +django-bower==5.1.0 mock==2.0.0 + # This is used for Mailchimp integration mailchimp==2.0.9 # These are used for Heroku hosting setup. -dj-static==0.0.6 +whitenoise==3.0 gunicorn==19.3.0 dj-database-url==0.3.0 newrelic==2.50.0.39 diff --git a/ide/static/ide/js/whats_new.js b/root/static/common/js/whats_new.js similarity index 100% rename from ide/static/ide/js/whats_new.js rename to root/static/common/js/whats_new.js diff --git a/root/templates/common/base.html b/root/templates/common/base.html index 8dfecfe7..0a59b036 100644 --- a/root/templates/common/base.html +++ b/root/templates/common/base.html @@ -1,14 +1,14 @@ {% load staticfiles %} +{% load pipeline %} {% load i18n %} {% block title %}CloudPebble{% endblock %} - - - - + + {% stylesheet 'base' %} +