merge with master

This commit is contained in:
Artur Barseghyan 2016-11-17 14:05:31 +01:00
commit dca4d9d20d
275 changed files with 6266 additions and 3460 deletions

4
.gitignore vendored
View file

@ -8,6 +8,7 @@
.zip
/.coverage
/dev.db
/.cache/
MANIFEST.in~
MIND_BUCKET.rst
@ -31,9 +32,11 @@ README_PARTS.rst
/src/django_fobi.egg-info
/src/fobi/contrib/plugins/form_elements/fields/hidden_model_object/
/src/fobi/contrib/plugins/form_importers/mailchimp_importer/bucket.py
/src/fobi/contrib/apps/wagtail_integration_/
/scripts/install_django_1_7_wagtail.sh
/scripts/reinstall_django_1_7_wagtail.sh
/scripts/copy_lund_files.sh
/examples/db/
/examples/tmp/
@ -41,6 +44,7 @@ README_PARTS.rst
/examples/media/fobi_plugins/content_image/
/examples/media/fobi_plugins/file/
/examples/media/cache/
/examples/simple/lund_urls.py
/examples/simple/lund/
/examples/simple/settings/local_settings.py
/examples/simple/settings/local_settings_foundation5.py

View file

@ -15,6 +15,123 @@ are used for versioning (schema follows below):
0.3.4 to 0.4).
- All backwards incompatible changes are mentioned in this document.
0.10.1
------
2016-11-17
- Fixed captcha and re-captcha issues in form wizards.
0.10
----
2016-11-16
Note, that this release contains minor backwards incompatible changes, that may
break your code. Two additional arguments have been added to the
`submit_plugin_form_data` method of the form element plugins. If you have
written custom form element plugins - update your code.
Note, that this release contain minor backwards incompatible changes, that
may break your existing code (your data is left intact). If you have written
custom form element plugins you should update your code!
- Added `form_entry_elements` and `kwargs` to the `submit_plugin_form_data`
method of the form element plugins. Make sure to update your custom
plugins if you have written any.
- Added tests for mailchimp integration plugin.
- Moving all plugins to base submodules of the correspondent sub
packages.
- Add missing whitespace toe the `help_text` of the `title` field of
`FormEntry` and `FormWizardEntry` models.
- Disable GoogleAnalytics while testing (guess what - this change speeds up
selenium tests twice).
- Docs updated.
- Helper scripts updated.
- Multiple pep8 fixes.
0.9.17
------
2016-11-13
Announcing dropping support of Python 2.6 and Django 1.7. As of 0.9.17
everything is still backwards compatible with Django 1.7, but in future
versions it will be wiped out.
- Value validations for Integer and Text Fields.
- Hide previous button in form wizard template for bootstrap3 on first step.
0.9.16
------
2016-11-10
- Introduced form titles (shown in view templates).
- Improved navigation of the form wizards.
0.9.15
------
2016-11-07
- Minor fixes.
0.9.14
------
2016-11-07
- Minor fixes.
0.9.13
------
2016-11-05
Announcing dropping support of Django 1.5 and 1.6. As of 0.9.17 everything is
still backwards compatible with versions 1.5 and 1.6, but in future versions
compatibility with these versions will be wiped out.
- Fix backwards compatibility of `slider` and `range_select` plugins with
Django versions 1.5 and 1.6.
0.9.12
------
2016-11-02
- Better debugging.
- Upgrade example FeinCMS integration to work with 1.12.
0.9.11
------
2016-11-01
- Fixes.
0.9.10
------
2016-11-01
- Fixed issue with custom labels in the `slider` plugin.
- Made `slider` plugin compatible with Django <= 1.6.
- Fixes `get_absolute_url` methods on `FormEntry` and `FormWizardEntry`
models. #48
0.9.9
-----
2016-10-31
- Make it possible to add custom ticks to the `slider` plugin.
0.9.8
-----
2016-10-27
- Support multiple sliders in one form.
0.9.7
-----
2016-10-27
- Improvements in the generic integration processor. #47
- Improved form wizard interface and navigation.
- Fixed a broken test.
- Added import/export functionality for form wizards.
0.9.6
-----
2016-10-25

View file

@ -23,3 +23,15 @@ Thanks to the following people for their contributions:
- `Mario Taddei
<https://github.com/barseghyanartur/django-fobi/commits/master?author=mariuccio>`_
for his initiative to make `Select multiple with max` plugin.
- `Andy Babic
<https://github.com/barseghyanartur/django-fobi/commits/master?author=ababic>`_
for improvements in the generic integration processor.
- `Heldroe
<https://github.com/barseghyanartur/django-fobi/commits/master?author=Heldroe>`_
for minor fixes.
- `Michal Dabski
<https://github.com/barseghyanartur/django-fobi/commits/master?author=mick88>`_
for minor fixes.
- `Marcos Amorim
<https://github.com/barseghyanartur/django-fobi/commits/master?author=marcosamorim>`_
for number of validation improvements.

View file

