diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..c80e0ec --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,21 @@ +types: + - test + - deploy + + +test_app: + type: test + script: + #- docker login -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" $CI_REGISTRY + #- docker pull "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME" + - echo "test $CI_BUILD_REF_NAME" + - runtests.sh + - COVERALLS_REPO_TOKEN=$COVERALLS_REPO_TOKEN coveralls + + +trigger_build: + stage: deploy + script: + - curl -X POST -F token=$SPICYCRM_TRIGGER_TOKEN -F ref=$CI_BUILD_REF_NAME https://gitlab.com/api/v3/projects/1624463/trigger/builds + dependencies: + - test_app diff --git a/README.md b/README.md index c6813d4..6cb0182 100755 --- a/README.md +++ b/README.md @@ -74,8 +74,183 @@ spicy create siteskin [:default cms-chief-editor] = 1.3 <= 1.5.12 +- Python 2.7 support + +How to Use +========== + +Get the code +------------ + +Getting the code for the latest stable release use 'pip'. :: + + git+https://gitlab.com/spicycms.com/spicy.core.git@1.2.0#egg=spicy + + +Install in your project +----------------------- + +your project's settings. :: + + LOGIN_REDIRECT_URL = '/' + LOGIN_URL = '/signin/' + REGISTRATION_OPEN = True + + LOGIN_URL = '/signin/' + LOGIN_REDIRECT_URL = '/' + + AUTHENTICATION_BACKENDS = ( + 'spicy.core.profile.auth_backends.CustomUserModelBackend', + ) + + SERVICES = ( + 'spicy.core.profile.services.ProfileService', + 'spicy.core.trash.services.TrashService', + ) + + INSTALLED_APPS = ( + # Django native apps + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.humanize', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.staticfiles', + + # Spicy core components + 'spicy.core.trash', + 'spicy.core.admin', + 'spicy.core.service', + 'spicy.core.siteskin', + 'spicy.core.simplepages', + ) + + STATICFILES_FINDERS = ( + 'spicy.core.siteskin.loaders.ThemeStaticFinder', + 'spicy.core.siteskin.loaders.AppDirectoriesFinder', + ) + + TEMPLATE_LOADERS = ( + 'spicy.core.siteskin.loaders.ThemeTemplateLoader', + 'django.template.loaders.app_directories.Loader', + 'spicy.core.siteskin.loaders.BackendTemplateLoader', + ) + + TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.contrib.auth.context_processors.auth', + + 'spicy.core.profile.context_processors.auth', + 'spicy.core.siteskin.context_processors.base', + 'spicy.core.admin.context_processors.base', + + 'django.core.context_processors.debug', + 'django.core.context_processors.i18n', + 'django.core.context_processors.media', + 'django.core.context_processors.request', + ) + + MIDDLEWARE_CLASSES = ( + 'spicy.core.siteskin.middleware.AjaxMiddleware', + 'spicy.core.siteskin.threadlocals.ThreadLocals', + ) + + if DEBUG: + MIDDLEWARE_CLASSES += ( + # for developers + 'spicy.core.rmanager.middleware.ProfileMiddleware', + ) + + + + +Docs +---- + +####Custom User Profile +В этом разделе описана последовательность действий с примером кода, которая позволит создать кастомную модель профайла. +Например, вы хотите добавить поля skype и sms_notification к модели пользователя. Для этого необходимо: + +1) запустить проект со схемой данных для базового профайла + +* в бд вы получаете таблицу test_profile, без дополнительных полей +* в коде класс-модель profile.TestProfile, без дополнительных полей + +2) создать новую ветку в проекте (apps.webapp), перейти на нее и расширить модель профайла нужными полями + +
+class CustomProfile(AbstractProfile):
+    sms_notification = models.BooleanField(_('Use SMS notification'), blank=True, default=False)
+    skype = models.CharField(_('Skype'), max_length=255, blank=True, null=True)
+
+    class Meta:
+        abstract = False
+        db_table = 'test_profile'
+
+ +3) добавить в settings.py настройку новой модели профайла + +
CUSTOM_USER_MODEL = 'webapp.CustomProfile'
+ +* в бд остается таблица test_profile, без дополнительных полей +* в коде начинает использоваться класс-модель CustomProfile, с расширенным набором полей + +4) сделать патч таблицы профайла tet_profile - добавить новые поля модели (внутри контейнера db) + +
+begin;
+alter table test_profile add column sms_notification boolean default False;
+alter table test_profile add column skype varchar(255);
+commit;
+
+ +* в бд таблица test_profile расширена полями +* в коде используется расширенный класс пользователя webapp.CustomProfile + +5) сделать патч системных таблиц Django - заменить на уровне бд customprofile на test_profile, чтобы сохранить старые данные пользователей (внутри контейнера db) + +
+begin;
+SELECT django_content_type.id into test_id FROM django_content_type WHERE app_label = 'profile' AND model = 'testprofile';
+SELECT django_content_type.id into custom_id FROM django_content_type WHERE app_label = 'webapp' AND model = 'customprofile';
+
+update auth_permission set content_type_id = (select * from test_id) where content_type_id = (select * from custom_id);
+delete from django_content_type where id = (select * from custom_id);
+update django_content_type set app_label = 'webapp', model = 'customprofile' where id=(select * from test_id);
+
+drop table test_id;
+drop table custom_id;
+commit;
+
+begin;
+alter table test_profile_sites rename testprofile_id to customprofile_id;
+commit;
+
+ +* в бд таблица test_profile расширена полями +* системные таблицы Django не содержат ссылок на customprofile +* в коде используется расширенный класс пользователя webapp.CustomProfile + +6) убедиться, что новый профайл работает корректно + +* создание пользователя работает +* изменение пользователя работает +* удаление пользователя работает + + +TODO: write docs +TODO: custom User Profile, forms create and edit templates +TODO: use API service +TODO: base templates for admin panel and formfield +TODO: templates tag and filter +======= Service + Provider Cunsumer diff --git a/setup.py b/setup.py index 8d046fe..d29067b 100755 --- a/setup.py +++ b/setup.py @@ -66,10 +66,10 @@ def long_description(): 'pycrypto==2.6.1', # for Fabric API 'numpydoc==0.4', 'django-nose==1.2', - #'django-debug-toolbar==1.3', - #'django-devserver', - #'django-extensions', - 'django-autocomplete-light==2.0.0a15', + 'django-debug-toolbar', + 'django-devserver', + 'django-extensions', + 'django-autocomplete-light==1.4.14', 'xlrd', 'xlwt' diff --git a/src/spicy/core/profile/templates/spicy.core.profile/mail/activation_email.txt b/src/spicy/core/profile/templates/spicy.core.profile/mail/activation_email.txt index 3103f0e..dffa0a0 100755 --- a/src/spicy/core/profile/templates/spicy.core.profile/mail/activation_email.txt +++ b/src/spicy/core/profile/templates/spicy.core.profile/mail/activation_email.txt @@ -1,3 +1,4 @@ +{% load url from future %} {% blocktrans with sitename=site.name %}Welcome to {{ sitename }}!{% endblocktrans %} {% trans "Your account is not acivated yet. To activate press the following link:" %} diff --git a/src/spicy/core/siteskin/decorators.py b/src/spicy/core/siteskin/decorators.py index 36412be..bcb3d83 100755 --- a/src/spicy/core/siteskin/decorators.py +++ b/src/spicy/core/siteskin/decorators.py @@ -6,11 +6,14 @@ from django.shortcuts import render_to_response from django.template import RequestContext, loader from django.template.base import TemplateDoesNotExist, TemplateSyntaxError -from django.utils import simplejson from django.utils.translation import ugettext as _ from spicy.utils import make_cache_key from spicy.utils.printing import print_error, print_info, print_warning from . import cache, defaults +try: + import json +except ImportError: + from django.utils import simplejson as json class APIResponse(object): @@ -88,7 +91,7 @@ class JsonResponse(HttpResponse): """ def __init__(self, data): super(JsonResponse, self).__init__( - content=simplejson.dumps(data, cls=DjangoJSONEncoder), + content=json.dumps(data, cls=DjangoJSONEncoder), mimetype='application/json') if not 'Content-Length' in self: self['Content-Length'] = len(self.content) diff --git a/src/spicy/core/siteskin/widgets.py b/src/spicy/core/siteskin/widgets.py index 7a21911..ab85348 100755 --- a/src/spicy/core/siteskin/widgets.py +++ b/src/spicy/core/siteskin/widgets.py @@ -9,11 +9,13 @@ from django.utils.html import escape, conditional_escape from django.utils.safestring import mark_safe from django.utils.encoding import force_unicode -from django.utils.simplejson import JSONEncoder from django.utils.translation import ugettext from django.core.validators import EMPTY_VALUES from django.db import models - +try: + from json import JSONEncoder +except ImportError: + from django.utils.simplejson import JSONEncoder ### NEW diff --git a/src/spicy/core/trash/views.py b/src/spicy/core/trash/views.py index 7f13058..ac15da8 100755 --- a/src/spicy/core/trash/views.py +++ b/src/spicy/core/trash/views.py @@ -1,5 +1,3 @@ -from django.utils import simplejson as json - from datetime import datetime from django.conf import settings @@ -14,3 +12,8 @@ from django.views.decorators.csrf import csrf_protect from spicy.core.siteskin.decorators import render_to, ajax_request + +try: + import json +except ImportError: + from django.utils import simplejson as json \ No newline at end of file