@ -10,8 +10,21 @@ handling the submitted form data).
Prerequisites
=============
- Django 1.5, 1.6, 1.7, 1.8, 1.9, 1.10
- Python >= 2.6.8, >= 2.7, >= 3.3
Current
-------
- Django 1.8, 1.9, 1.10
- Python >= 2.7, >= 3.3
Past
----
- Dropping support of Django 1.5, 1.6 has been announced in version
0.9.13. Dropping support of Django 1.7 has been announced in version 0.9.17.
As of 0.9.17 everything is still backwards compatible with versions 1.5, 1.6
and 1.7, but in future versions compatibility with these versions will be
wiped out.
- Dropping support of Python 2.6 has been announced in version 0.9.17.
As of 0.9.17 everything is still backwards compatible with Python 2.6, but
in future versions compatibility with it will be wiped out.
Key concepts
============
@ -89,7 +102,7 @@ Roadmap
=======
Some of the upcoming/in-development features/improvements are:
- Integration with `django-rest-framework` (in version 0.10).
- Integration with `django-rest-framework` (in version 0.11).
See the `TODOS <https://raw.githubusercontent.com/barseghyanartur/django-fobi/master/TODOS.rst>`_
for the full list of planned-, pending- in-development- or to-be-implemented
@ -416,12 +429,16 @@ following arguments:
- `request` (django.http.HttpRequest): The Django HTTP request.
- `form` (django.forms.Form): Form object (a valid one, which contains
the ``cleaned_data`` attribute).
- `form_element_entries` (fobi.models.FormElementEntry): Form element entries
for the `form_entry` given.
- (**)kwargs : Additional arguments.
Example (taken from fobi.contrib.plugins.form_elements.fields.file):
.. code-block:: python
def submit_plugin_form_data(self, form_entry, request, form):
def submit_plugin_form_data(self, form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data."""
# Get the file path
file_path = form.cleaned_data.get(self.data.name, None)
@ -1486,16 +1503,6 @@ README.rst file in directory of each plugin for details.
<https://github.com/barseghyanartur/django-fobi/tree/stable/src/fobi/contrib/plugins/form_handlers/mail/>`__:
Send the form data by email.
Limitations
-----------
- At the moment, if you have used `django-simple-captcha` or
`django-recaptcha` plugins in one of the forms of the wizard, the wizard
becomes invalid at the end and sends you back to the form which used
captcha (see the issue `here
<https://github.com/mbi/django-simple-captcha/issues/6>`__ and `here
<https://github.com/praekelt/django-recaptcha/issues/115>`__). Therefore,
you're not recommended to use captcha solutions in wizard forms (yet).
Permissions
===========
Plugin system allows administrators to specify the access rights to every
@ -1783,56 +1790,58 @@ Note, that you should not provide the `fobi_dynamic_values.` as a prefix.
Currently, the following variables are available in the
`fobi.context_processors.dynamic_values` context processor:
- request: Stripped HttpRequest object.
.. code-block:: text
- request.path: A string representing the full path to the requested page,
not including the scheme or domain.
- request: Stripped HttpRequest object.
- request.get_full_path(): Returns the path, plus an appended query string,
if applicable.
- request.path: A string representing the full path to the requested page,
not including the scheme or domain.
- request.is_secure(): Returns True if the request is secure; that is, if
it was made with HTTPS.
- request.get_full_path(): Returns the path, plus an appended query string,
if applicable.
- request.is_ajax(): Returns True if the request was made via an
XMLHttpRequest, by checking the HTTP_X_REQUESTED_WITH header for the
string 'XMLHttpRequest'.
- request.is_secure(): Returns True if the request is secure; that is, if
it was made with HTTPS.
- request.META: A stripped down standard Python dictionary containing the
available HTTP headers.
- request.is_ajax(): Returns True if the request was made via an
XMLHttpRequest, by checking the HTTP_X_REQUESTED_WITH header for the
string 'XMLHttpRequest'.
- HTTP_ACCEPT_ENCODING: Acceptable encodings for the response.
- request.META: A stripped down standard Python dictionary containing the
available HTTP headers.
- HTTP_ACCEPT_LANGUAGE: Acceptable languages for the response.
- HTTP_ACCEPT_ENCODING: Acceptable encodings for the response.
- HTTP_HOST: The HTTP Host header sent by the client.
- HTTP_ACCEPT_LANGUAGE: Acceptable languages for the response.
- HTTP_REFERER: The referring page, if any.
- HTTP_HOST: The HTTP Host header sent by the client.
- HTTP_USER_AGENT: The clients user-agent string.
- HTTP_REFERER: The referring page, if any.
- QUERY_STRING: The query string, as a single (unparsed) string.
- HTTP_USER_AGENT: The clients user-agent string.
- REMOTE_ADDR: The IP address of the client.
- QUERY_STRING: The query string, as a single (unparsed) string.
- request.user: Authenticated user.
- REMOTE_ADDR: The IP address of the client.
- request.user.email:
- request.user: Authenticated user.
- request.user.get_username(): Returns the username for the user. Since
the User model can be swapped out, you should use this method
instead of referencing the username attribute directly.
- request.user.email:
- request.user.get_full_name(): Returns the first_name plus the
last_name, with a space in between.
- request.user.get_username(): Returns the username for the user. Since
the User model can be swapped out, you should use this method
instead of referencing the username attribute directly.
- request.user.get_short_name(): Returns the first_name.
- request.user.get_full_name(): Returns the first_name plus the
last_name, with a space in between.
- request.user.is_anonymous():
- request.user.get_short_name(): Returns the first_name.
- now: datetime.datetime.now()
- request.user.is_anonymous():
- today: datetime.date.today()
- now: datetime.datetime.now()
- today: datetime.date.today()
Submitted form element plugins values
=====================================
@ -1985,6 +1994,51 @@ element- and form handler- plugins.
shown in case of missing form element handlers, set this to False in
your settings module. Default value is True.
Testing
=======
Project is covered by test (functional- and browser-tests).
To test with all supported Python/Django versions type:
.. code-block:: sh
tox
To test just your working environment type:
.. code-block:: sh
./runtests.py
It's assumed that you have all the requirements installed. If not, first
install the test requirements:
.. code-block:: sh
pip install -r examples/requirements/common_test_requirements.txt
Selenium
--------
Latest versions of Firefox are often not supported by Selenium. Current
version of the Selenium for Python (2.53.6) works fine with Firefox 47.
Thus, instead of using system Firefox you could better use a custom one.
Set up Firefox 47
~~~~~~~~~~~~~~~~~
1. Download Firefox 47 from
`this
<https://ftp.mozilla.org/pub/firefox/releases/47.0.1/linux-x86_64/en-GB/firefox-47.0.1.tar.bz2>`__
location and unzip it into ``/usr/lib/firefox47/``
2. Specify the full path to your Firefox in ``FIREFOX_BIN_PATH``
setting. Example:
.. code-block:: python
FIREFOX_BIN_PATH = '/usr/lib/firefox47/firefox'
After that your Selenium tests would work.
Troubleshooting
===============
If you get a ``FormElementPluginDoesNotExist`` or a

View file

@ -1,6 +1,6 @@
Roadmap of upcoming releases
============================
0.10
0.11
----
yyyy-mm-ddd (upcoming).

View file

@ -34,7 +34,7 @@ Regarding the form wizards
+ Ideally, it would be great to support data-slider-handle="square" (or
"round", "triangle") options of the bootstrap-slider plugin. See the first
issue in "Uncategorised".
- Rethink the new navigation of forms and form wizards.
+ Rethink the new navigation of forms and form wizards.
- Add support for form wizard conditions.
+ Fixed broken dependencies for docs.
- Add FeinCMS integration app for form wizards.
@ -45,6 +45,8 @@ Regarding the form wizards
- Add selenium tests for form wizards.
- Make `foundation5` and `django-admin-theme` themes to reflect the latest
GUI changes (form wizards).
- Make sure captcha plugins are usable with form wizards (at the moment they
are being invalidated on the last step).
Roadmap
-------
@ -54,6 +56,11 @@ Roadmap
Uncategorised
-------------
- Implement the clone form functionality.
- Implement the clone form wizard functionality.
- Rethink templating of the integration packages (feincms_integration,
djangocms_integration, mezzanine_integration), as now they are a bit
of a mess. Document integration properly, if not yet done.
- Add tests for import/export of forms.
- Add tests for export of plugin data (db_store).
- In the form element plugins, when handling submit_form_data, somehow
@ -103,9 +110,9 @@ Uncategorised
validation method there, which accepts the request, the form and the
form_entry object for validation. Also, in the BaseFormFieldPlugin, there
should be `name`, `required`, `help_text`, `label` fields to be present (
scheck other fields of Django formfield). In formfield plugins, subclass
check other fields of Django formfield). In formfield plugins, subclass
from BaseFormFieldPlugin, instead of the BaseFormElementPlugin.
+ In the view, validate the form fields (if they are sublcass of
+ In the view, validate the form fields (if they are subclass of
BaseFormFieldPlugin).
+ Actually, if plugin doesn't have a form, save it immediately. Do not wait
for POST.
@ -305,7 +312,7 @@ Uncategorised
+ Check if it's safe to use the initial dynamic values.
+ In the updated GUI (bootstrap3), if form names are too long, the layout
doesn't look nice anymore.
- Somehow, the drag and drop of the form elements got broken. Fix ASAP.
+ Somehow, the drag and drop of the form elements got broken. Fix ASAP.
- Since tests have been made quite general, create them for all contrib
form elements and handlers (not yet for things like CAPTCHA).
- Translate German and Russian URLs.
@ -313,9 +320,7 @@ Uncategorised
admin) as much generic so that change between versions doesn't cause
styling issues.
- Make sure the existing "simple" theme works very well (in looks) in
Django 1.6.
- Make sure the existing "simple" theme works very well (in looks) in
Django 1.7.
Django 1.8, 1.9 and 1.10.
- Nicer styling for the radio button (Foundation 5 theme).
- Nicer styling for the radio button (Simple theme).
- Make it possible to provide an alternative rendering of the form field
@ -327,7 +332,7 @@ Uncategorised
part).
- Split the ``FOBI_RESTRICT_PLUGIN_ACCESS`` into two: one for form elements
and one for form handlers.
- Improve the "simple" theme for Django 1.6 and Django 1.7 (tiny bits of
- Improve the "simple" theme for Django 1.8, 1.9 and 1.10 (tiny bits of
styling).
- Edit form test.
- Edit form element tests.
@ -343,7 +348,7 @@ Uncategorised
with the latest versions of the packages.
- Add support for `imageurl` and `birthday` fields of MailChimp (they are
ignored at the moment).
- Fix layout issue on step 2 of the MailChimp import (step 2 of the wizard).
+ Fix layout issue on step 2 of the MailChimp import (step 2 of the wizard).
- Properly document the form importers API.
- django-rest-framework integration.
@ -397,7 +402,7 @@ Should haves
re-created form from saved JSON sa well.
- Add `django-treebeard` field as an alternative (vs MPTT fields).
- Make sure that all views are 100% AJAX ready.
- Wagtail integration.
- Wagtail integration (in progress since October 2016).
- Document the changes.
- Find out why subclassing the ``select_model_object`` plugin didn't work.
- Rename the ``simple`` theme into ``django_admin_style_theme``.
@ -451,7 +456,7 @@ Could haves
least the FeinCMS).
- Make sure that the form view return can be overridden?
- Add datetime range and date range fields.
- Configure defaults values of each plugin in projects' settings module.
+ Configure defaults values of each plugin in projects' settings module.
- TinyMCE form element cosmetic plugin.
- In the cosmetic image plugin, render the sized image.
- Add Armenian translation.
@ -467,7 +472,7 @@ Could haves
Would haves
===========
- Conditional inputs.
- Form wizards (combine forms with each other, having one at a step, finally -
+ Form wizards (combine forms with each other, having one at a step, finally -
send it all as one).
- Perhaps, completely re-write the base template for the foundation 5 theme?
- Make it possible to design a form based on existing models.

View file

@ -9,7 +9,7 @@ Subpackages
fobi.contrib.apps.djangocms_integration
fobi.contrib.apps.feincms_integration
fobi.contrib.apps.mezzanine_integration
fobi.contrib.apps.wagtail_integration
fobi.contrib.apps.wagtail_integration_
Module contents
---------------

View file

@ -12,6 +12,22 @@ fobi.contrib.plugins.form_elements.content.content_text.apps module
:undoc-members:
:show-inheritance:
fobi.contrib.plugins.form_elements.content.content_text.conf module
-------------------------------------------------------------------
.. automodule:: fobi.contrib.plugins.form_elements.content.content_text.conf
:members:
:undoc-members:
:show-inheritance:
fobi.contrib.plugins.form_elements.content.content_text.defaults module
-----------------------------------------------------------------------
.. automodule:: fobi.contrib.plugins.form_elements.content.content_text.defaults
:members:
:undoc-members:
:show-inheritance:
fobi.contrib.plugins.form_elements.content.content_text.fobi_form_elements module
---------------------------------------------------------------------------------
@ -28,6 +44,14 @@ fobi.contrib.plugins.form_elements.content.content_text.forms module
:undoc-members:
:show-inheritance:
fobi.contrib.plugins.form_elements.content.content_text.settings module
-----------------------------------------------------------------------
.. automodule:: fobi.contrib.plugins.form_elements.content.content_text.settings
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------

View file

@ -52,6 +52,14 @@ fobi.contrib.plugins.form_elements.fields.slider.forms module
:undoc-members:
:show-inheritance:
fobi.contrib.plugins.form_elements.fields.slider.helpers module
---------------------------------------------------------------
.. automodule:: fobi.contrib.plugins.form_elements.fields.slider.helpers
:members:
:undoc-members:
:show-inheritance:
fobi.contrib.plugins.form_elements.fields.slider.settings module
----------------------------------------------------------------

View file

@ -84,6 +84,30 @@ fobi.migrations.0010_formwizardhandler module
:undoc-members:
:show-inheritance:
fobi.migrations.0011_formentry_title module
-------------------------------------------
.. automodule:: fobi.migrations.0011_formentry_title
:members:
:undoc-members:
:show-inheritance:
fobi.migrations.0012_auto_20161109_1550 module
----------------------------------------------
.. automodule:: fobi.migrations.0012_auto_20161109_1550
:members:
:undoc-members:
:show-inheritance:
fobi.migrations.0013_formwizardentry_show_all_navigation_buttons module
-----------------------------------------------------------------------
.. automodule:: fobi.migrations.0013_formwizardentry_show_all_navigation_buttons
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------

View file

@ -10,8 +10,21 @@ handling the submitted form data).
Prerequisites
=============
- Django 1.5, 1.6, 1.7, 1.8, 1.9, 1.10
- Python >= 2.6.8, >= 2.7, >= 3.3
Current
-------
- Django 1.8, 1.9, 1.10
- Python >= 2.7, >= 3.3
Past
----
- Dropping support of Django 1.5, 1.6 has been announced in version
0.9.13. Dropping support of Django 1.7 has been announced in version 0.9.17.
As of 0.9.17 everything is still backwards compatible with versions 1.5, 1.6
and 1.7, but in future versions compatibility with these versions will be
wiped out.
- Dropping support of Python 2.6 has been announced in version 0.9.17.
As of 0.9.17 everything is still backwards compatible with Python 2.6, but
in future versions compatibility with it will be wiped out.
Key concepts
============
@ -89,7 +102,7 @@ Roadmap
=======
Some of the upcoming/in-development features/improvements are:
- Integration with `django-rest-framework` (in version 0.10).
- Integration with `django-rest-framework` (in version 0.11).
See the `TODOS <https://raw.githubusercontent.com/barseghyanartur/django-fobi/master/TODOS.rst>`_
for the full list of planned-, pending- in-development- or to-be-implemented
@ -416,12 +429,16 @@ following arguments:
- `request` (django.http.HttpRequest): The Django HTTP request.
- `form` (django.forms.Form): Form object (a valid one, which contains
the ``cleaned_data`` attribute).
- `form_element_entries` (fobi.models.FormElementEntry): Form element entries
for the `form_entry` given.
- (**)kwargs : Additional arguments.
Example (taken from fobi.contrib.plugins.form_elements.fields.file):
.. code-block:: python
def submit_plugin_form_data(self, form_entry, request, form):
def submit_plugin_form_data(self, form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data."""
# Get the file path
file_path = form.cleaned_data.get(self.data.name, None)
@ -1486,16 +1503,6 @@ README.rst file in directory of each plugin for details.
<https://github.com/barseghyanartur/django-fobi/tree/stable/src/fobi/contrib/plugins/form_handlers/mail/>`__:
Send the form data by email.
Limitations
-----------
- At the moment, if you have used `django-simple-captcha` or
`django-recaptcha` plugins in one of the forms of the wizard, the wizard
becomes invalid at the end and sends you back to the form which used
captcha (see the issue `here
<https://github.com/mbi/django-simple-captcha/issues/6>`__ and `here
<https://github.com/praekelt/django-recaptcha/issues/115>`__). Therefore,
you're not recommended to use captcha solutions in wizard forms (yet).
Permissions
===========
Plugin system allows administrators to specify the access rights to every
@ -1783,56 +1790,58 @@ Note, that you should not provide the `fobi_dynamic_values.` as a prefix.
Currently, the following variables are available in the
`fobi.context_processors.dynamic_values` context processor:
- request: Stripped HttpRequest object.
.. code-block:: text
- request.path: A string representing the full path to the requested page,
not including the scheme or domain.
- request: Stripped HttpRequest object.
- request.get_full_path(): Returns the path, plus an appended query string,
if applicable.
- request.path: A string representing the full path to the requested page,
not including the scheme or domain.
- request.is_secure(): Returns True if the request is secure; that is, if
it was made with HTTPS.
- request.get_full_path(): Returns the path, plus an appended query string,
if applicable.
- request.is_ajax(): Returns True if the request was made via an
XMLHttpRequest, by checking the HTTP_X_REQUESTED_WITH header for the
string 'XMLHttpRequest'.
- request.is_secure(): Returns True if the request is secure; that is, if
it was made with HTTPS.
- request.META: A stripped down standard Python dictionary containing the
available HTTP headers.
- request.is_ajax(): Returns True if the request was made via an
XMLHttpRequest, by checking the HTTP_X_REQUESTED_WITH header for the
string 'XMLHttpRequest'.
- HTTP_ACCEPT_ENCODING: Acceptable encodings for the response.
- request.META: A stripped down standard Python dictionary containing the
available HTTP headers.
- HTTP_ACCEPT_LANGUAGE: Acceptable languages for the response.
- HTTP_ACCEPT_ENCODING: Acceptable encodings for the response.
- HTTP_HOST: The HTTP Host header sent by the client.
- HTTP_ACCEPT_LANGUAGE: Acceptable languages for the response.
- HTTP_REFERER: The referring page, if any.
- HTTP_HOST: The HTTP Host header sent by the client.
- HTTP_USER_AGENT: The clients user-agent string.
- HTTP_REFERER: The referring page, if any.
- QUERY_STRING: The query string, as a single (unparsed) string.
- HTTP_USER_AGENT: The clients user-agent string.
- REMOTE_ADDR: The IP address of the client.
- QUERY_STRING: The query string, as a single (unparsed) string.
- request.user: Authenticated user.
- REMOTE_ADDR: The IP address of the client.
- request.user.email:
- request.user: Authenticated user.
- request.user.get_username(): Returns the username for the user. Since
the User model can be swapped out, you should use this method
instead of referencing the username attribute directly.
- request.user.email:
- request.user.get_full_name(): Returns the first_name plus the
last_name, with a space in between.
- request.user.get_username(): Returns the username for the user. Since
the User model can be swapped out, you should use this method
instead of referencing the username attribute directly.
- request.user.get_short_name(): Returns the first_name.
- request.user.get_full_name(): Returns the first_name plus the
last_name, with a space in between.
- request.user.is_anonymous():
- request.user.get_short_name(): Returns the first_name.
- now: datetime.datetime.now()
- request.user.is_anonymous():
- today: datetime.date.today()
- now: datetime.datetime.now()
- today: datetime.date.today()
Submitted form element plugins values
=====================================
@ -1985,6 +1994,51 @@ element- and form handler- plugins.
shown in case of missing form element handlers, set this to False in
your settings module. Default value is True.
Testing
=======
Project is covered by test (functional- and browser-tests).
To test with all supported Python/Django versions type:
.. code-block:: sh
tox
To test just your working environment type:
.. code-block:: sh
./runtests.py
It's assumed that you have all the requirements installed. If not, first
install the test requirements:
.. code-block:: sh
pip install -r examples/requirements/common_test_requirements.txt
Selenium
--------
Latest versions of Firefox are often not supported by Selenium. Current
version of the Selenium for Python (2.53.6) works fine with Firefox 47.
Thus, instead of using system Firefox you could better use a custom one.
Set up Firefox 47
~~~~~~~~~~~~~~~~~
1. Download Firefox 47 from
`this
<https://ftp.mozilla.org/pub/firefox/releases/47.0.1/linux-x86_64/en-GB/firefox-47.0.1.tar.bz2>`__
location and unzip it into ``/usr/lib/firefox47/``
2. Specify the full path to your Firefox in ``FIREFOX_BIN_PATH``
setting. Example:
.. code-block:: python
FIREFOX_BIN_PATH = '/usr/lib/firefox47/firefox'
After that your Selenium tests would work.
Troubleshooting
===============
If you get a ``FormElementPluginDoesNotExist`` or a

View file

@ -31,7 +31,6 @@ six==1.10.0
snowballstemmer==1.2.0
Sphinx==1.3.1
sphinx-rtd-theme==0.1.9
sqlparse==0.1.17
traitlets==4.0.0
#Unidecode==0.4.18
virtualenv==13.1.2

View file

@ -10,3 +10,4 @@ django-debug-toolbar==1.5
django-registration-redux>=1.4
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.2.2

View file

@ -11,3 +11,4 @@ django-localeurl>=2.0.2
django-registration-redux==1.2
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -11,3 +11,4 @@ django-localeurl>=2.0.2
django-registration-redux==1.2
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -7,6 +7,7 @@ django-debug-toolbar==0.11.0
django-localeurl>=2.0.2
#django-nine>=0.1.10
#django-nonefield>=0.1
django-registration-redux>=1.3
django-registration-redux==1.3
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -11,3 +11,4 @@ django-formtools
django-registration-redux>=1.4
#easy-thumbnails==2.3
#vishap>=0.1.5
sqlparse==0.1.9

View file

@ -3,7 +3,7 @@
Django>=1.9,<1.10
django-admin-tools>=0.7.1
django-autoslug==1.9.3
django-debug-toolbar==0.11.0
django-debug-toolbar==1.5
django-formtools==1.0
django-localeurl==2.0.2
django-nine>=0.1.10
@ -11,3 +11,4 @@ django-nonefield>=0.1
django-registration-redux>=1.4
easy-thumbnails==2.3
vishap>=0.1.5
sqlparse==0.2.2

View file

@ -0,0 +1,5 @@
-r django_1_9.txt
FeinCMS==1.12.1
django-mptt==0.8.6
django-tinymce==2.4.0

View file

@ -1,5 +1,5 @@
"""
This file was generated with the customdashboard management command, it
This file was generated with the custom dashboard management command, it
contains the two classes for the main dashboard and app index dashboard.
You can customize these classes as you want.
@ -7,83 +7,110 @@ To activate your index dashboard add the following to your settings.py::
ADMIN_TOOLS_INDEX_DASHBOARD = 'admin_tools_dashboard.CustomIndexDashboard'
And to activate the app index dashboard::
ADMIN_TOOLS_APP_INDEX_DASHBOARD = 'admin_tools_dashboard.CustomAppIndexDashboard'
ADMIN_TOOLS_APP_INDEX_DASHBOARD = \
'admin_tools_dashboard.CustomAppIndexDashboard'
"""
from django.conf import settings
from django.utils.translation import ugettext, ugettext_lazy as _
from django.utils.translation import ugettext_lazy as _
from admin_tools.dashboard import modules, Dashboard, AppIndexDashboard
from admin_tools.utils import get_admin_site_name
# from admin_tools.utils import get_admin_site_name
from . import conf
class CustomIndexDashboard(Dashboard):
"""
Custom index dashboard.
"""
"""Custom index dashboard."""
columns = 3
def init_with_context(self, context):
## Foo
#self.children.append(modules.ModelList(_('Foo'),
# models = conf.foo_apps,
# collapsible = False,
# deletable = False
#))
# Foo
# self.children.append(
# modules.ModelList(
# _('Foo'),
# models=conf.foo_apps,
# collapsible=False,
# deletable=False
# )
# )
# Fobi
self.children.append(modules.Group(
title = _('Fobi'),
display = 'stacked',
children = [
modules.ModelList(_('Plugins'), models=conf.fobi_plugins, collapsible=False, deletable=False),
modules.ModelList(_('Forms'), models=conf.fobi_forms, collapsible=False, deletable=False),
modules.ModelList(_('Data'), models=conf.fobi_data, collapsible=False, deletable=False),
]
))
self.children.append(
modules.Group(
title=_('Fobi'),
display='stacked',
children=[
modules.ModelList(
_('Plugins'),
models=conf.fobi_plugins,
collapsible=False,
deletable=False
),
modules.ModelList(
_('Forms'),
models=conf.fobi_forms,
collapsible=False,
deletable=False
),
modules.ModelList(
_('Data'),
models=conf.fobi_data,
collapsible=False,
deletable=False
),
]
)
)
if 'feincms' in settings.INSTALLED_APPS:
# FeinCMS pages
self.children.append(modules.AppList(
_('FeinCMS Pages'),
models = conf.feincms_pages,
collapsible = False,
deletable = False
))
self.children.append(
modules.AppList(
_('FeinCMS Pages'),
models=conf.feincms_pages,
collapsible=False,
deletable=False
)
)
if 'cms' in settings.INSTALLED_APPS:
# DjangoCMS pages
self.children.append(modules.AppList(
_('DjangoCMS Pages'),
models = conf.djangocms_pages,
collapsible = False,
deletable = False
))
self.children.append(
modules.AppList(
_('DjangoCMS Pages'),
models=conf.djangocms_pages,
collapsible=False,
deletable=False
)
)
# Append an app list module for "Administration"
self.children.append(modules.AppList(
_('Administration'),
models = conf.django_contrib_apps,
collapsible = False,
deletable = False
))
self.children.append(
modules.AppList(
_('Administration'),
models=conf.django_contrib_apps,
collapsible=False,
deletable=False
)
)
# Append an app list module for "Administration"
self.children.append(modules.AppList(
_('Other apps'),
models = conf.other_apps,
collapsible = False,
deletable = False
))
self.children.append(
modules.AppList(
_('Other apps'),
models=conf.other_apps,
collapsible=False,
deletable=False
)
)
# Append a recent actions module
self.children.append(modules.RecentActions(_('Recent Actions'), 10))
class CustomAppIndexDashboard(AppIndexDashboard):
"""
Custom app index dashboard for netcommunities.
"""
"""Custom app index dashboard."""
# We disable title because its redundant with the model list module
title = ''
@ -91,14 +118,14 @@ class CustomAppIndexDashboard(AppIndexDashboard):
def __init__(self, *args, **kwargs):
AppIndexDashboard.__init__(self, *args, **kwargs)
self.children.append(modules.RecentActions(
self.children.append(
modules.RecentActions(
_('Recent Actions'),
include_list=self.get_app_content_types(),
limit=10
))
)
)
def init_with_context(self, context):
"""
Use this method if you need to access the request context.
"""
"""Use this method if you need to access the request context."""
return super(CustomAppIndexDashboard, self).init_with_context(context)

View file

@ -2,19 +2,23 @@
# ************ Foo **************
# *******************************
foo_apps = [
'foo.models.*', 'bar.models.*',
'foo.models.*',
'bar.models.*',
]
# *******************************
# ************ Fobi *************
# *******************************
fobi_plugins = [
'fobi.models.FormElement', 'fobi.models.FormHandler'
'fobi.models.FormElement',
'fobi.models.FormHandler'
]
fobi_forms = [
'fobi.models.FormWizardEntry', 'fobi.models.FormEntry',
'fobi.models.FormElementEntry', 'fobi.models.FormFieldsetEntry',
'fobi.models.FormWizardEntry',
'fobi.models.FormEntry',
'fobi.models.FormElementEntry',
'fobi.models.FormFieldsetEntry',
'fobi.models.FormHandlerEntry',
]
@ -33,5 +37,7 @@ djangocms_pages = [
# *******************************
# ************ Django ***********
# *******************************
django_contrib_apps = ['django.contrib.*',]
django_contrib_apps = [
'django.contrib.*',
]
other_apps = foo_apps

View file

@ -27,39 +27,50 @@ class CustomMenu(Menu):
]
# Foo
self.children.append(items.ModelList(_('Foo'),
models=conf.foo_apps
))
self.children.append(
items.ModelList(
_('Foo'),
models=conf.foo_apps
)
)
# Fobi
self.children.append(items.MenuItem(
_('Fobi'),
children=[
items.ModelList(_('Plugins'), models=conf.fobi_plugins),
items.ModelList(_('Forms'), models=conf.fobi_forms),
items.ModelList(_('Data'), models=conf.fobi_data),
]
))
self.children.append(
items.MenuItem(
_('Fobi'),
children=[
items.ModelList(_('Plugins'), models=conf.fobi_plugins),
items.ModelList(_('Forms'), models=conf.fobi_forms),
items.ModelList(_('Data'), models=conf.fobi_data),
]
)
)
if 'feincms' in settings.INSTALLED_APPS:
# FeinCMS pages integration
self.children.append(items.AppList(
_('FeinCMS Pages'),
models=conf.feincms_pages
))
self.children.append(
items.AppList(
_('FeinCMS Pages'),
models=conf.feincms_pages
)
)
if 'cms' in settings.INSTALLED_APPS:
# DjangoCMS pages integration
self.children.append(items.AppList(
_('DjangoCMS Pages'),
models=conf.djangocms_pages
))
self.children.append(
items.AppList(
_('DjangoCMS Pages'),
models=conf.djangocms_pages
)
)
# append an app list module for "Administration"
self.children.append(items.AppList(
_('Administration'),
models=['django.contrib.*',]
))
self.children.append(
items.AppList(
_('Administration'),
models=['django.contrib.*']
)
)
def init_with_context(self, context):
"""Use this method if you need to access the request context."""

View file

@ -19,7 +19,7 @@ class Genre(MPTTModel):
"""MPTT meta."""
# level_attr = 'mptt_level'
order_insertion_by=['name']
order_insertion_by = ['name']
def __str__(self):
return self.name

View file

@ -1,6 +1,13 @@
__all__ = ('disable_admin_tools',)
from django.conf import settings
__all__ = ('disable_admin_tools', 'testing',)
def disable_admin_tools(request):
"""Disable admin tools."""
return {'ADMIN_TOOLS_DISABLED': True}
def testing(request):
"""Put `testing` into context."""
return {'testing': settings.TESTING}

View file

@ -1 +1 @@
from customauth.models import MyUser
from .models import MyUser

View file

@ -93,11 +93,9 @@ class MyUserAdmin(UserAdmin):
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'first_name', 'last_name',
'date_of_birth', 'password1', 'password2')}
)
(None, {'classes': ('wide',),
'fields': ('username', 'email', 'first_name', 'last_name',
'date_of_birth', 'password1', 'password2')}),
)
search_fields = ('email',)
ordering = ('email',)

View file

@ -13,7 +13,7 @@ from fobi.constants import (
logger = logging.getLogger('fobi')
__all__= (
__all__ = (
'SaveAsFooItem',
'DummyInvalidCallback',
)

View file

@ -38,7 +38,8 @@ class RadioInputPlugin(FormFieldPlugin):
return [(self.data.name, ChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
def submit_plugin_form_data(self, form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data/process.
:param fobi.models.FormEntry form_entry: Instance of

View file

@ -40,7 +40,8 @@ class SelectModelObjectInputPlugin(FormFieldPlugin):
return [(self.data.name, ModelChoiceField, field_kwargs)]
def submit_plugin_form_data(self, form_entry, request, form):
def submit_plugin_form_data(self, form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data/process.
:param fobi.models.FormEntry form_entry: Instance of

View file

@ -8,7 +8,7 @@ __all__ = ('MySimpleTheme',)
class MySimpleTheme(SimpleTheme):
"""Overriding the "simple" theme."""
html_classes = ['my-simple-theme',]
html_classes = ['my-simple-theme']
base_view_template = 'override_simple_theme/base_view.html'
form_ajax = 'override_simple_theme/snippets/form_ajax.html'
form_snippet_template_name = \

View file

@ -1,133 +1,116 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
# Generated by Django 1.9.10 on 2016-10-17 20:45
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import feincms.contrib.richtext
import feincms.extensions.base
import feincms.module.mixins
import fobi.integration.processors
class Migration(SchemaMigration):
class Migration(migrations.Migration):
def forwards(self, orm):
# Adding model 'Page'
db.create_table(u'page_page', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
(u'lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
('slug', self.gf('django.db.models.fields.SlugField')(max_length=150)),
('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name=u'children', null=True, to=orm['page.Page'])),
('in_navigation', self.gf('django.db.models.fields.BooleanField')(default=False)),
('override_url', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('redirect_to', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('_cached_url', self.gf('django.db.models.fields.CharField')(default=u'', max_length=255, db_index=True, blank=True)),
(u'template_key', self.gf('django.db.models.fields.CharField')(default='page_base', max_length=255)),
))
db.send_create_signal(u'page', ['Page'])
initial = True
# Adding model 'FobiFormWidget'
db.create_table(u'page_page_fobiformwidget', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('form_entry', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['fobi.FormEntry'])),
(u'parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name=u'fobiformwidget_set', to=orm['page.Page'])),
(u'region', self.gf('django.db.models.fields.CharField')(max_length=255)),
(u'ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal(u'page', ['FobiFormWidget'])
dependencies = [
('fobi', '0010_formwizardhandler'),
]
def backwards(self, orm):
# Deleting model 'Page'
db.delete_table(u'page_page')
# Deleting model 'FobiFormWidget'
db.delete_table(u'page_page_fobiformwidget')
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'})
},
u'fobi.formentry': {
'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormEntry'},
'form_wizard_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormWizardEntry']", 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'position': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'fobi.formwizardentry': {
'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormWizardEntry'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'page.fobiformwidget': {
'Meta': {'ordering': "[u'ordering']", 'object_name': 'FobiFormWidget', 'db_table': "u'page_page_fobiformwidget'"},
'form_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormEntry']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
u'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
u'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'fobiformwidget_set'", 'to': u"orm['page.Page']"}),
u'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
u'page.page': {
'Meta': {'ordering': "[u'tree_id', u'lft']", 'object_name': 'Page'},
'_cached_url': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'db_index': 'True', 'blank': 'True'}),
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'override_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'children'", 'null': 'True', 'to': u"orm['page.Page']"}),
'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150'}),
u'template_key': ('django.db.models.fields.CharField', [], {'default': "'page_base'", 'max_length': '255'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
}
}
complete_apps = ['page']
operations = [
migrations.CreateModel(
name='FobiFormWidget',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('form_template_name', models.CharField(blank=True, choices=[(b'fobi/bootstrap3_extras/view_embed_form_entry_ajax.html', b'Custom bootstrap3 embed form view template')], help_text='Template to render the form with.', max_length=255, null=True, verbose_name='Form template name')),
('hide_form_title', models.BooleanField(default=False, help_text='If checked, no form title is shown.', verbose_name='Hide form title')),
('form_title', models.CharField(blank=True, help_text='Overrides the default form title.', max_length=255, null=True, verbose_name='Form title')),
('form_submit_button_text', models.CharField(blank=True, help_text='Overrides the default form submit button text.', max_length=255, null=True, verbose_name='Submit button text')),
('success_page_template_name', models.CharField(blank=True, choices=[(b'fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html', b'Custom bootstrap3 embed form entry submitted template')], help_text='Template to render the success page with.', max_length=255, null=True, verbose_name='Success page template name')),
('hide_success_page_title', models.BooleanField(default=False, help_text='If checked, no success page title is shown.', verbose_name='Hide success page title')),
('success_page_title', models.CharField(blank=True, help_text='Overrides the default success page title.', max_length=255, null=True, verbose_name='Succes page title')),
('success_page_text', models.TextField(blank=True, help_text='Overrides the default success page text.', null=True, verbose_name='Succes page text')),
('region', models.CharField(max_length=255)),
('ordering', models.IntegerField(default=0, verbose_name='ordering')),
('form_entry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fobi.FormEntry', verbose_name='Form')),
],
options={
'ordering': ['ordering'],
'abstract': False,
'verbose_name_plural': 'fobi form widgets',
'db_table': 'page_page_fobiformwidget',
'verbose_name': 'fobi form widget',
'permissions': [],
},
bases=(models.Model, fobi.integration.processors.IntegrationProcessor),
),
migrations.CreateModel(
name='Page',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('active', models.BooleanField(default=True, verbose_name='active')),
('title', models.CharField(help_text='This title is also used for navigation menu items.', max_length=200, verbose_name='title')),
('slug', models.SlugField(help_text='This is used to build the URL for this page', max_length=150, verbose_name='slug')),
('in_navigation', models.BooleanField(default=False, verbose_name='in navigation')),
('override_url', models.CharField(blank=True, help_text="Override the target URL. Be sure to include slashes at the beginning and at the end if it is a local URL. This affects both the navigation and subpages' URLs.", max_length=255, verbose_name='override URL')),
('redirect_to', models.CharField(blank=True, help_text='Target URL for automatic redirects or the primary key of a page.', max_length=255, verbose_name='redirect to')),
('_cached_url', models.CharField(blank=True, db_index=True, default='', editable=False, max_length=255, verbose_name='Cached URL')),
('lft', models.PositiveIntegerField(db_index=True, editable=False)),
('rght', models.PositiveIntegerField(db_index=True, editable=False)),
('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
('level', models.PositiveIntegerField(db_index=True, editable=False)),
('language', models.CharField(choices=[(b'en', b'English'), (b'hy', b'Armenian'), (b'nl', b'Dutch'), (b'ru', b'Russian'), (b'de', b'German')], default=b'en', max_length=10, verbose_name='language')),
('template_key', models.CharField(choices=[(b'page_base', 'Base template')], default=b'page_base', max_length=255, verbose_name='template')),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='page.Page', verbose_name='Parent')),
('translation_of', models.ForeignKey(blank=True, help_text='Leave this empty for entries in the primary language.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='page.Page', verbose_name='translation of')),
],
options={
'ordering': ['tree_id', 'lft'],
'verbose_name': 'page',
'verbose_name_plural': 'pages',
},
bases=(models.Model, feincms.extensions.base.ExtensionsMixin, feincms.module.mixins.ContentModelMixin),
),
migrations.CreateModel(
name='RawContent',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField(blank=True, verbose_name='content')),
('region', models.CharField(max_length=255)),
('ordering', models.IntegerField(default=0, verbose_name='ordering')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rawcontent_set', to='page.Page')),
],
options={
'ordering': ['ordering'],
'abstract': False,
'verbose_name_plural': 'raw contents',
'db_table': 'page_page_rawcontent',
'verbose_name': 'raw content',
'permissions': [],
},
),
migrations.CreateModel(
name='RichTextContent',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('region', models.CharField(max_length=255)),
('ordering', models.IntegerField(default=0, verbose_name='ordering')),
('text', feincms.contrib.richtext.RichTextField(blank=True, verbose_name='text')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='richtextcontent_set', to='page.Page')),
],
options={
'ordering': ['ordering'],
'abstract': False,
'verbose_name_plural': 'rich texts',
'db_table': 'page_page_richtextcontent',
'verbose_name': 'rich text',
'permissions': [],
},
),
migrations.AddField(
model_name='fobiformwidget',
name='parent',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fobiformwidget_set', to='page.Page'),
),
]

View file

@ -0,0 +1,133 @@
# -*- 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 'Page'
db.create_table(u'page_page', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
(u'lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
('slug', self.gf('django.db.models.fields.SlugField')(max_length=150)),
('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name=u'children', null=True, to=orm['page.Page'])),
('in_navigation', self.gf('django.db.models.fields.BooleanField')(default=False)),
('override_url', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('redirect_to', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('_cached_url', self.gf('django.db.models.fields.CharField')(default=u'', max_length=255, db_index=True, blank=True)),
(u'template_key', self.gf('django.db.models.fields.CharField')(default='page_base', max_length=255)),
))
db.send_create_signal(u'page', ['Page'])
# Adding model 'FobiFormWidget'
db.create_table(u'page_page_fobiformwidget', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('form_entry', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['fobi.FormEntry'])),
(u'parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name=u'fobiformwidget_set', to=orm['page.Page'])),
(u'region', self.gf('django.db.models.fields.CharField')(max_length=255)),
(u'ordering', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal(u'page', ['FobiFormWidget'])
def backwards(self, orm):
# Deleting model 'Page'
db.delete_table(u'page_page')
# Deleting model 'FobiFormWidget'
db.delete_table(u'page_page_fobiformwidget')
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'})
},
u'fobi.formentry': {
'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormEntry'},
'form_wizard_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormWizardEntry']", 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'position': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'fobi.formwizardentry': {
'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormWizardEntry'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
},
u'page.fobiformwidget': {
'Meta': {'ordering': "[u'ordering']", 'object_name': 'FobiFormWidget', 'db_table': "u'page_page_fobiformwidget'"},
'form_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormEntry']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
u'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
u'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'fobiformwidget_set'", 'to': u"orm['page.Page']"}),
u'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
u'page.page': {
'Meta': {'ordering': "[u'tree_id', u'lft']", 'object_name': 'Page'},
'_cached_url': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'db_index': 'True', 'blank': 'True'}),
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'override_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'children'", 'null': 'True', 'to': u"orm['page.Page']"}),
'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150'}),
u'template_key': ('django.db.models.fields.CharField', [], {'default': "'page_base'", 'max_length': '255'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
}
}
complete_apps = ['page']

View file

@ -0,0 +1 @@
./manage.py runserver 0.0.0.0:8000 --traceback -v 3 --settings=settings.bootstrap3_theme_django_1_9_captcha --traceback -v 3

View file

@ -0,0 +1 @@
./manage.py runserver 0.0.0.0:8000 --traceback -v 3 --settings=settings.bootstrap3_theme_django_1_7_feincms --traceback -v 3

View file

@ -0,0 +1 @@
./manage.py runserver 0.0.0.0:8001 --traceback -v 3 --settings=settings.foundation5_theme_django_1_10 --traceback -v 3

View file

@ -0,0 +1 @@
./manage.py runserver 0.0.0.0:8001 --traceback -v 3 --settings=settings.foundation5_theme_django_1_8 --traceback -v 3

View file

@ -0,0 +1 @@
./manage.py runserver 0.0.0.0:8001 --traceback -v 3 --settings=settings.foundation5_theme_django_1_9 --traceback -v 3

View file

@ -4,8 +4,18 @@ from nine.versions import (
DJANGO_GTE_1_7, DJANGO_GTE_1_8, DJANGO_LTE_1_7, DJANGO_GTE_1_9,
DJANGO_GTE_1_10
)
PROJECT_DIR = lambda base : os.path.abspath(os.path.join(os.path.dirname(__file__), base).replace('\\','/'))
gettext = lambda s: s
def project_dir(base):
return os.path.abspath(
os.path.join(os.path.dirname(__file__), base).replace('\\', '/')
)
PROJECT_DIR = project_dir
def gettext(s):
return s
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
@ -22,13 +32,18 @@ MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': PROJECT_DIR('../../db/example.db'), # Or path to database file if using sqlite3.
# Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'ENGINE': 'django.db.backends.sqlite3',
# Or path to database file if using sqlite3.
'NAME': PROJECT_DIR('../../db/example.db'),
# The following settings are not used with sqlite3:
'USER': '',
'PASSWORD': '',
'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
# Empty for localhost through domain sockets or '127.0.0.1' for
# localhost through TCP.
'HOST': '',
# Set to empty string for default.
'PORT': '',
}
}
@ -47,7 +62,7 @@ TIME_ZONE = 'America/Chicago'
LANGUAGE_CODE = 'en'
LANGUAGES = (
('en', gettext("English")), # Main language!
('en', gettext("English")), # Main language!
('hy', gettext("Armenian")),
('nl', gettext("Dutch")),
('ru', gettext("Russian")),
@ -67,7 +82,8 @@ USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Absolute filesystem path to the directory that will hold user-uploaded
# files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = PROJECT_DIR(os.path.join('..', '..', 'media'))
@ -105,12 +121,17 @@ STATICFILES_FINDERS = (
# Make this unique, and don't share it with anybody.
SECRET_KEY = '97818c*w97Zi8a-m^1coRRrmurMI6+q5_kyn*)s@(*_Pk6q423'
try:
from .local_settings import DEBUG_TEMPLATE
except Exception as err:
DEBUG_TEMPLATE = False
if DJANGO_GTE_1_10:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'APP_DIRS': True,
'DIRS': [PROJECT_DIR(os.path.join('..', 'templates')),],
'DIRS': [PROJECT_DIR(os.path.join('..', 'templates'))],
'OPTIONS': {
'context_processors': [
"django.template.context_processors.debug",
@ -123,6 +144,7 @@ if DJANGO_GTE_1_10:
"django.contrib.messages.context_processors.messages",
"fobi.context_processors.theme", # Important!
"fobi.context_processors.dynamic_values", # Optional
"context_processors.testing", # Testing
],
'loaders': [
'django.template.loaders.filesystem.Loader',
@ -130,7 +152,7 @@ if DJANGO_GTE_1_10:
'django.template.loaders.eggs.Loader',
'admin_tools.template_loaders.Loader',
],
'debug': DEBUG,
'debug': DEBUG_TEMPLATE,
}
},
]
@ -139,7 +161,7 @@ elif DJANGO_GTE_1_8:
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'APP_DIRS': True,
'DIRS': [PROJECT_DIR(os.path.join('..', 'templates')),],
'DIRS': [PROJECT_DIR(os.path.join('..', 'templates'))],
'OPTIONS': {
'context_processors': [
"django.contrib.auth.context_processors.auth",
@ -150,8 +172,9 @@ elif DJANGO_GTE_1_8:
"django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.request",
"fobi.context_processors.theme", # Important!
"fobi.context_processors.dynamic_values", # Optional
"fobi.context_processors.theme", # Important!
"fobi.context_processors.dynamic_values", # Optional
"context_processors.testing", # Testing
],
'loaders': [
'django.template.loaders.filesystem.Loader',
@ -159,14 +182,15 @@ elif DJANGO_GTE_1_8:
'django.template.loaders.eggs.Loader',
'admin_tools.template_loaders.Loader',
],
'debug': DEBUG,
'debug': DEBUG_TEMPLATE,
}
},
]
else:
TEMPLATE_DEBUG = DEBUG
TEMPLATE_DEBUG = DEBUG_TEMPLATE
# List of callables that know how to import templates from various sources.
# 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',
@ -185,12 +209,14 @@ else:
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
"fobi.context_processors.theme", # Important!
"fobi.context_processors.dynamic_values", # Optional
"fobi.context_processors.theme", # Important!
"fobi.context_processors.dynamic_values", # Optional
"context_processors.testing", # Testing
)
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# 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.
PROJECT_DIR(os.path.join('..', 'templates')),
@ -198,7 +224,6 @@ else:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
# 'localeurl.middleware.LocaleURLMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -207,9 +232,6 @@ MIDDLEWARE_CLASSES = [
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# if DJANGO_GTE_1_8:
# MIDDLEWARE_CLASSES.remove('localeurl.middleware.LocaleURLMiddleware')
ROOT_URLCONF = 'urls'
# Python dotted path to the WSGI application used by Django's runserver.
@ -240,7 +262,6 @@ INSTALLED_APPS = [
# 'tinymce', # TinyMCE
'easy_thumbnails', # Thumbnailer
'registration', # Auth views and registration app
# 'localeurl', # Locale URL
# ***********************************************************************
# ***********************************************************************
@ -334,17 +355,23 @@ INSTALLED_APPS = [
# ***********************************************************************
'fobi.contrib.themes.bootstrap3', # Bootstrap 3 theme
# DateTime widget
'fobi.contrib.themes.bootstrap3.widgets.form_elements.datetime_bootstrap3_widget',
'fobi.contrib.themes.bootstrap3.widgets.form_elements.date_bootstrap3_widget',
'fobi.contrib.themes.bootstrap3.widgets.form_elements.'
'datetime_bootstrap3_widget',
'fobi.contrib.themes.bootstrap3.widgets.form_elements.'
'date_bootstrap3_widget',
# SliderPercentage widget
'fobi.contrib.themes.bootstrap3.widgets.form_elements.slider_bootstrap3_widget',
'fobi.contrib.themes.bootstrap3.widgets.form_elements.'
'slider_bootstrap3_widget',
# ***********************************************************************
# ************************ Foundation 5 theme ***************************
# ***********************************************************************
'fobi.contrib.themes.foundation5', # Foundation 5 theme
'fobi.contrib.themes.foundation5.widgets.form_handlers.db_store_foundation5_widget',
'fobi.contrib.themes.foundation5.widgets.form_handlers.'
'db_store_foundation5_widget',
# ***********************************************************************
# **************************** Simple theme *****************************
@ -369,9 +396,6 @@ INSTALLED_APPS = [
if DJANGO_LTE_1_7:
INSTALLED_APPS.append('south')
# if DJANGO_GTE_1_8:
# INSTALLED_APPS.remove('localeurl')
# LOGIN_URL = '/accounts/login/'
# LOGIN_REDIRECT_URL = '/fobi/' # Important for passing the selenium tests
@ -379,23 +403,12 @@ if DJANGO_LTE_1_7:
LOGIN_URL = '/en/accounts/login/'
LOGIN_REDIRECT_URL = '/en/fobi/' # Important for passing the selenium tests
#LOGIN_URL = '/accounts/login/'
#LOGIN_ERROR_URL = '/accounts/login/'
#LOGOUT_URL = '/accounts/logout/'
# LOGIN_URL = '/accounts/login/'
# LOGIN_ERROR_URL = '/accounts/login/'
# LOGOUT_URL = '/accounts/logout/'
# if not DJANGO_GTE_1_8:
# # Tell localeurl to use sessions for language store.
# LOCALEURL_USE_SESSION = True
#
# # localeurl locale independent paths (language code won't be appended)
# LOCALE_INDEPENDENT_PATHS = (
# r'^/sitemap.*\.xml$', # Global regex for all XML sitemaps
# r'^/admin/',
# #r'^/dashboard/',
# )
PACKAGE_NAME_FILEBROWSER = "filebrowser_safe" # Just for tests
PACKAGE_NAME_GRAPPELLI = "grappelli_safe" # Just for tests
PACKAGE_NAME_FILEBROWSER = "filebrowser_safe" # Just for tests
PACKAGE_NAME_GRAPPELLI = "grappelli_safe" # Just for tests
MIGRATION_MODULES = {
'fobi': 'migrations',
@ -426,8 +439,10 @@ FOBI_CUSTOM_THEME_DATA = {
],
'success_page_template_choices': [
(
'fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html',
gettext("Custom bootstrap3 embed form entry submitted template")
'fobi/bootstrap3_extras/embed_form_entry_'
'submitted_ajax.html',
gettext("Custom bootstrap3 embed form entry submitted "
"template")
),
],
},
@ -440,8 +455,10 @@ FOBI_CUSTOM_THEME_DATA = {
],
'success_page_template_choices': [
(
'fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html',
gettext("Custom bootstrap3 embed form entry submitted template")
'fobi/bootstrap3_extras/embed_form_entry_submitted_'
'ajax.html',
gettext("Custom bootstrap3 embed form entry submitted "
"template")
),
],
},
@ -462,8 +479,10 @@ FOBI_CUSTOM_THEME_DATA = {
],
'success_page_template_choices': [
(
'fobi/foundation5_extras/embed_form_entry_submitted_ajax.html',
gettext("Custom foundation5 embed form entry submitted template")
'fobi/foundation5_extras/embed_form_entry_submitted_'
'ajax.html',
gettext("Custom foundation5 embed form entry submitted "
"template")
),
],
},
@ -476,8 +495,10 @@ FOBI_CUSTOM_THEME_DATA = {
],
'success_page_template_choices': [
(
'fobi/foundation5_extras/embed_form_entry_submitted_ajax.html',
gettext("Custom foundation5 embed form entry submitted template")
'fobi/foundation5_extras/embed_form_entry_submitted_'
'ajax.html',
gettext("Custom foundation5 embed form entry submitted "
"template")
),
],
},
@ -500,7 +521,8 @@ FOBI_THEME_FOOTER_TEXT = gettext('&copy; django-fobi example site 2014-2015')
# django-admin-tools custom dashboard
ADMIN_TOOLS_INDEX_DASHBOARD = 'admin_tools_dashboard.CustomIndexDashboard'
ADMIN_TOOLS_APP_INDEX_DASHBOARD = 'admin_tools_dashboard.CustomAppIndexDashboard'
ADMIN_TOOLS_APP_INDEX_DASHBOARD = \
'admin_tools_dashboard.CustomAppIndexDashboard'
ADMIN_TOOLS_MENU = 'admin_tools_dashboard.menu.CustomMenu'
SOUTH_MIGRATION_MODULES = {
@ -532,7 +554,8 @@ LOGGING = {
},
'formatters': {
'verbose': {
'format': '\n%(levelname)s %(asctime)s [%(pathname)s:%(lineno)s] %(message)s'
'format': '\n%(levelname)s %(asctime)s [%(pathname)s:%(lineno)s] '
'%(message)s'
},
'simple': {
'format': '\n%(levelname)s %(message)s'
@ -550,32 +573,32 @@ LOGGING = {
'formatter': 'verbose'
},
'all_log': {
'level':'DEBUG',
'class':'logging.handlers.RotatingFileHandler',
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/all.log"),
'maxBytes': 1048576,
'backupCount': 99,
'formatter': 'verbose',
},
'django_log': {
'level':'DEBUG',
'class':'logging.handlers.RotatingFileHandler',
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/django.log"),
'maxBytes': 1048576,
'backupCount': 99,
'formatter': 'verbose',
},
'django_request_log': {
'level':'DEBUG',
'class':'logging.handlers.RotatingFileHandler',
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/django_request.log"),
'maxBytes': 1048576,
'backupCount': 99,
'formatter': 'verbose',
},
'fobi_log': {
'level':'DEBUG',
'class':'logging.handlers.RotatingFileHandler',
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/fobi.log"),
'maxBytes': 1048576,
'backupCount': 99,
@ -630,6 +653,9 @@ if DJANGO_GTE_1_7 or DJANGO_GTE_1_8:
# For Selenium tests
FIREFOX_BIN_PATH = ''
# Testing mode
TESTING = False
# Do not put any settings below this line
try:
from .local_settings import *
@ -660,7 +686,7 @@ if DEBUG:
try:
# Make sure the django-template-debug is installed. You can then
# in templates use it as follows:
#
#
# {% load debug_tags %}
# {% set_trace %}
import template_debug

View file

@ -4,8 +4,10 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.append('captcha')
INSTALLED_APPS.append('fobi.contrib.plugins.form_elements.security.captcha')
INSTALLED_APPS.append(
'fobi.contrib.plugins.form_elements.security.captcha'
)
except Exception as e:
pass
#FOBI_DEFAULT_THEME = 'simple'
# FOBI_DEFAULT_THEME = 'simple'

View file

@ -5,8 +5,7 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
INSTALLED_APPS.remove('localeurl') if 'localeurl' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
try:
@ -16,5 +15,5 @@ try:
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass

View file

@ -6,6 +6,8 @@ try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
INSTALLED_APPS.append('captcha')
INSTALLED_APPS.append('fobi.contrib.plugins.form_elements.security.captcha')
INSTALLED_APPS.append(
'fobi.contrib.plugins.form_elements.security.captcha'
)
except Exception as e:
pass

View file

@ -2,40 +2,40 @@ from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS += [
'cms', # DjangoCMS
'cms', # DjangoCMS
'mptt',
'menus',
'sekizai',
#'djangocms_admin_style',
# 'djangocms_admin_style',
# Some plugins
'djangocms_picture',
'djangocms_snippet',
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
#'djangocms_page', # Example
# 'djangocms_page', # Example
]
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
#INSTALLED_APPS.remove('admin_tools') \
# INSTALLED_APPS.remove('admin_tools') \
# if 'admin_tools' in INSTALLED_APPS else None
#INSTALLED_APPS.remove('admin_tools.menu') \
# INSTALLED_APPS.remove('admin_tools.menu') \
# if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
MIDDLEWARE_CLASSES += [
#'django.middleware.cache.UpdateCacheMiddleware',
# 'django.middleware.cache.UpdateCacheMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
#'django.middleware.cache.FetchFromCacheMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
]
TEMPLATE_CONTEXT_PROCESSORS = list(TEMPLATE_CONTEXT_PROCESSORS)
@ -46,8 +46,8 @@ TEMPLATE_CONTEXT_PROCESSORS += [
]
FOBI_DEFAULT_THEME = 'bootstrap3'
#FOBI_DEFAULT_THEME = 'foundation5'
#FOBI_DEFAULT_THEME = 'simple'
# FOBI_DEFAULT_THEME = 'foundation5'
# FOBI_DEFAULT_THEME = 'simple'
CMS_TEMPLATES = (
('cms_page/{0}/page_with_sidebar.html'.format(FOBI_DEFAULT_THEME),
@ -63,6 +63,6 @@ MIGRATION_MODULES = {
LANGUAGE_CODE = 'en'
#FEINCMS_RICHTEXT_INIT_CONTEXT = {
# FEINCMS_RICHTEXT_INIT_CONTEXT = {
# 'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js',
#}
# }

View file

@ -4,17 +4,19 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
#INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') if 'admin_tools.dashboard' in INSTALLED_APPS else None
# INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS \
else None
INSTALLED_APPS += [
'feincms', # FeinCMS
'feincms', # FeinCMS
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'page', # Example
'page', # Example
]
except Exception as e:
except Exception as err:
pass

View file

@ -5,7 +5,7 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
try:
@ -15,5 +15,5 @@ try:
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass

View file

@ -0,0 +1,13 @@
from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
INSTALLED_APPS.append('captcha')
INSTALLED_APPS.append(
'fobi.contrib.plugins.form_elements.security.captcha'
)
except Exception as err:
pass

View file

@ -0,0 +1,30 @@
from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
# INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS \
else None
INSTALLED_APPS += [
'feincms', # FeinCMS
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'page', # Example
]
except Exception as e:
pass
FEINCMS_RICHTEXT_INIT_CONTEXT = {
'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js',
}
MIGRATION_MODULES = {
'fobi': 'fobi.migrations',
'db_store': 'fobi.contrib.plugins.form_handlers.db_store.migrations',
}

View file

@ -2,39 +2,39 @@ from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS += [
'cms', # DjangoCMS
'cms', # DjangoCMS
'mptt',
'menus',
'sekizai',
#'djangocms_admin_style',
# 'djangocms_admin_style',
# Some plugins
'djangocms_picture',
'djangocms_snippet',
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
#'djangocms_page', # Example
# 'djangocms_page', # Example
]
try:
#INSTALLED_APPS.remove('admin_tools') \
# INSTALLED_APPS.remove('admin_tools') \
# if 'admin_tools' in INSTALLED_APPS else None
#INSTALLED_APPS.remove('admin_tools.menu') \
# INSTALLED_APPS.remove('admin_tools.menu') \
# if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
MIDDLEWARE_CLASSES += [
#'django.middleware.cache.UpdateCacheMiddleware',
# 'django.middleware.cache.UpdateCacheMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
#'django.middleware.cache.FetchFromCacheMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
]
TEMPLATE_CONTEXT_PROCESSORS = list(TEMPLATE_CONTEXT_PROCESSORS)
@ -45,8 +45,8 @@ TEMPLATE_CONTEXT_PROCESSORS += [
]
FOBI_DEFAULT_THEME = 'bootstrap3'
#FOBI_DEFAULT_THEME = 'foundation5'
#FOBI_DEFAULT_THEME = 'simple'
# FOBI_DEFAULT_THEME = 'foundation5'
# FOBI_DEFAULT_THEME = 'simple'
CMS_TEMPLATES = (
('cms_page/{0}/page_with_sidebar.html'.format(FOBI_DEFAULT_THEME),
@ -62,6 +62,6 @@ MIGRATION_MODULES = {
LANGUAGE_CODE = 'en'
#FEINCMS_RICHTEXT_INIT_CONTEXT = {
# FEINCMS_RICHTEXT_INIT_CONTEXT = {
# 'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js',
#}
# }

View file

@ -2,63 +2,68 @@ from .base import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': PROJECT_DIR('../db/example_djangocms_2.db'), # Or path to database file if using sqlite3.
# Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'ENGINE': 'django.db.backends.sqlite3',
# Or path to database file if using sqlite3.
'NAME': PROJECT_DIR('../db/example_djangocms_2.db'),
# The following settings are not used with sqlite3:
'USER': '',
'PASSWORD': '',
'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
'PORT': '', # Set to empty string for default.
# Empty for localhost through domain sockets or '127.0.0.1' for
# localhost through TCP.
'HOST': '',
# Set to empty string for default.
'PORT': '',
}
}
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS += [
'cms', # DjangoCMS
'cms', # DjangoCMS
'mptt',
'menus',
'sekizai',
#'djangocms_admin_style',
# 'djangocms_admin_style',
# Some plugins
'cms.plugins.picture',
'cms.plugins.snippet',
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
#'djangocms_page', # Example
# 'djangocms_page', # Example
]
try:
#INSTALLED_APPS.remove('admin_tools') \
# INSTALLED_APPS.remove('admin_tools') \
# if 'admin_tools' in INSTALLED_APPS else None
#INSTALLED_APPS.remove('admin_tools.menu') \
# INSTALLED_APPS.remove('admin_tools.menu') \
# if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
MIDDLEWARE_CLASSES += [
#'django.middleware.cache.UpdateCacheMiddleware',
# 'django.middleware.cache.UpdateCacheMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
#'django.middleware.cache.FetchFromCacheMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
]
TEMPLATE_CONTEXT_PROCESSORS = list(TEMPLATE_CONTEXT_PROCESSORS)
TEMPLATE_CONTEXT_PROCESSORS += [
'cms.context_processors.media',
'sekizai.context_processors.sekizai',
#'cms.context_processors.cms_settings',
# 'cms.context_processors.cms_settings',
]
FOBI_DEFAULT_THEME = 'bootstrap3'
#FOBI_DEFAULT_THEME = 'foundation5'
#FOBI_DEFAULT_THEME = 'simple'
# FOBI_DEFAULT_THEME = 'foundation5'
# FOBI_DEFAULT_THEME = 'simple'
CMS_TEMPLATES = (
('cms_page/{0}/page_with_sidebar.html'.format(FOBI_DEFAULT_THEME),
@ -74,6 +79,6 @@ MIGRATION_MODULES = {
LANGUAGE_CODE = 'en'
#FEINCMS_RICHTEXT_INIT_CONTEXT = {
# FEINCMS_RICHTEXT_INIT_CONTEXT = {
# 'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js',
#}
# }

View file

@ -2,18 +2,23 @@ from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS += [
'feincms', # FeinCMS
'feincms', # FeinCMS
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'page', # Example
'page', # Example
]
try:
#INSTALLED_APPS.remove('admin_tools') if 'admin_tools' in INSTALLED_APPS else None
#INSTALLED_APPS.remove('admin_tools.menu') if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
# INSTALLED_APPS.remove('admin_tools') \
# if 'admin_tools' in INSTALLED_APPS \
# else None
# INSTALLED_APPS.remove('admin_tools.menu') \
# if 'admin_tools.menu' in INSTALLED_APPS \
# else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
FEINCMS_RICHTEXT_INIT_CONTEXT = {

View file

@ -5,7 +5,13 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.append('mptt')
INSTALLED_APPS.append('bar')
INSTALLED_APPS.append('fobi.contrib.plugins.form_elements.fields.select_mptt_model_object')
INSTALLED_APPS.append('fobi.contrib.plugins.form_elements.fields.select_multiple_mptt_model_objects')
except Exception as e:
INSTALLED_APPS.append(
'fobi.contrib.plugins.form_elements.fields.'
'select_mptt_model_object'
)
INSTALLED_APPS.append(
'fobi.contrib.plugins.form_elements.fields.'
'select_multiple_mptt_model_objects'
)
except Exception as err:
pass

View file

@ -5,7 +5,7 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
try:
@ -15,11 +15,12 @@ try:
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as e:
except Exception as err:
pass
#INSTALLED_APPS.remove('fobi.contrib.plugins.form_handlers.http_repost')
#INSTALLED_APPS.remove('fobi.contrib.plugins.form_handlers.mail')
#INSTALLED_APPS.remove('fobi.contrib.themes.foundation5')
#INSTALLED_APPS.remove('fobi.contrib.themes.foundation5.widgets.form_handlers.db_store_foundation5_widget')
#INSTALLED_APPS.remove('fobi.contrib.themes.simple')
# INSTALLED_APPS.remove('fobi.contrib.plugins.form_handlers.http_repost')
# INSTALLED_APPS.remove('fobi.contrib.plugins.form_handlers.mail')
# INSTALLED_APPS.remove('fobi.contrib.themes.foundation5')
# INSTALLED_APPS.remove('fobi.contrib.themes.foundation5.widgets.'
# 'form_handlers.db_store_foundation5_widget')
# INSTALLED_APPS.remove('fobi.contrib.themes.simple')

View file

@ -4,11 +4,13 @@ INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.append('captcha')
INSTALLED_APPS.append('fobi.contrib.plugins.form_elements.security.recaptcha')
except Exception as e:
INSTALLED_APPS.append(
'fobi.contrib.plugins.form_elements.security.recaptcha'
)
except Exception as err:
pass
#RECAPTCHA_PUBLIC_KEY = ''
#RECAPTCHA_PRIVATE_KEY = ''
# RECAPTCHA_PUBLIC_KEY = ''
# RECAPTCHA_PRIVATE_KEY = ''
RECAPTCHA_USE_SSL = True
#FOBI_DEFAULT_THEME = 'simple'
# FOBI_DEFAULT_THEME = 'simple'

View file

@ -1,20 +1,22 @@
from nine.versions import DJANGO_GTE_1_8
from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS.remove('django.contrib.admin')
INSTALLED_APPS += [
'cms', # DjangoCMS
'cms', # DjangoCMS
'mptt',
'menus',
'sekizai',
#'djangocms_admin_style',
# 'djangocms_admin_style',
# Some plugins
'djangocms_picture',
'djangocms_snippet',
'treebeard',
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
'fobi.contrib.apps.djangocms_integration', # Fobi DjangoCMS app
# Django-CMS admin style
'djangocms_admin_style',
@ -34,15 +36,14 @@ except Exception as e:
MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
MIDDLEWARE_CLASSES += [
#'django.middleware.cache.UpdateCacheMiddleware',
# 'django.middleware.cache.UpdateCacheMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware',
#'django.middleware.cache.FetchFromCacheMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
]
from nine.versions import DJANGO_GTE_1_8
if DJANGO_GTE_1_8:
TEMPLATES[0]['OPTIONS']['context_processors'] += [
'cms.context_processors.cms_settings',
@ -57,9 +58,9 @@ else:
'cms.context_processors.cms_settings',
]
#FOBI_DEFAULT_THEME = 'bootstrap3'
#FOBI_DEFAULT_THEME = 'foundation5'
#FOBI_DEFAULT_THEME = 'simple'
# FOBI_DEFAULT_THEME = 'bootstrap3'
# FOBI_DEFAULT_THEME = 'foundation5'
# FOBI_DEFAULT_THEME = 'simple'
FOBI_DEFAULT_THEME = 'djangocms_admin_style_theme'
CMS_TEMPLATES = (

View file

@ -5,8 +5,10 @@ FOBI_DEFAULT_THEME = 'foundation5'
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.date_foundation5_widget'
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'date_foundation5_widget'
)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.datetime_foundation5_widget'
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'datetime_foundation5_widget'
)

View file

@ -0,0 +1,32 @@
from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
try:
INSTALLED_APPS.remove('admin_tools') \
if 'admin_tools' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.menu') \
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
FOBI_DEFAULT_THEME = 'foundation5'
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'date_foundation5_widget'
)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'datetime_foundation5_widget'
)

View file

@ -0,0 +1,32 @@
from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
try:
INSTALLED_APPS.remove('admin_tools') \
if 'admin_tools' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.menu') \
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
FOBI_DEFAULT_THEME = 'foundation5'
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'date_foundation5_widget'
)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'datetime_foundation5_widget'
)

View file

@ -0,0 +1,32 @@
from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
try:
INSTALLED_APPS.remove('admin_tools') \
if 'admin_tools' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.menu') \
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
FOBI_DEFAULT_THEME = 'foundation5'
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'date_foundation5_widget'
)
INSTALLED_APPS.append(
'fobi.contrib.themes.foundation5.widgets.form_elements.'
'datetime_foundation5_widget'
)

View file

@ -2,11 +2,11 @@ from .base import *
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS += [
'feincms', # FeinCMS
'feincms', # FeinCMS
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app
'page', # Example
'page', # Example
]
FEINCMS_RICHTEXT_INIT_CONTEXT = {

View file

@ -4,6 +4,9 @@ PROJECT_DIR = lambda base : os.path.abspath(os.path.join(os.path.dirname(__file_
DEBUG = True
DEBUG_TOOLBAR = not True
TEMPLATE_DEBUG = not True
DEBUG_TEMPLATE = True
DEV = True
os.environ.setdefault(
'FOBI_SOURCE_PATH',

View file

@ -19,7 +19,8 @@ LOGGING = {
},
'formatters': {
'verbose': {
'format': '\n%(levelname)s %(asctime)s [%(pathname)s:%(lineno)s] %(message)s'
'format': '\n%(levelname)s %(asctime)s [%(pathname)s:%(lineno)s] '
'%(message)s'
},
'simple': {
'format': '\n%(levelname)s %(message)s'
@ -37,32 +38,32 @@ LOGGING = {
'formatter': 'verbose'
},
'all_log': {
'level':'ERROR',
'class':'logging.handlers.RotatingFileHandler',
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/all.log"),
'maxBytes': 1048576,
'backupCount': 99,
'formatter': 'verbose',
},
'django_log': {
'level':'ERROR',
'class':'logging.handlers.RotatingFileHandler',
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/django.log"),
'maxBytes': 1048576,
'backupCount': 99,
'formatter': 'verbose',
},
'django_request_log': {
'level':'ERROR',
'class':'logging.handlers.RotatingFileHandler',
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/django_request.log"),
'maxBytes': 1048576,
'backupCount': 99,
'formatter': 'verbose',
},
'fobi_log': {
'level':'ERROR',
'class':'logging.handlers.RotatingFileHandler',
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'filename': PROJECT_DIR("../../logs/fobi.log"),
'maxBytes': 1048576,
'backupCount': 99,

View file

@ -3,6 +3,6 @@ from .base import *
FOBI_DEFAULT_THEME = 'simple'
INSTALLED_APPS = list(INSTALLED_APPS)
#INSTALLED_APPS.remove('admin_tools')
#INSTALLED_APPS.remove('admin_tools.menu')
#INSTALLED_APPS.remove('admin_tools.dashboard')
# INSTALLED_APPS.remove('admin_tools')
# INSTALLED_APPS.remove('admin_tools.menu')
# INSTALLED_APPS.remove('admin_tools.dashboard')

View file

@ -1 +1,95 @@
# Use in `tox`.
from nine import versions
from .base import *
TESTING = True
INSTALLED_APPS = list(INSTALLED_APPS)
if versions.DJANGO_1_5:
try:
INSTALLED_APPS.append(
'south') if 'south' not in INSTALLED_APPS else None
except Exception as err:
pass
elif versions.DJANGO_1_6:
try:
INSTALLED_APPS.append(
'south') if 'south' not in INSTALLED_APPS else None
except Exception as err:
pass
elif versions.DJANGO_1_7:
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove(
'tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
elif versions.DJANGO_1_8:
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove(
'tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
try:
INSTALLED_APPS.remove('admin_tools') \
if 'admin_tools' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.menu') \
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
elif versions.DJANGO_1_9:
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove(
'tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
try:
INSTALLED_APPS.remove('admin_tools') \
if 'admin_tools' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.menu') \
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
elif versions.DJANGO_1_10:
try:
INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None
INSTALLED_APPS.remove(
'tinymce') if 'tinymce' in INSTALLED_APPS else None
except Exception as err:
pass
try:
INSTALLED_APPS.remove('admin_tools') \
if 'admin_tools' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.menu') \
if 'admin_tools.menu' in INSTALLED_APPS else None
INSTALLED_APPS.remove('admin_tools.dashboard') \
if 'admin_tools.dashboard' in INSTALLED_APPS else None
except Exception as err:
pass
LOGGING = {}
DEBUG_TOOLBAR = False

View file

@ -2,5 +2,5 @@
{% block theme-javascripts %}
{{ block.super }}
{% include "google_analytics.html" %}
{% endblock theme-javascripts %}
{% if not testing %}{% include "google_analytics.html" %}{% endif %}
{% endblock theme-javascripts %}

View file

@ -8,6 +8,8 @@ from django.views.generic import TemplateView
from fobi.settings import DEFAULT_THEME
from nine import versions
admin.autodiscover()
# Mapping.
@ -29,7 +31,7 @@ if DEFAULT_THEME in ('simple', 'djangocms_admin_style_theme'):
urlpatterns = []
urlpatterns += i18n_patterns(
url_patterns_args = [
# DB Store plugin URLs
# namespace='fobi'
url(r'^fobi/plugins/form-handlers/db-store/',
@ -59,7 +61,12 @@ urlpatterns += i18n_patterns(
# django-fobi public forms contrib app:
# url(r'^', include('fobi.contrib.apps.public_forms.urls')),
)
]
if versions.DJANGO_LTE_1_7:
urlpatterns += i18n_patterns('', *url_patterns_args)
else:
urlpatterns += i18n_patterns(*url_patterns_args)
# Serving media and static in debug/developer mode.
if settings.DEBUG:
@ -72,17 +79,24 @@ if settings.DEBUG:
if 'feincms' in settings.INSTALLED_APPS:
from page.models import Page
Page
urlpatterns += i18n_patterns(
url_patterns_args = [
url(r'^pages/', include('feincms.urls')),
)
]
if versions.DJANGO_LTE_1_7:
urlpatterns += i18n_patterns('', *url_patterns_args)
else:
urlpatterns += i18n_patterns(*url_patterns_args)
# Conditionally including DjangoCMS URls in case if
# DjangoCMS in installed apps.
if 'cms' in settings.INSTALLED_APPS:
urlpatterns += i18n_patterns(
url_patterns_args = [
url(r'^cms-pages/', include('cms.urls')),
)
]
if versions.DJANGO_LTE_1_7:
urlpatterns += i18n_patterns('', *url_patterns_args)
else:
urlpatterns += i18n_patterns(*url_patterns_args)
# Conditionally including Captcha URls in case if
# Captcha in installed apps.

View file

@ -7,11 +7,13 @@ norecursedirs=
_sass
build
dist
migrations
python_files =
test_*.py
export =
DJANGO_SETTINGS_MODULE=./examples/simple/settings.testing
tests.py
DJANGO_SETTINGS_MODULE=settings.test
addopts=
--cov=src/fobi
--cov=fobi
--ignore=.tox
--ignore=requirements
--ignore=release

14
runtests.py Executable file
View file

@ -0,0 +1,14 @@
#!/usr/bin/env python
import os
import sys
import pytest
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.test")
sys.path.insert(0, "examples/simple")
return pytest.main()
if __name__ == '__main__':
sys.exit(main())

View file

@ -1,8 +1,7 @@
./scripts/uninstall.sh
./scripts/install.sh
#cd ..
cat README.rst SCREENSHOTS.rst docs/documentation.rst.distrib > docs/index.rst
cat QUICK_START.rst > docs/quickstart.rst
sphinx-build -n -a -b html docs builddocs
cd builddocs && zip -r ../builddocs.zip . -x ".*" && cd ..
#cd scripts

View file

@ -1,4 +1,3 @@
#cd ..
echo 'Compiling messages for django-fobi...'
cd src/fobi/
#django-admin.py compilemessages -l hy
@ -12,5 +11,3 @@ cd ../../examples/simple/
django-admin.py compilemessages -l de
django-admin.py compilemessages -l nl
django-admin.py compilemessages -l ru
#cd ../../scripts

View file

@ -1,5 +1,4 @@
#pip install -r examples/requirements/django_1_7.txt
pip install -r examples/requirements/feincms.txt
pip install -r examples/requirements/feincms_1_10.txt
python setup.py install
mkdir -p examples/logs examples/db examples/media examples/media/static examples/media/fobi_plugins/content_image
mkdir -p examples/media/fobi_plugins/file

View file

@ -0,0 +1,8 @@
pip install -r examples/requirements/feincms_1_12.txt
python setup.py install
mkdir -p examples/logs examples/db examples/media examples/media/static examples/media/fobi_plugins/content_image
mkdir -p examples/media/fobi_plugins/file
python examples/simple/manage.py collectstatic --noinput --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3
python examples/simple/manage.py syncdb --noinput --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3
python examples/simple/manage.py migrate --noinput --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3
python examples/simple/manage.py fobi_create_test_data --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3

9
scripts/make_migrations.sh Executable file
View file

@ -0,0 +1,9 @@
echo 'Making messages for django-fobi...'
cd examples/simple/
./manage.py makemigrations fobi
echo 'Making messages for example projects...'
./manage.py makemigrations
echo 'Applying migrations...'
./manage.py migrate

2
scripts/prepare_docs.sh Executable file
View file

@ -0,0 +1,2 @@
cat README.rst SCREENSHOTS.rst docs/documentation.rst.distrib > docs/index.rst
cat QUICK_START.rst > docs/quickstart.rst

2
scripts/pycodestyle.sh Executable file
View file

@ -0,0 +1,2 @@
reset
pycodestyle src/fobi/ --exclude src/fobi/migrations/,src/fobi/south_migrations/,src/fobi/contrib/plugins/form_handlers/db_store/migrations/

2
scripts/pycodestyle_example.sh Executable file
View file

@ -0,0 +1,2 @@
reset
pycodestyle examples/simple/ --exclude examples/simple/page/migrations/,examples/simple/page/south_migrations/,examples/simple/lund/fobi_addons/migrations/,examples/simple/wsgi.py

View file

@ -0,0 +1,3 @@
reset
./scripts/uninstall.sh
./scripts/install_django_1_9_feincms.sh

1
scripts/touch_docs.sh Executable file
View file

@ -0,0 +1 @@
cat README.rst SCREENSHOTS.rst docs/documentation.rst.distrib > docs/index.rst

View file

@ -4,6 +4,8 @@ import sys
from distutils.version import LooseVersion
from setuptools import setup, find_packages
version = '0.10.1'
# ***************************************************************************
# ************************** Django version *********************************
# ***************************************************************************
@ -204,8 +206,6 @@ for locale_dir in locale_dirs:
for f
in os.listdir(locale_dir)]
version = '0.9.6'
install_requires = []
# If certain version of Django is already installed, choose version agnostic
# dependencies.

View file

@ -1,6 +1,6 @@
__title__ = 'django-fobi'
__version__ = '0.9.6'
__build__ = 0x000068
__version__ = '0.10.1'
__build__ = 0x000074
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'

View file

@ -787,6 +787,11 @@ class BaseFormFieldPluginForm(BasePluginForm):
return True
if not DJANGO_GTE_1_7:
def add_error(self, field, error):
"""Backwards compatibility hack."""
raise forms.ValidationError(error, 'invalid')
# *****************************************************************************
# *****************************************************************************
# ******************************** Plugins ************************************
@ -1055,15 +1060,13 @@ class BasePlugin(object):
plugin_form = self.get_form()
if plugin_form:
try:
plugin_form = self.get_form()
if plugin_form:
kwargs = {
'data': data,
'files': files,
}
if initial_data:
kwargs.update({'initial': initial_data})
return plugin_form(**kwargs)
kwargs = {
'data': data,
'files': files,
}
if initial_data:
kwargs.update({'initial': initial_data})
return plugin_form(**kwargs)
except Exception as e:
if DEBUG:
logger.debug(e)
@ -1532,7 +1535,8 @@ class FormElementPlugin(BasePlugin):
logger.debug(str(err))
return {}
def _submit_plugin_form_data(self, form_entry, request, form):
def _submit_plugin_form_data(self, form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data (internal method).
Do not override this method. Use ``submit_plugin_form_data``,
@ -1545,20 +1549,30 @@ class FormElementPlugin(BasePlugin):
``fobi.models.FormEntry``.
:param django.http.HttpRequest request:
:param django.forms.Form form:
:param iterable form_element_entries:
"""
if DEBUG:
return self.submit_plugin_form_data(
form_entry=form_entry, request=request, form=form
form_entry=form_entry,
request=request,
form=form,
form_element_entries=form_element_entries,
**kwargs
)
else:
try:
return self.submit_plugin_form_data(
form_entry=form_entry, request=request, form=form
form_entry=form_entry,
request=request,
form=form,
form_element_entries=form_element_entries,
**kwargs
)
except Exception as e:
logger.debug(str(e))
def submit_plugin_form_data(self, form_entry, request, form):
def submit_plugin_form_data(self, form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data.
Called on form submission (when user actually
@ -1568,6 +1582,7 @@ class FormElementPlugin(BasePlugin):
``fobi.models.FormEntry``.
:param django.http.HttpRequest request:
:param django.forms.Form form:
:param iterable form_element_entries:
"""
@ -1610,24 +1625,30 @@ class FormHandlerPlugin(BasePlugin):
if not form_element_entries:
form_element_entries = form_entry.formelemententry_set.all()[:]
try:
if FAIL_ON_ERRORS_IN_FORM_HANDLER_PLUGINS:
response = self.run(form_entry, request, form,
form_element_entries)
if response:
return response
else:
return (True, None)
except Exception as err:
if FAIL_ON_ERRORS_IN_FORM_HANDLER_PLUGINS:
raise err.__class__("Exception: {0}. {1}"
"".format(str(err),
traceback.format_exc()))
logger.error(
"Error in class {0}. Details: "
"{1}. Full trace: {2}".format(self.__class__.__name__,
str(err), traceback.format_exc())
)
return (False, err)
else:
try:
response = self.run(form_entry, request, form,
form_element_entries)
if response:
return response
else:
return (True, None)
except Exception as err:
logger.error(
"Error in class {0}. Details: "
"{1}. Full trace: {2}".format(
self.__class__.__name__,
str(err), traceback.format_exc()
)
)
return (False, err)
def run(self, form_entry, request, form, form_element_entries=None):
"""Run.
@ -2399,19 +2420,27 @@ def validate_form_element_plugin_uid(plugin_uid):
return validate_plugin_uid(form_element_plugin_registry, plugin_uid)
def submit_plugin_form_data(form_entry, request, form):
def submit_plugin_form_data(form_entry, request, form,
form_element_entries=None, **kwargs):
"""Submit plugin form data for all plugins.
:param fobi.models.FormEntry form_entry: Instance of
``fobi.models.FormEntry``.
:param django.http.HttpRequest request:
:param django.forms.Form form:
:param iterable form_element_entries:
"""
for form_element_entry in form_entry.formelemententry_set.all():
if not form_element_entries:
form_element_entries = form_entry.formelemententry_set.all()
for form_element_entry in form_element_entries:
# Get the plugin.
form_element_plugin = form_element_entry.get_plugin(request=request)
updated_form = form_element_plugin._submit_plugin_form_data(
form_entry=form_entry, request=request, form=form
form_entry=form_entry,
request=request,
form=form,
form_element_entries=form_element_entries,
**kwargs
)
if updated_form:
form = updated_form

View file

@ -19,9 +19,9 @@ Installation
2. In the terminal type:
.. code-block:: none
.. code-block:: sh
$ ./manage.py fobi_sync_plugins
./manage.py fobi_sync_plugins
3. Assign appropriate permissions to the target users/groups to be using
the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True.

View file

@ -0,0 +1,86 @@
from __future__ import absolute_import
from uuid import uuid4
from django.conf import settings
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin
from fobi.helpers import delete_file, clone_file
from . import UID
from .forms import ContentImageForm
from .helpers import get_crop_filter
from .settings import (
FIT_METHOD_FIT_WIDTH, FIT_METHOD_FIT_HEIGHT, IMAGES_UPLOAD_DIR
)
__title__ = 'fobi.contrib.plugins.form_elements.content.content_image.base'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentImagePlugin',)
class ContentImagePlugin(FormElementPlugin):
"""Content image plugin."""
uid = UID
name = _("Content image")
group = _("Content")
form = ContentImageForm
def post_processor(self):
"""Post process data.
Always the same.
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def delete_plugin_data(self):
"""Delete uploaded file."""
delete_file(self.data.file)
def clone_plugin_data(self, entry):
"""Clone plugin data.
Clone plugin data, which means we make a copy of the original image.
TODO: Perhaps rely more on data of ``form_element_entry``?
"""
cloned_image = clone_file(
IMAGES_UPLOAD_DIR, self.data.file, relative_path=True
)
return self.get_cloned_plugin_data(update={'file': cloned_image})
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
width, height = self.data.size.split('x')
crop = get_crop_filter(self.data.fit_method)
if FIT_METHOD_FIT_WIDTH == self.data.fit_method:
thumb_size = (width, 0)
elif FIT_METHOD_FIT_HEIGHT == self.data.fit_method:
thumb_size = (0, height)
else:
thumb_size = (width, height)
context = {
'plugin': self,
'MEDIA_URL': settings.MEDIA_URL,
'crop': crop,
'thumb_size': thumb_size
}
rendered_image = render_to_string('content_image/render.html', context)
field_kwargs = {
'initial': rendered_image,
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]

View file

@ -1,20 +1,8 @@
from uuid import uuid4
from __future__ import absolute_import
from django.conf import settings
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from fobi.base import form_element_plugin_registry
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin, form_element_plugin_registry
from fobi.helpers import delete_file, clone_file
from . import UID
from .forms import ContentImageForm
from .helpers import get_crop_filter
from .settings import (
FIT_METHOD_FIT_WIDTH, FIT_METHOD_FIT_HEIGHT, IMAGES_UPLOAD_DIR
)
from .base import ContentImagePlugin
__title__ = 'fobi.contrib.plugins.form_elements.content.content_image.' \
'fobi_form_elements'
@ -24,65 +12,4 @@ __license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentImagePlugin',)
class ContentImagePlugin(FormElementPlugin):
"""Content image plugin."""
uid = UID
name = _("Content image")
group = _("Content")
form = ContentImageForm
def post_processor(self):
"""Post process data.
Always the same.
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def delete_plugin_data(self):
"""Delete uploaded file."""
delete_file(self.data.file)
def clone_plugin_data(self, entry):
"""Clone plugin data.
Clone plugin data, which means we make a copy of the original image.
TODO: Perhaps rely more on data of ``form_element_entry``?
"""
cloned_image = clone_file(
IMAGES_UPLOAD_DIR, self.data.file, relative_path=True
)
return self.get_cloned_plugin_data(update={'file': cloned_image})
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
width, height = self.data.size.split('x')
crop = get_crop_filter(self.data.fit_method)
if FIT_METHOD_FIT_WIDTH == self.data.fit_method:
thumb_size = (width, 0)
elif FIT_METHOD_FIT_HEIGHT == self.data.fit_method:
thumb_size = (0, height)
else:
thumb_size = (width, height)
context = {
'plugin': self,
'MEDIA_URL': settings.MEDIA_URL,
'crop': crop,
'thumb_size': thumb_size
}
rendered_image = render_to_string('content_image/render.html', context)
field_kwargs = {
'initial': rendered_image,
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(ContentImagePlugin)

View file

@ -18,9 +18,50 @@ Installation
2. In the terminal type:
.. code-block:: none
.. code-block:: sh
$ ./manage.py fobi_sync_plugins
./manage.py fobi_sync_plugins
3. Assign appropriate permissions to the target users/groups to be using
the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True.
4. Additionally, for the fine tuning, see the
``fobi.contrib.plugins.form_elements.content.content_text.defaults``
module. If necessary, override the settings by prepending
``FOBI_PLUGIN_CONTENT_TEXT_`` to the desired variable name from the
above mentioned ``defaults`` module.
By default the content of the text field is stripped using either the
awesome `bleach <https://bleach.readthedocs.io/>`_ library or if bleach
is not installed just Django's own `strip_tags` function. To configure
the strip (bleach only) behaviour, two settings are introduced:
.. code-block:: text
- ALLOWED_TAGS:
- ALLOWED_ATTRIBUTES:
The default values are:
.. code-block:: python
ALLOWED_TAGS = [
'a',
'abbr',
'acronym',
'b',
'blockquote',
'code',
'em',
'i',
'li',
'ol',
'strong',
'ul',
]
ALLOWED_ATTRIBUTES = {
'a': ['href', 'title'],
'abbr': ['title'],
'acronym': ['title'],
}

View file

@ -0,0 +1,46 @@
from __future__ import absolute_import
from uuid import uuid4
from django.utils.encoding import smart_str
from django.utils.translation import ugettext_lazy as _
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin
from . import UID
from .forms import ContentTextForm
__title__ = 'fobi.contrib.plugins.form_elements.content.content_text.base'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentTextPlugin',)
class ContentTextPlugin(FormElementPlugin):
"""Content text plugin."""
uid = UID
name = _("Content text")
group = _("Content")
form = ContentTextForm
def post_processor(self):
"""Post process data.
Always the same.
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
field_kwargs = {
'initial': "<p>{0}</p>".format(smart_str(self.data.text)),
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]

View file

@ -0,0 +1,34 @@
from django.conf import settings
from . import defaults
__title__ = 'fobi.contrib.plugins.form_elements.content.content_text.conf'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('get_setting',)
def get_setting(setting, override=None):
"""Get setting.
Get a setting from
``fobi.contrib.plugins.form_elements.content.content_text`` conf module,
falling back to the default.
If override is not None, it will be used instead of the setting.
:param setting: String with setting name
:param override: Value to use when no setting is available. Defaults to
None.
:return: Setting value.
"""
if override is not None:
return override
if hasattr(settings, 'FOBI_PLUGIN_CONTENT_TEXT_{0}'.format(setting)):
return getattr(
settings,
'FOBI_PLUGIN_CONTENT_TEXT_{0}'.format(setting)
)
else:
return getattr(defaults, setting)

View file

@ -0,0 +1,29 @@
__title__ = 'fobi.contrib.plugins.form_elements.content.content_text.defaults'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = (
'ALLOWED_TAGS',
'ALLOWED_TAGS',
)
ALLOWED_TAGS = [
'a',
'abbr',
'acronym',
'b',
'blockquote',
'code',
'em',
'i',
'li',
'ol',
'strong',
'ul',
]
ALLOWED_ATTRIBUTES = {
'a': ['href', 'title'],
'abbr': ['title'],
'acronym': ['title'],
}

View file

@ -1,14 +1,8 @@
from uuid import uuid4
from __future__ import absolute_import
from django.utils.encoding import smart_str
from django.utils.translation import ugettext_lazy as _
from fobi.base import form_element_plugin_registry
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin, form_element_plugin_registry
from . import UID
from .forms import ContentTextForm
from .base import ContentTextPlugin
__title__ = 'fobi.contrib.plugins.form_elements.content.content_text.' \
'fobi_form_elements'
@ -18,31 +12,4 @@ __license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentTextPlugin',)
class ContentTextPlugin(FormElementPlugin):
"""Content text plugin."""
uid = UID
name = _("Content text")
group = _("Content")
form = ContentTextForm
def post_processor(self):
"""Post process data.
Always the same.
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
field_kwargs = {
'initial': "<p>{0}</p>".format(smart_str(self.data.text)),
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(ContentTextPlugin)

View file

@ -1,9 +1,18 @@
from django import forms
from django.forms.widgets import Textarea
from django.utils.html import strip_tags
from django.utils.translation import ugettext_lazy as _
from fobi.base import BasePluginForm, get_theme
from .settings import ALLOWED_TAGS, ALLOWED_ATTRIBUTES
try:
import bleach
BLEACH_INSTALLED = True
except ImportError as err:
BLEACH_INSTALLED = False
__title__ = 'fobi.contrib.plugins.form_elements.content.content_text.forms'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
@ -26,3 +35,16 @@ class ContentTextForm(forms.Form, BasePluginForm):
required=True,
widget=Textarea(attrs={'class': theme.form_element_html_class})
)
def clean_text(self):
"""Clean text value."""
if BLEACH_INSTALLED:
return bleach.clean(
text=self.cleaned_data['text'],
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
strip=True,
strip_comments=True
)
else:
return strip_tags(self.cleaned_data['text'])

View file

@ -0,0 +1,13 @@
from .conf import get_setting
__title__ = 'fobi.contrib.plugins.form_elements.content.content_text.settings'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = (
'ALLOWED_TAGS',
'ALLOWED_ATTRIBUTES',
)
ALLOWED_TAGS = get_setting('ALLOWED_TAGS')
ALLOWED_ATTRIBUTES = get_setting('ALLOWED_ATTRIBUTES')

View file

@ -18,9 +18,9 @@ Installation
2. In the terminal type:
.. code-block:: none
.. code-block:: sh
$ ./manage.py fobi_sync_plugins
./manage.py fobi_sync_plugins
3. Assign appropriate permissions to the target users/groups to be using
the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True.

View file

@ -0,0 +1,51 @@
from __future__ import absolute_import
from uuid import uuid4
from django.utils.translation import ugettext_lazy as _
from vishap import render_video
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin
from . import UID
from .forms import ContentVideoForm
__title__ = 'fobi.contrib.plugins.form_elements.content.content_video.base'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentVideoPlugin',)
class ContentVideoPlugin(FormElementPlugin):
"""Content video plugin."""
uid = UID
name = _("Content video")
group = _("Content")
form = ContentVideoForm
def post_processor(self):
"""Process plugin data.
Always the same.
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
width, height = self.data.size.split('x')
field_kwargs = {
'initial': '<div class="video-wrapper">{0}</div>'.format(
render_video(self.data.url, width, height)
),
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]

View file

@ -1,15 +1,8 @@
from uuid import uuid4
from __future__ import absolute_import
from django.utils.translation import ugettext_lazy as _
from fobi.base import form_element_plugin_registry
from vishap import render_video
from nonefield.fields import NoneField
from fobi.base import FormElementPlugin, form_element_plugin_registry
from . import UID
from .forms import ContentVideoForm
from .base import ContentVideoPlugin
__title__ = 'fobi.contrib.plugins.form_elements.content.content_video.' \
'fobi_form_elements'
@ -19,35 +12,4 @@ __license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('ContentVideoPlugin',)
class ContentVideoPlugin(FormElementPlugin):
"""Content video plugin."""
uid = UID
name = _("Content video")
group = _("Content")
form = ContentVideoForm
def post_processor(self):
"""Process plugin data.
Always the same.
"""
self.data.name = "{0}_{1}".format(self.uid, uuid4())
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
width, height = self.data.size.split('x')
field_kwargs = {
'initial': '<div class="video-wrapper">{0}</div>'.format(
render_video(self.data.url, width, height)
),
'required': False,
'label': '',
}
return [(self.data.name, NoneField, field_kwargs)]
form_element_plugin_registry.register(ContentVideoPlugin)

View file

@ -19,9 +19,9 @@ Installation
2. In the terminal type:
.. code-block:: none
.. code-block:: sh
$ ./manage.py fobi_sync_plugins
./manage.py fobi_sync_plugins
3. Assign appropriate permissions to the target users/groups to be using
the plugin if ``FOBI_RESTRICT_PLUGIN_ACCESS`` is set to True.

View file

@ -0,0 +1,34 @@
from django.forms.fields import BooleanField
from django.utils.translation import ugettext_lazy as _
from fobi.base import FormFieldPlugin
from . import UID
from .forms import BooleanSelectForm
__title__ = 'fobi.contrib.plugins.form_elements.fields.boolean.base'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('BooleanSelectPlugin',)
class BooleanSelectPlugin(FormFieldPlugin):
"""Boolean select plugin."""
uid = UID
name = _("Boolean")
group = _("Fields")
form = BooleanSelectForm
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
'required': self.data.required,
}
return [(self.data.name, BooleanField, field_kwargs)]

View file

@ -1,10 +1,8 @@
from django.forms.fields import BooleanField
from django.utils.translation import ugettext_lazy as _
from __future__ import absolute_import
from fobi.base import FormFieldPlugin, form_element_plugin_registry
from fobi.base import form_element_plugin_registry
from . import UID
from .forms import BooleanSelectForm
from .base import BooleanSelectPlugin
__title__ = 'fobi.contrib.plugins.form_elements.fields.boolean.' \
'fobi_form_elements'
@ -14,25 +12,4 @@ __license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('BooleanSelectPlugin',)
class BooleanSelectPlugin(FormFieldPlugin):
"""Boolean select plugin."""
uid = UID
name = _("Boolean")
group = _("Fields")
form = BooleanSelectForm
def get_form_field_instances(self, request=None, form_entry=None,
form_element_entries=None, **kwargs):
"""Get form field instances."""
field_kwargs = {
'label': self.data.label,
'help_text': self.data.help_text,
'initial': self.data.initial,
'required': self.data.required,
}
return [(self.data.name, BooleanField, field_kwargs)]
form_element_plugin_registry.register(BooleanSelectPlugin)

Some files were not shown because too many files have changed in this diff Show more