From fc615702852c1f9d87f27ff6ccba766f8c381b85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sun, 29 Sep 2019 20:53:23 +0200
Subject: [PATCH] misc: use relative imports (#36517)

---
 extra/pyvotecore/vote_field.py                |  2 +-
 extra/vote/anonymity.py                       |  2 +-
 extra/vote/ranked_items.py                    |  2 +-
 tests/test_admin_pages.py                     |  4 +-
 tests/test_api.py                             | 11 ++-
 tests/test_backoffice_pages.py                |  8 +-
 tests/test_datasource.py                      | 10 +--
 tests/test_fc_auth.py                         | 12 +--
 tests/test_fields.py                          |  2 +-
 tests/test_form_pages.py                      | 50 ++++++------
 tests/test_formdata.py                        |  4 +-
 tests/test_formdef_import.py                  |  2 +-
 tests/test_publisher.py                       |  2 +-
 tests/test_role.py                            |  2 +-
 tests/test_templates.py                       |  4 +-
 tests/test_workflow_import.py                 |  2 +-
 tests/test_workflows.py                       |  6 +-
 tests/utilities.py                            | 21 +----
 wcs/__init__.py                               | 11 +--
 wcs/admin/__init__.py                         |  2 +-
 wcs/admin/bounces.py                          | 18 ++---
 wcs/admin/categories.py                       |  6 +-
 wcs/admin/data_sources.py                     | 10 +--
 wcs/admin/fields.py                           | 10 +--
 wcs/admin/forms.py                            | 18 ++---
 wcs/admin/logged_errors.py                    |  6 +-
 wcs/admin/roles.py                            |  8 +-
 wcs/admin/settings.py                         | 55 +++++++------
 wcs/admin/users.py                            | 30 +++----
 wcs/admin/workflows.py                        | 14 ++--
 wcs/admin/wscalls.py                          |  8 +-
 wcs/api.py                                    | 16 ++--
 wcs/api_utils.py                              |  2 +-
 wcs/backoffice/__init__.py                    |  2 +-
 wcs/backoffice/cards.py                       |  4 +-
 wcs/backoffice/data_management.py             |  6 +-
 wcs/backoffice/management.py                  | 32 ++++----
 wcs/backoffice/root.py                        | 14 ++--
 wcs/backoffice/studio.py                      |  6 +-
 wcs/backoffice/submission.py                  |  8 +-
 wcs/carddef.py                                |  2 +-
 wcs/categories.py                             | 10 +--
 wcs/conditions.py                             |  4 +-
 wcs/ctl/backup.py                             |  2 +-
 wcs/ctl/check_hobos.py                        | 10 +--
 wcs/ctl/delete_tenant.py                      |  2 +-
 wcs/ctl/export_settings.py                    |  2 +-
 wcs/ctl/hobo_notify.py                        |  4 +-
 wcs/ctl/management/commands/__init__.py       |  2 +-
 wcs/ctl/management/commands/convert_to_sql.py |  2 +-
 wcs/ctl/management/commands/runscript.py      |  2 +-
 wcs/ctl/process_bounce.py                     |  8 +-
 wcs/ctl/rebuild_indexes.py                    |  2 +-
 wcs/ctl/restore.py                            |  2 +-
 wcs/ctl/runscript.py                          |  2 +-
 wcs/ctl/shell.py                              |  2 +-
 wcs/ctl/wipe_data.py                          |  2 +-
 wcs/data_sources.py                           | 36 ++++-----
 wcs/fields.py                                 | 20 ++---
 wcs/formdata.py                               | 32 ++++----
 wcs/formdef.py                                | 32 ++++----
 wcs/forms/actions.py                          | 10 +--
 wcs/forms/backoffice.py                       |  8 +-
 wcs/forms/common.py                           | 12 +--
 wcs/forms/preview.py                          |  2 +-
 wcs/forms/root.py                             | 16 ++--
 wcs/forms/workflows.py                        |  2 +-
 wcs/logged_errors.py                          |  4 +-
 wcs/myspace.py                                |  4 +-
 wcs/portfolio.py                              | 11 +--
 wcs/publisher.py                              | 22 +++---
 wcs/qommon/__init__.py                        |  4 +-
 wcs/qommon/admin/cfg.py                       |  2 +-
 wcs/qommon/admin/emails.py                    | 10 +--
 wcs/qommon/admin/logger.py                    |  8 +-
 wcs/qommon/admin/menu.py                      |  4 +-
 wcs/qommon/admin/settings.py                  |  8 +-
 wcs/qommon/admin/texts.py                     | 10 +--
 wcs/qommon/afterjobs.py                       |  6 +-
 wcs/qommon/backoffice/__init__.py             |  2 +-
 wcs/qommon/backoffice/listing.py              |  2 +-
 wcs/qommon/backoffice/menu.py                 |  4 +-
 wcs/qommon/backoffice/root.py                 |  4 +-
 wcs/qommon/bounces.py                         |  2 +-
 wcs/qommon/ctl.py                             |  4 +-
 wcs/qommon/emails.py                          | 17 ++--
 wcs/qommon/errors.py                          |  8 +-
 wcs/qommon/form.py                            | 12 +--
 wcs/qommon/http_request.py                    |  4 +-
 wcs/qommon/http_response.py                   |  6 +-
 wcs/qommon/humantime.py                       |  2 +-
 wcs/qommon/ident/__init__.py                  |  2 +-
 wcs/qommon/ident/franceconnect.py             | 10 +--
 wcs/qommon/ident/idp.py                       | 26 +++----
 wcs/qommon/ident/password.py                  | 36 ++++-----
 wcs/qommon/ident/password_accounts.py         |  2 +-
 .../management/commands/collectstatic.py      |  2 +-
 wcs/qommon/management/commands/cron.py        |  6 +-
 wcs/qommon/management/commands/migrate.py     |  2 +-
 wcs/qommon/misc.py                            |  8 +-
 wcs/qommon/myspace.py                         | 16 ++--
 wcs/qommon/pages.py                           |  4 +-
 wcs/qommon/publisher.py                       | 37 ++++-----
 wcs/qommon/saml2.py                           | 12 +--
 wcs/qommon/saml2utils.py                      |  2 +-
 wcs/qommon/sessions.py                        |  6 +-
 wcs/qommon/sms.py                             |  6 +-
 wcs/qommon/storage.py                         |  8 +-
 wcs/qommon/substitution.py                    |  2 +-
 wcs/qommon/template.py                        | 14 ++--
 wcs/qommon/tokens.py                          |  2 +-
 wcs/roles.py                                  |  9 +--
 wcs/root.py                                   | 76 +++++++++---------
 wcs/sessions.py                               |  8 +-
 wcs/sql.py                                    | 10 +--
 wcs/tracking_code.py                          |  4 +-
 wcs/users.py                                  | 10 +--
 wcs/variables.py                              | 16 ++--
 wcs/wf/aggregation_email.py                   | 12 +--
 wcs/wf/attachment.py                          |  4 +-
 wcs/wf/backoffice_fields.py                   |  4 +-
 wcs/wf/criticality.py                         |  2 +-
 wcs/wf/dispatch.py                            |  8 +-
 wcs/wf/export_to_model.py                     | 13 ++--
 wcs/wf/form.py                                |  4 +-
 wcs/wf/geolocate.py                           | 10 +--
 wcs/wf/jump.py                                | 12 +--
 wcs/wf/notification.py                        |  8 +-
 wcs/wf/profile.py                             | 10 +--
 wcs/wf/redirect_to_url.py                     |  4 +-
 wcs/wf/register_comment.py                    |  8 +-
 wcs/wf/remove.py                              |  2 +-
 wcs/wf/resubmit.py                            |  2 +-
 wcs/wf/roles.py                               | 10 +--
 wcs/wf/wscall.py                              |  8 +-
 wcs/workflows.py                              | 78 +++++++++----------
 wcs/wscalls.py                                | 18 ++---
 137 files changed, 674 insertions(+), 701 deletions(-)

diff --git a/extra/pyvotecore/vote_field.py b/extra/pyvotecore/vote_field.py
index d4abd0fe8..bd3f9e7af 100644
--- a/extra/pyvotecore/vote_field.py
+++ b/extra/pyvotecore/vote_field.py
@@ -18,7 +18,7 @@
 
 import random
 from quixote.html import htmltext, TemplateIO
-from qommon.form import CompositeWidget, IntWidget, WidgetList, StringWidget, \
+from wcs.qommon.form import CompositeWidget, IntWidget, WidgetList, StringWidget, \
         CheckboxWidget, SingleSelectWidget
 from wcs.fields import WidgetField, register_field_class
 from pyvotecore import schulze_method, irv, ranked_pairs, schulze_pr, \
diff --git a/extra/vote/anonymity.py b/extra/vote/anonymity.py
index df39e14dd..67b6c83d1 100644
--- a/extra/vote/anonymity.py
+++ b/extra/vote/anonymity.py
@@ -19,7 +19,7 @@
 from quixote import get_publisher
 
 from wcs.fields import WidgetField, register_field_class
-from qommon.form import *
+from wcs.qommon.form import *
 
 class VoteAnonymityWidget(CheckboxWidget):
     vote_anonymity = 'anonymous'
diff --git a/extra/vote/ranked_items.py b/extra/vote/ranked_items.py
index d83077820..b975a5e69 100644
--- a/extra/vote/ranked_items.py
+++ b/extra/vote/ranked_items.py
@@ -18,7 +18,7 @@
 
 import random
 from quixote.html import htmltext, TemplateIO
-from qommon.form import *
+from wcs.qommon.form import *
 from wcs.fields import WidgetField, register_field_class
 
 class RankedItemsWidget(CompositeWidget):
diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py
index a45bd4ad9..d4067ede4 100644
--- a/tests/test_admin_pages.py
+++ b/tests/test_admin_pages.py
@@ -28,7 +28,7 @@ from quixote.http_request import Upload as QuixoteUpload
 
 from wcs.qommon import errors, sessions
 from wcs.qommon.form import UploadedFile
-from qommon.ident.password_accounts import PasswordAccount
+from wcs.qommon.ident.password_accounts import PasswordAccount
 from wcs.qommon.http_request import HTTPRequest
 from wcs.qommon.template import get_current_theme
 from wcs.qommon.bounces import Bounce
@@ -4501,7 +4501,7 @@ def test_settings_idp(pub):
     resp = resp.forms[0].submit() # confirm delete
     assert len(pub.cfg['idp']) == 0
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         idp_metadata_filename = os.path.join(os.path.dirname(__file__), 'idp_metadata.xml')
         urlopen.side_effect = lambda *args: open(idp_metadata_filename)
         resp = app.get('/backoffice/settings/identification/idp/idp/')
diff --git a/tests/test_api.py b/tests/test_api.py
index 8d3a3ee37..a38d37c89 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -530,7 +530,7 @@ def test_formdef_schema(pub):
     formdef.workflow_id = workflow.id
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO('''\
 {"data": [{"id": 0, "text": "zéro", "foo": "bar"}, \
 {"id": 1, "text": "uné", "foo": "bar1"}, \
@@ -1282,9 +1282,8 @@ def test_formdata_with_workflow_data(pub, local_user):
     formdata.status = 'wf-new'
     formdata.evolution[-1].status = 'wf-new'
 
-    from qommon.form import PicklableUpload as PicklableUpload2
     from wcs.qommon.form import PicklableUpload as PicklableUpload3
-    upload = PicklableUpload2('test.txt', 'text/plain', 'ascii')
+    upload = PicklableUpload3('test.txt', 'text/plain', 'ascii')
     upload.receive(['test'])
     upload2 = PicklableUpload3('test.txt', 'text/plain', 'ascii')
     upload2.receive(['test'])
@@ -2547,7 +2546,7 @@ def test_get_secret_and_orig(no_request_pub):
     assert orig == 'example.net'
 
 def test_reverse_geocoding(pub):
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(json.dumps({'address': 'xxx'}))
         get_app(pub).get('/api/reverse-geocoding', status=400)
         resp = get_app(pub).get('/api/reverse-geocoding?lat=0&lon=0')
@@ -2603,7 +2602,7 @@ def test_formdef_submit_structured(pub, local_user):
             '?format=json&orig=coucou&email=%s' % urllib.quote(local_user.email), '1234')
         return signed_url[len('http://example.net'):]
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO('''\
 {"data": [{"id": 0, "text": "zéro", "foo": "bar"}, \
 {"id": 1, "text": "uné", "foo": "bar1"}, \
@@ -2634,7 +2633,7 @@ def test_formdef_submit_structured(pub, local_user):
 
 
 def test_geocoding(pub):
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(json.dumps([{'lat': 0, 'lon': 0}]))
         get_app(pub).get('/api/geocoding', status=400)
         resp = get_app(pub).get('/api/geocoding?q=test')
diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py
index accb8691a..5df73ed66 100644
--- a/tests/test_backoffice_pages.py
+++ b/tests/test_backoffice_pages.py
@@ -22,11 +22,11 @@ except ImportError:
     xlwt = None
 
 from quixote import cleanup, get_publisher
-from qommon import ods
+from wcs.qommon import ods
 from wcs.api_utils import sign_url
 from wcs.qommon import errors, sessions
 from wcs.qommon.form import PicklableUpload
-from qommon.ident.password_accounts import PasswordAccount
+from wcs.qommon.ident.password_accounts import PasswordAccount
 from wcs.qommon.http_request import HTTPRequest
 from wcs.roles import Role
 from wcs.workflows import (Workflow, CommentableWorkflowStatusItem,
@@ -2899,7 +2899,7 @@ def test_backoffice_wfedit_and_data_source_with_user_info(pub):
 
     app = login(get_app(pub))
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]}
         def side_effect(url, *args):
             assert '?name_id=admin' in url
@@ -4023,7 +4023,7 @@ def test_backoffice_workflow_form_with_live_data_source(pub):
 
     app = get_app(pub)
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data1 = {'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]}
         data2 = {'data': [{'id': 'C', 'text': 'hello'}, {'id': 'D', 'text': 'world'}]}
         def side_effect(url, *args):
diff --git a/tests/test_datasource.py b/tests/test_datasource.py
index 9224cc8a8..8c14d6dad 100644
--- a/tests/test_datasource.py
+++ b/tests/test_datasource.py
@@ -387,7 +387,7 @@ def test_data_source_unicode():
 
     data_source2 = NamedDataSource.select()[0]
     assert data_source2.data_source == data_source.data_source
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(
                 '{"data": [{"id": 0, "text": "zéro"}, {"id": 1, "text": "uné"}, {"id": 2, "text": "deux"}]}')
         assert data_sources.get_items({'type': 'foobar'}) == [
@@ -403,7 +403,7 @@ def test_data_source_signed(no_request_pub):
     data_source.data_source = {'type': 'json', 'value': "https://api.example.com/json"}
     data_source.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(
                 '{"data": [{"id": 0, "text": "zero"}]}')
         assert len(data_sources.get_items({'type': 'foobar'})) == 1
@@ -420,7 +420,7 @@ def test_data_source_signed(no_request_pub):
 
     data_source.data_source = {'type': 'json', 'value': "https://api.example.com/json?foo=bar"}
     data_source.store()
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(
                 '{"data": [{"id": 0, "text": "zero"}]}')
         assert len(data_sources.get_items({'type': 'foobar'})) == 1
@@ -437,7 +437,7 @@ def test_data_source_signed(no_request_pub):
 
     data_source.data_source = {'type': 'json', 'value': "https://no-secret.example.com/json"}
     data_source.store()
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(
                 '{"data": [{"id": 0, "text": "zero"}]}')
         assert len(data_sources.get_items({'type': 'foobar'})) == 1
@@ -450,7 +450,7 @@ def test_named_datasource_json_cache(requests_pub):
     datasource.data_source = {'type': 'json', 'value': 'http://whatever/'}
     datasource.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         urlopen.side_effect = lambda *args: StringIO(
             json.dumps({'data': [{'id': '1', 'text': 'foo'}, {'id': '2', 'text': 'bar'}]}))
 
diff --git a/tests/test_fc_auth.py b/tests/test_fc_auth.py
index 8b446f104..66e54a058 100644
--- a/tests/test_fc_auth.py
+++ b/tests/test_fc_auth.py
@@ -144,8 +144,8 @@ def test_fc_login_page(caplog):
     }
 
     assert pub.user_class.count() == 0
-    with mock.patch('qommon.ident.franceconnect.http_post_request') as http_post_request, \
-            mock.patch('qommon.ident.franceconnect.http_get_page') as http_get_page:
+    with mock.patch('wcs.qommon.ident.franceconnect.http_post_request') as http_post_request, \
+            mock.patch('wcs.qommon.ident.franceconnect.http_get_page') as http_get_page:
         http_post_request.return_value = (None, 200, json.dumps(token_result), None)
         http_get_page.return_value = (None, 200, json.dumps(user_info_result), None)
         resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({
@@ -197,8 +197,8 @@ def test_fc_login_page(caplog):
         id_token['nonce'] = qs['nonce'][0]
         token_result['id_token'] = '.%s.' % base64url_encode(json.dumps(id_token))
 
-        with mock.patch('qommon.ident.franceconnect.http_post_request') as http_post_request, \
-                mock.patch('qommon.ident.franceconnect.http_get_page') as http_get_page:
+        with mock.patch('wcs.qommon.ident.franceconnect.http_post_request') as http_post_request, \
+                mock.patch('wcs.qommon.ident.franceconnect.http_get_page') as http_get_page:
             http_post_request.return_value = (None, 200, json.dumps(token_result), None)
             http_get_page.return_value = (None, 200, json.dumps(user_info_result), None)
             resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({
@@ -245,8 +245,8 @@ def test_fc_login_page(caplog):
         'family_name': 'Deux',
         # 'email': 'john.deux@example.com',  # missing
     }
-    with mock.patch('qommon.ident.franceconnect.http_post_request') as http_post_request, \
-            mock.patch('qommon.ident.franceconnect.http_get_page') as http_get_page:
+    with mock.patch('wcs.qommon.ident.franceconnect.http_post_request') as http_post_request, \
+            mock.patch('wcs.qommon.ident.franceconnect.http_get_page') as http_get_page:
         http_post_request.return_value = (None, 200, json.dumps(token_result), None)
         http_get_page.return_value = (None, 200, json.dumps(bad_user_info_result), None)
         resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({
diff --git a/tests/test_fields.py b/tests/test_fields.py
index 088153915..a1f6fae7b 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -8,7 +8,7 @@ import pytest
 
 from quixote import cleanup
 from quixote.http_request import Upload
-from qommon.http_request import HTTPRequest
+from wcs.qommon.http_request import HTTPRequest
 from wcs.qommon import sessions
 from wcs import fields
 from wcs.qommon.form import Form
diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py
index 0b13ade6f..c80bae617 100644
--- a/tests/test_form_pages.py
+++ b/tests/test_form_pages.py
@@ -850,7 +850,7 @@ def test_form_multi_page_many_conditions(pub):
     formdef.store()
     formdef.data_class().wipe()
 
-    with mock.patch('qommon.publisher.Substitutions.invalidate_cache') as invalidate_cache:
+    with mock.patch('wcs.qommon.publisher.Substitutions.invalidate_cache') as invalidate_cache:
         resp = get_app(pub).get('/test/')
         call_count = invalidate_cache.call_count
 
@@ -861,7 +861,7 @@ def test_form_multi_page_many_conditions(pub):
     formdef.store()
 
     # check the cache doesn't get invalidated for every page
-    with mock.patch('qommon.publisher.Substitutions.invalidate_cache') as invalidate_cache:
+    with mock.patch('wcs.qommon.publisher.Substitutions.invalidate_cache') as invalidate_cache:
         resp = get_app(pub).get('/test/')
         assert invalidate_cache.call_count == call_count
 
@@ -2496,7 +2496,7 @@ def test_form_page_formula_prefill_items_field(pub):
         data_source=ds, display_disabled_items=True,
         prefill={'type': 'formula', 'value': '["2"]'})]
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello'}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -4948,7 +4948,7 @@ def test_item_field_with_disabled_items(http_requests, pub):
         data_source=ds, display_disabled_items=True)]
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello'}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -4961,7 +4961,7 @@ def test_item_field_with_disabled_items(http_requests, pub):
 
     formdef.data_class().wipe()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -4986,7 +4986,7 @@ def test_item_field_with_disabled_items(http_requests, pub):
         display_disabled_items=False)]
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -5003,7 +5003,7 @@ def test_item_field_with_disabled_items(http_requests, pub):
         data_source=ds, display_mode='radio', display_disabled_items=True)]
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello'}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -5016,7 +5016,7 @@ def test_item_field_with_disabled_items(http_requests, pub):
 
     formdef.data_class().wipe()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -5045,7 +5045,7 @@ def test_items_field_with_disabled_items(http_requests, pub):
         data_source=ds, display_disabled_items=True)]
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello'}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -5058,7 +5058,7 @@ def test_items_field_with_disabled_items(http_requests, pub):
 
     formdef.data_class().wipe()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -5075,7 +5075,7 @@ def test_items_field_with_disabled_items(http_requests, pub):
         data_source=ds, display_disabled_items=False)]
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = get_app(pub).get('/test/')
@@ -5104,7 +5104,7 @@ def test_item_field_autocomplete_json_source(http_requests, pub):
     ]
     formdef.store()
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'},
                          {'id': '2', 'text': 'world', 'extra': 'bar'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
@@ -5121,7 +5121,7 @@ def test_item_field_autocomplete_json_source(http_requests, pub):
     # check hint is displayed within
     formdef.fields[0].hint = 'help text'
     formdef.store()
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'},
                          {'id': '2', 'text': 'world', 'extra': 'bar'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
@@ -5141,7 +5141,7 @@ def test_item_field_autocomplete_json_source(http_requests, pub):
     formdef.data_class().wipe()
 
     app = get_app(pub)
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'},
                          {'id': '2', 'text': 'world', 'extra': 'bar'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
@@ -5150,7 +5150,7 @@ def test_item_field_autocomplete_json_source(http_requests, pub):
         pq = resp.pyquery.remove_namespaces()
         select2_url = pq('select').attr['data-select2-url']
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp2 = app.get(select2_url + '?q=hell')
@@ -5166,7 +5166,7 @@ def test_item_field_autocomplete_json_source(http_requests, pub):
     resp.form['f0'].force_value('1')
     resp.form.fields['f0_display'].force_value('hello')
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = resp.form.submit('submit') # -> validation page
@@ -5175,7 +5175,7 @@ def test_item_field_autocomplete_json_source(http_requests, pub):
         assert resp.form['f0'].value == '1'
         assert resp.form['f0_label'].value == 'hello'
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = resp.form.submit('submit') # -> submit
@@ -5193,7 +5193,7 @@ remote.example.net = 1234
 ''')
 
     app = get_app(pub)
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'},
                          {'id': '2', 'text': 'world', 'extra': 'bar'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
@@ -5202,7 +5202,7 @@ remote.example.net = 1234
         pq = resp.pyquery.remove_namespaces()
         select2_url = pq('select').attr['data-select2-url']
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp2 = app.get(select2_url + '?q=hell')
@@ -5215,7 +5215,7 @@ remote.example.net = 1234
     resp.form['f0'].force_value('1')
     resp.form.fields['f0_display'].force_value('hello')
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = resp.form.submit('submit') # -> validation page
@@ -5224,7 +5224,7 @@ remote.example.net = 1234
         assert resp.form['f0'].value == '1'
         assert resp.form['f0_label'].value == 'hello'
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
         resp = resp.form.submit('submit') # -> submit
@@ -5240,7 +5240,7 @@ remote.example.net = 1234
     formdef.store()
 
     app = get_app(pub)
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'},
                          {'id': '2', 'text': 'world', 'extra': 'bar'}]}
         urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
@@ -5274,7 +5274,7 @@ def test_item_field_autocomplete_jsonp_source(http_requests, pub):
     formdef.store()
 
     app = get_app(pub)
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         resp = app.get('/test/')
         assert urlopen.call_count == 0
         pq = resp.pyquery.remove_namespaces()
@@ -5287,13 +5287,13 @@ def test_item_field_autocomplete_jsonp_source(http_requests, pub):
     resp.form['f0'].force_value('1')
     resp.form['f0_display'].force_value('hello')
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         resp = resp.form.submit('submit') # -> validation page
         assert urlopen.call_count == 0
         assert resp.form['f0'].value == '1'
         assert resp.form['f0_label'].value == 'hello'
 
-    with mock.patch('qommon.misc.urlopen') as urlopen:
+    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
         resp = resp.form.submit('submit') # -> submit
         assert urlopen.call_count == 0
         assert formdef.data_class().select()[0].data['0'] == '1'
diff --git a/tests/test_formdata.py b/tests/test_formdata.py
index 0eb306685..2e9bedae1 100644
--- a/tests/test_formdata.py
+++ b/tests/test_formdata.py
@@ -7,8 +7,8 @@ import time
 
 from quixote import cleanup
 from quixote.http_request import Upload
-from qommon.template import Template
-from qommon.form import PicklableUpload
+from wcs.qommon.template import Template
+from wcs.qommon.form import PicklableUpload
 from wcs.qommon.http_request import HTTPRequest
 from wcs import fields, formdef
 from wcs.categories import Category
diff --git a/tests/test_formdef_import.py b/tests/test_formdef_import.py
index 141a3efa7..6d78ddf59 100644
--- a/tests/test_formdef_import.py
+++ b/tests/test_formdef_import.py
@@ -13,7 +13,7 @@ from wcs.categories import Category
 from wcs.formdef import FormDef, fields, FormdefImportError
 from wcs.workflows import Workflow
 from wcs.roles import Role
-from qommon.misc import indent_xml as indent
+from wcs.qommon.misc import indent_xml as indent
 
 from utilities import create_temporary_pub
 
diff --git a/tests/test_publisher.py b/tests/test_publisher.py
index b973c6d02..9e943dacf 100644
--- a/tests/test_publisher.py
+++ b/tests/test_publisher.py
@@ -182,7 +182,7 @@ def test_cron_command():
 
     # simulate another locked cron
     import tempfile
-    from qommon.vendor import locket
+    from wcs.qommon.vendor import locket
     lockfile = os.path.join(tempfile.gettempdir(), 'wcs-cron-in-progress.lock')
     with locket.lock_file(lockfile, timeout=0):
         with mock.patch('wcs.qommon.management.commands.cron.cron_worker') as cron_worker:
diff --git a/tests/test_role.py b/tests/test_role.py
index c9363ed1c..55275c367 100644
--- a/tests/test_role.py
+++ b/tests/test_role.py
@@ -4,7 +4,7 @@ import cPickle
 
 from utilities import create_temporary_pub, clean_temporary_pub
 
-from qommon.storage import StorableObject
+from wcs.qommon.storage import StorableObject
 from wcs.roles import Role, get_user_roles
 
 def setup_module(module):
diff --git a/tests/test_templates.py b/tests/test_templates.py
index 18f0ea659..c7723b271 100644
--- a/tests/test_templates.py
+++ b/tests/test_templates.py
@@ -6,8 +6,8 @@ import string
 
 from django.test import override_settings
 from quixote import cleanup
-from qommon.substitution import CompatibilityNamesDict
-from qommon.template import Template, TemplateError
+from wcs.qommon.substitution import CompatibilityNamesDict
+from wcs.qommon.template import Template, TemplateError
 from wcs.conditions import Condition
 from wcs.variables import LazyFormData
 
diff --git a/tests/test_workflow_import.py b/tests/test_workflow_import.py
index d3280fb2f..f5229b94d 100644
--- a/tests/test_workflow_import.py
+++ b/tests/test_workflow_import.py
@@ -21,7 +21,7 @@ from wcs.wf.backoffice_fields import SetBackofficeFieldsWorkflowStatusItem
 from wcs.roles import Role
 from wcs.fields import StringField
 
-from qommon.misc import indent_xml as indent
+from wcs.qommon.misc import indent_xml as indent
 
 from utilities import create_temporary_pub, clean_temporary_pub
 
diff --git a/tests/test_workflows.py b/tests/test_workflows.py
index a465b69fe..ccac4141d 100644
--- a/tests/test_workflows.py
+++ b/tests/test_workflows.py
@@ -13,10 +13,10 @@ import mock
 from django.utils.six import StringIO
 
 from quixote import cleanup, get_response
-from qommon.errors import ConnectionError
+from wcs.qommon.errors import ConnectionError
 from quixote.http_request import Upload as QuixoteUpload
 from wcs.qommon.http_request import HTTPRequest
-from qommon.form import *
+from wcs.qommon.form import *
 
 from wcs.formdef import FormDef
 from wcs import sessions
@@ -2221,7 +2221,7 @@ def test_sms_with_passerelle(pub):
     item.body = 'my message'
     with mock.patch('wcs.wscalls.get_secret_and_orig') as mocked_secret_and_orig:
         mocked_secret_and_orig.return_value = ('secret', 'localhost')
-        with mock.patch('qommon.misc._http_request') as mocked_http_post:
+        with mock.patch('wcs.qommon.misc._http_request') as mocked_http_post:
             mocked_http_post.return_value = ('response', '200', 'data', 'headers')
             item.perform(formdata)
             url = mocked_http_post.call_args[0][0]
diff --git a/tests/utilities.py b/tests/utilities.py
index 6fa342111..48660cd0d 100644
--- a/tests/utilities.py
+++ b/tests/utilities.py
@@ -25,8 +25,7 @@ from wcs.users import User
 from wcs.tracking_code import TrackingCode
 import wcs.qommon.emails
 import wcs.qommon.sms
-import qommon.sms
-from qommon.errors import ConnectionError
+from wcs.qommon.errors import ConnectionError
 
 import wcs.middleware
 
@@ -264,18 +263,13 @@ class EmailsMocking(object):
 
     def __enter__(self):
         self.wcs_create_smtp_server = sys.modules['wcs.qommon.emails'].create_smtp_server
-        self.qommon_create_smtp_server = sys.modules['qommon.emails'].create_smtp_server
-
         sys.modules['wcs.qommon.emails'].create_smtp_server = self.create_smtp_server
-        sys.modules['qommon.emails'].create_smtp_server = self.create_smtp_server
-
         self.emails = {}
         return self
 
     def __exit__(self, exc_type, exc_value, tb):
         del self.emails
         sys.modules['wcs.qommon.emails'].create_smtp_server = self.wcs_create_smtp_server
-        sys.modules['qommon.emails'].create_smtp_server = self.qommon_create_smtp_server
 
 
 class MockSubstitutionVariables(object):
@@ -290,24 +284,14 @@ class HttpRequestsMocking(object):
 
     def __enter__(self):
         import wcs.qommon.misc
-        import qommon.misc
-
         self.wcs_qommon_misc_http_request = wcs.qommon.misc._http_request
-        self.qommon_misc_http_request = qommon.misc._http_request
-
         wcs.qommon.misc._http_request = self.http_request
-        qommon.misc._http_request = self.http_request
         return self
 
     def __exit__(self, exc_type, exc_value, tb):
         import wcs.qommon.misc
-        import qommon.misc
-
         wcs.qommon.misc._http_request = self.wcs_qommon_misc_http_request
-        qommon.misc._http_request = self.qommon_misc_http_request
-
         del self.wcs_qommon_misc_http_request
-        del self.qommon_misc_http_request
 
     def http_request(self, url, method='GET', body=None, headers={},
             cert_file=None, timeout=None, raise_on_http_errors=False):
@@ -397,12 +381,9 @@ class SMSMocking(wcs.qommon.sms.MobytSMS):
     def __enter__(self):
         self.sms = []
         self.wcs_get_sms_class = wcs.qommon.sms.SMS.get_sms_class
-        self.qommon_get_sms_class = qommon.sms.SMS.get_sms_class
         wcs.qommon.sms.SMS.get_sms_class = self.get_sms_class
-        qommon.sms.SMS.get_sms_class = self.get_sms_class
         return self
 
     def __exit__(self, exc_type, exc_value, tb):
         del self.sms
         wcs.qommon.sms.SMS.get_sms_class = self.wcs_get_sms_class
-        qommon.sms.SMS.get_sms_class = self.qommon_get_sms_class
diff --git a/wcs/__init__.py b/wcs/__init__.py
index a9923b73c..4ca66c760 100644
--- a/wcs/__init__.py
+++ b/wcs/__init__.py
@@ -18,12 +18,5 @@ import sys
 import os
 sys.path.insert(0, os.path.dirname(__file__))
 
-import monkeypatch
-
-import qommon
-sys.modules['qommon'] = sys.modules['wcs.qommon']
-
-import qommon.form
-sys.modules['form'] = qommon.form
-
-import compat
+from . import monkeypatch
+from . import compat
diff --git a/wcs/admin/__init__.py b/wcs/admin/__init__.py
index 58d0eb15b..e5b328d79 100644
--- a/wcs/admin/__init__.py
+++ b/wcs/admin/__init__.py
@@ -14,4 +14,4 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from root import RootDirectory
+from .root import RootDirectory
diff --git a/wcs/admin/bounces.py b/wcs/admin/bounces.py
index abe3cf1e7..200425164 100644
--- a/wcs/admin/bounces.py
+++ b/wcs/admin/bounces.py
@@ -21,15 +21,15 @@ from quixote import get_response, redirect
 from quixote.directory import Directory
 from quixote.html import htmltext, TemplateIO
 
-from qommon import _
-from qommon import errors
-from qommon import misc
-from qommon.bounces import Bounce
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import command_icon
-
-from qommon.form import *
-from qommon.misc import get_cfg
+from ..qommon import _
+from ..qommon import errors
+from ..qommon import misc
+from ..qommon.bounces import Bounce
+from ..qommon.backoffice.menu import html_top
+from ..qommon.admin.menu import command_icon
+
+from ..qommon.form import *
+from ..qommon.misc import get_cfg
 
 def get_email_type_label(type):
     from settings import EmailsDirectory
diff --git a/wcs/admin/categories.py b/wcs/admin/categories.py
index 30afbf8af..9b55decad 100644
--- a/wcs/admin/categories.py
+++ b/wcs/admin/categories.py
@@ -18,10 +18,10 @@ from quixote import redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
+from ..qommon import _
 from wcs.categories import Category
-from qommon.form import *
-from qommon.backoffice.menu import html_top
+from ..qommon.form import *
+from ..qommon.backoffice.menu import html_top
 
 from wcs.formdef import FormDef
 
diff --git a/wcs/admin/data_sources.py b/wcs/admin/data_sources.py
index 134a9d749..8e3a9015d 100644
--- a/wcs/admin/data_sources.py
+++ b/wcs/admin/data_sources.py
@@ -18,11 +18,11 @@ from quixote import redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon import template
-from qommon.form import *
-from qommon.misc import json_response
-from qommon.backoffice.menu import html_top
+from ..qommon import _
+from ..qommon import template
+from ..qommon.form import *
+from ..qommon.misc import json_response
+from ..qommon.backoffice.menu import html_top
 from wcs.data_sources import (NamedDataSource, DataSourceSelectionWidget,
         get_structured_items)
 from wcs.formdef import FormDef
diff --git a/wcs/admin/fields.py b/wcs/admin/fields.py
index 5242ef3e6..d6264ffea 100644
--- a/wcs/admin/fields.py
+++ b/wcs/admin/fields.py
@@ -20,11 +20,11 @@ from quixote import redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext, htmlescape
 
-from qommon import _
-from qommon.form import *
-from qommon import errors, misc
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import command_icon
+from ..qommon import _
+from ..qommon.form import *
+from ..qommon import errors, misc
+from ..qommon.backoffice.menu import html_top
+from ..qommon.admin.menu import command_icon
 
 from wcs import fields
 from wcs.formdef import FormDef
diff --git a/wcs/admin/forms.py b/wcs/admin/forms.py
index fa94cd081..61f65e671 100644
--- a/wcs/admin/forms.py
+++ b/wcs/admin/forms.py
@@ -28,15 +28,15 @@ from quixote import get_response, redirect
 from quixote.directory import Directory, AccessControlled
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon import misc
-from qommon.errors import *
-from qommon.form import *
-from qommon.backoffice.menu import html_top
-from qommon import get_logger
-from qommon.misc import C_
+from ..qommon import _
+from ..qommon import misc
+from ..qommon.errors import *
+from ..qommon.form import *
+from ..qommon.backoffice.menu import html_top
+from ..qommon import get_logger
+from ..qommon.misc import C_
 
-from qommon.afterjobs import AfterJob
+from ..qommon.afterjobs import AfterJob
 
 from wcs.formdef import FormDef, FormdefImportError, FormdefImportRecoverableError
 from wcs.categories import Category
@@ -44,7 +44,7 @@ from wcs.roles import Role, logged_users_role, get_user_roles
 from wcs.workflows import Workflow
 from wcs.forms.root import qrcode
 
-from fields import FieldDefPage, FieldsDirectory
+from .fields import FieldDefPage, FieldsDirectory
 from .categories import CategoriesDirectory
 from .data_sources import NamedDataSourcesDirectory
 from .logged_errors import LoggedErrorsDirectory
diff --git a/wcs/admin/logged_errors.py b/wcs/admin/logged_errors.py
index 106da8725..4c7fba5eb 100644
--- a/wcs/admin/logged_errors.py
+++ b/wcs/admin/logged_errors.py
@@ -19,9 +19,9 @@ import re
 from quixote import get_response, get_publisher, redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
-from qommon import _, ngettext
-from qommon import errors, get_cfg
-from qommon.misc import localstrftime
+from ..qommon import _, ngettext
+from ..qommon import errors, get_cfg
+from ..qommon.misc import localstrftime
 
 from wcs.logged_errors import LoggedError
 
diff --git a/wcs/admin/roles.py b/wcs/admin/roles.py
index 9d0fe5fb0..353091163 100644
--- a/wcs/admin/roles.py
+++ b/wcs/admin/roles.py
@@ -18,11 +18,11 @@ from quixote import redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _, get_cfg
-from qommon import errors
-from qommon.form import *
+from ..qommon import _, get_cfg
+from ..qommon import errors
+from ..qommon.form import *
 
-from qommon.backoffice.menu import html_top
+from ..qommon.backoffice.menu import html_top
 
 from wcs.roles import Role, get_user_roles
 from wcs.formdef import FormDef
diff --git a/wcs/admin/settings.py b/wcs/admin/settings.py
index 798eb0cef..e9722480b 100644
--- a/wcs/admin/settings.py
+++ b/wcs/admin/settings.py
@@ -33,24 +33,23 @@ from quixote import get_publisher, get_request, get_response, redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon import get_cfg
-from qommon import errors
-from qommon import misc
-from qommon import template
-from qommon.form import *
-from qommon.sms import SMS
-
-from qommon.afterjobs import AfterJob
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import error_page
-from qommon.admin.cfg import cfg_submit
-from qommon.admin.emails import EmailsDirectory
+from ..qommon import _
+from ..qommon import get_cfg
+from ..qommon import errors
+from ..qommon import misc
+from ..qommon import template
+from ..qommon.form import *
+from ..qommon.sms import SMS
+
+from ..qommon.afterjobs import AfterJob
+from ..qommon.backoffice.menu import html_top
+from ..qommon.admin.menu import error_page
+from ..qommon.admin.cfg import cfg_submit
+from ..qommon.admin.emails import EmailsDirectory
 from wcs.qommon.admin.texts import TextsDirectory
-from qommon.admin.settings import SettingsDirectory as QommonSettingsDirectory
-from qommon.admin.logger import LoggerDirectory
-import qommon.ident
-import qommon.template
+from ..qommon.admin.settings import SettingsDirectory as QommonSettingsDirectory
+from ..qommon.admin.logger import LoggerDirectory
+from ..qommon import ident
 
 from wcs.formdef import FormDef
 from wcs.carddef import CardDef
@@ -108,7 +107,7 @@ authentication is unavailable. Lasso must be installed to use it.'))
 
     def _q_lookup(self, component):
         get_response().breadcrumb.append( ('identification/', _('Identification')) )
-        return qommon.ident.get_method_admin_directory(component)
+        return ident.get_method_admin_directory(component)
 
 
 class UserFieldDefPage(FieldDefPage):
@@ -204,7 +203,7 @@ class UserFieldsFormDef(FormDef):
         self.publisher.cfg['users'] = users_cfg
         self.publisher.write_cfg()
         if self.publisher.is_using_postgresql():
-            import sql
+            from wcs import sql
             sql.do_user_table()
             sql.do_tracking_code_table()
             sql.do_session_table()
@@ -371,12 +370,12 @@ class ThemePreviewDirectory(Directory):
 
         if path[1] in ('backoffice', 'admin') or \
                 get_request().get_method() == 'POST':
-            from qommon.template import error_page as base_error_page
+            from ..qommon.template import error_page as base_error_page
             output = base_error_page(_("The theme preview doesn't support this."))
         else:
             output = root_directory._q_traverse(path[1:])
 
-        from qommon.template import decorate
+        from ..qommon.template import decorate
         if isinstance(output, template.QommonTemplateResponse):
             output = template.render(output.templates, output.context)
         theme_preview = decorate(output, response)
@@ -440,7 +439,7 @@ class SettingsDirectory(QommonSettingsDirectory):
             identification_cfg = get_cfg('identification', {})
             for method in identification_cfg.get('methods', []):
                 try:
-                    method_admin = qommon.ident.get_method_admin_directory(method)
+                    method_admin = ident.get_method_admin_directory(method)
                 except AttributeError:
                     continue
 
@@ -637,7 +636,7 @@ class SettingsDirectory(QommonSettingsDirectory):
             r += htmltext('<a rel="popup" href="install_theme">%s</a>') % _('Install New Theme')
 
             r += htmltext('<form action="themes" enctype="multipart/form-data" method="post">')
-            themes = qommon.template.get_themes_dict()
+            themes = template.get_themes_dict()
             r += htmltext('<ul class="biglist themes">')
             for theme, theme_dict in sorted(themes.items()):
                 label = theme_dict.get('label')
@@ -670,7 +669,7 @@ class SettingsDirectory(QommonSettingsDirectory):
             r += htmltext('</form>')
             return r.getvalue()
         else:
-            themes = qommon.template.get_themes()
+            themes = template.get_themes()
             if themes.has_key(str(request.form['theme'])):
                 branding_cfg = get_cfg('branding', {})
                 branding_cfg[str('theme')] = str(request.form['theme'])
@@ -683,7 +682,7 @@ class SettingsDirectory(QommonSettingsDirectory):
         if not theme_id:
             return redirect('themes')
 
-        theme_directory = qommon.template.get_theme_directory(theme_id)
+        theme_directory = template.get_theme_directory(theme_id)
         if not theme_directory:
             return redirect('themes')
 
@@ -752,7 +751,7 @@ class SettingsDirectory(QommonSettingsDirectory):
             get_session().message = ('error', _('Theme is missing a desc.xml file.'))
             return redirect('themes')
         desc_xml = z.read('%s/desc.xml' % theme_name)
-        theme_dict = qommon.template.get_theme_dict(StringIO(desc_xml))
+        theme_dict = template.get_theme_dict(StringIO(desc_xml))
         if theme_dict.get('name') != theme_name:
             get_session().message = ('error', _('desc.xml is missing a name attribute.'))
             return redirect('themes')
@@ -779,7 +778,7 @@ class SettingsDirectory(QommonSettingsDirectory):
         return self.install_theme_from_file(StringIO(fp.read()))
 
     def template(self):
-        from qommon.template import get_default_ezt_template
+        from wcs.qommon.template import get_default_ezt_template
         default_template_ezt = get_default_ezt_template()
         branding_cfg = get_cfg('branding', {})
         template = branding_cfg.get('template', default_template_ezt)
@@ -811,7 +810,7 @@ class SettingsDirectory(QommonSettingsDirectory):
         return r.getvalue()
 
     def template_submit(self, form = None):
-        from qommon.template import DEFAULT_TEMPLATE_EZT, get_default_ezt_template
+        from wcs.qommon.template import DEFAULT_TEMPLATE_EZT, get_default_ezt_template
         theme_default_template_ezt = get_default_ezt_template()
 
         get_publisher().reload_cfg()
diff --git a/wcs/admin/users.py b/wcs/admin/users.py
index 48d1cd3c7..03f0ace87 100644
--- a/wcs/admin/users.py
+++ b/wcs/admin/users.py
@@ -18,19 +18,19 @@ from quixote import get_publisher, get_response, get_request, get_session, redir
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
+from ..qommon import _
 import wcs.qommon.storage as st
-from qommon import errors
-from qommon import misc, get_cfg
-from qommon.backoffice.listing import pagination_links
+from ..qommon import errors
+from ..qommon import misc, get_cfg
+from ..qommon.backoffice.listing import pagination_links
 from wcs.roles import Role
 
-import qommon.ident
-from qommon.ident.idp import is_idp_managing_user_attributes, is_idp_managing_user_roles
-from qommon.form import *
-from qommon.admin.emails import EmailsDirectory
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import error_page
+from ..qommon import ident
+from ..qommon.ident.idp import is_idp_managing_user_attributes, is_idp_managing_user_roles
+from ..qommon.form import *
+from ..qommon.admin.emails import EmailsDirectory
+from ..qommon.backoffice.menu import html_top
+from ..qommon.admin.menu import error_page
 
 class UserUI(object):
     def __init__(self, user):
@@ -65,7 +65,7 @@ class UserUI(object):
                         'render_br': False,
                         'options': [(None, '---', None)] + [(x.id, x.name, x.id) for x in roles]})
 
-        for klass in [x for x in qommon.ident.get_method_classes() if x.key in ident_methods]:
+        for klass in [x for x in ident.get_method_classes() if x.key in ident_methods]:
             if klass.method_admin_widget:
                 value = klass().get_value(self.user)
                 form.add(klass.method_admin_widget, 'method_%s' % klass.key, required = False,
@@ -94,7 +94,7 @@ class UserUI(object):
         self.user.store()
 
         ident_methods = get_cfg('identification', {}).get('methods', [])
-        for klass in [x for x in qommon.ident.get_method_classes() if x.key in ident_methods]:
+        for klass in [x for x in ident.get_method_classes() if x.key in ident_methods]:
             widget = form.get_widget('method_%s' % klass.key)
             if widget:
                 klass().submit(self.user, widget)
@@ -229,7 +229,7 @@ class UserPage(Directory):
 
         for method in ident_methods:
             try:
-                actions = qommon.ident.get_method_user_directory(
+                actions = ident.get_method_user_directory(
                                 method, self.user).get_actions()
             except AttributeError:
                 continue
@@ -283,7 +283,7 @@ class UserPage(Directory):
             return r.getvalue()
         else:
             ident_methods = get_cfg('identification', {}).get('methods', [])
-            for klass in [x for x in qommon.ident.get_method_classes() if x.key in ident_methods]:
+            for klass in [x for x in ident.get_method_classes() if x.key in ident_methods]:
                 if hasattr(klass, str('delete')):
                     klass().delete(self.user)
             self.user.remove_self()
@@ -293,7 +293,7 @@ class UserPage(Directory):
         ident_methods = get_cfg('identification', {}).get('methods', [])
         if component in ident_methods:
             get_response().breadcrumb.append((component + '/', None))
-            return qommon.ident.get_method_user_directory(component, self.user)
+            return ident.get_method_user_directory(component, self.user)
 
 class UsersDirectory(Directory):
     _q_exports = ['', 'new']
diff --git a/wcs/admin/workflows.py b/wcs/admin/workflows.py
index 87c6ae984..5b66a11d5 100644
--- a/wcs/admin/workflows.py
+++ b/wcs/admin/workflows.py
@@ -27,13 +27,13 @@ from quixote import redirect, get_publisher
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon import errors
-from qommon import misc
-from qommon.form import *
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import command_icon
-from qommon import get_logger
+from ..qommon import _
+from ..qommon import errors
+from ..qommon import misc
+from ..qommon.form import *
+from ..qommon.backoffice.menu import html_top
+from ..qommon.admin.menu import command_icon
+from ..qommon import get_logger
 
 from wcs.workflows import *
 from wcs.carddef import CardDef
diff --git a/wcs/admin/wscalls.py b/wcs/admin/wscalls.py
index adf69f0ec..cba776208 100644
--- a/wcs/admin/wscalls.py
+++ b/wcs/admin/wscalls.py
@@ -18,10 +18,10 @@ from quixote import redirect
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon import errors
-from qommon.form import *
-from qommon.backoffice.menu import html_top
+from ..qommon import _
+from ..qommon import errors
+from ..qommon.form import *
+from ..qommon.backoffice.menu import html_top
 from wcs.wscalls import NamedWsCall, WsCallRequestWidget
 
 class NamedWsCallUI(object):
diff --git a/wcs/api.py b/wcs/api.py
index 20869f18e..6f5243ced 100644
--- a/wcs/api.py
+++ b/wcs/api.py
@@ -25,12 +25,12 @@ from quixote.directory import Directory
 from django.utils.six.moves.urllib import parse as urllib
 from django.http import HttpResponse, HttpResponseBadRequest
 
-from qommon import _
-from qommon import misc
-from qommon.evalutils import make_datetime
-from qommon.errors import (AccessForbiddenError, QueryError, TraversalError,
+from .qommon import _
+from .qommon import misc
+from .qommon.evalutils import make_datetime
+from .qommon.errors import (AccessForbiddenError, QueryError, TraversalError,
     UnknownNameIdAccessForbiddenError, RequestError)
-from qommon.form import ComputedExpressionWidget, ConditionWidget
+from .qommon.form import ComputedExpressionWidget, ConditionWidget
 
 from wcs.categories import Category
 from wcs.conditions import Condition, ValidationError
@@ -42,8 +42,8 @@ from wcs.forms.common import FormStatusPage
 import wcs.qommon.storage as st
 from wcs.api_utils import sign_url_auto_orig, is_url_signed, get_user_from_api_query_string
 
-from backoffice.management import FormPage as BackofficeFormPage
-from backoffice.management import ManagementDirectory
+from .backoffice.management import FormPage as BackofficeFormPage
+from .backoffice.management import ManagementDirectory
 
 def posted_json_data_to_formdata_data(formdef, data):
     # remap fields from varname to field id
@@ -632,7 +632,7 @@ class ApiUserDirectory(Directory):
 
         if get_publisher().is_using_postgresql() and not get_request().form.get('full') == 'on':
             from wcs import sql
-            from qommon.storage import Equal
+            from .qommon.storage import Equal
             order_by = 'receipt_time'
             if get_request().form.get('sort') == 'desc':
                 order_by = '-receipt_time'
diff --git a/wcs/api_utils.py b/wcs/api_utils.py
index bbacbfd8a..1e1adf1ff 100644
--- a/wcs/api_utils.py
+++ b/wcs/api_utils.py
@@ -27,7 +27,7 @@ from django.utils.six.moves.urllib import parse as urllib
 from django.utils.six.moves.urllib import parse as urlparse
 
 from quixote import get_request, get_publisher
-from qommon.errors import (AccessForbiddenError, UnknownNameIdAccessForbiddenError)
+from .qommon.errors import (AccessForbiddenError, UnknownNameIdAccessForbiddenError)
 import qommon.misc
 
 DEFAULT_DURATION = 30
diff --git a/wcs/backoffice/__init__.py b/wcs/backoffice/__init__.py
index 58d0eb15b..e5b328d79 100644
--- a/wcs/backoffice/__init__.py
+++ b/wcs/backoffice/__init__.py
@@ -14,4 +14,4 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from root import RootDirectory
+from .root import RootDirectory
diff --git a/wcs/backoffice/cards.py b/wcs/backoffice/cards.py
index 1f18a686a..7749c0251 100644
--- a/wcs/backoffice/cards.py
+++ b/wcs/backoffice/cards.py
@@ -21,8 +21,8 @@ import time
 from quixote import get_publisher, get_request, get_response, get_session, redirect
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _, misc
-from qommon.misc import C_
+from ..qommon import _, misc
+from ..qommon.misc import C_
 
 from wcs.carddef import CardDef
 from wcs.roles import Role
diff --git a/wcs/backoffice/data_management.py b/wcs/backoffice/data_management.py
index 17ebbb548..747d864e6 100644
--- a/wcs/backoffice/data_management.py
+++ b/wcs/backoffice/data_management.py
@@ -17,9 +17,9 @@
 from quixote import get_request, get_response, get_session, redirect
 from quixote.html import TemplateIO, htmltext, htmlescape
 
-from qommon import _
-from qommon import errors
-from qommon.backoffice.menu import html_top
+from ..qommon import _
+from ..qommon import errors
+from ..qommon.backoffice.menu import html_top
 
 from wcs.carddef import CardDef
 from .management import ManagementDirectory, FormPage, FormFillPage, FormBackOfficeStatusPage
diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py
index a41f4ff23..555e23d22 100644
--- a/wcs/backoffice/management.py
+++ b/wcs/backoffice/management.py
@@ -33,21 +33,21 @@ from quixote import get_session, get_publisher, get_request, get_response, redir
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext, htmlescape
 
-from qommon import _, ngettext, ezt
-from qommon.admin.emails import EmailsDirectory
-from qommon.admin.menu import command_icon
-from qommon.backoffice.menu import html_top
-from qommon.backoffice.listing import pagination_links
-from qommon import misc, get_logger
-from qommon.evalutils import make_datetime
-from qommon.misc import C_, ellipsize
-from qommon.afterjobs import AfterJob
-from qommon import emails
-import qommon.sms
-from qommon import errors
-from qommon import ods
-from qommon.form import *
-from qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
+from ..qommon import _, ngettext, ezt
+from ..qommon.admin.emails import EmailsDirectory
+from ..qommon.admin.menu import command_icon
+from ..qommon.backoffice.menu import html_top
+from ..qommon.backoffice.listing import pagination_links
+from ..qommon import misc, get_logger
+from ..qommon.evalutils import make_datetime
+from ..qommon.misc import C_, ellipsize
+from ..qommon.afterjobs import AfterJob
+from ..qommon import emails
+from ..qommon import sms
+from ..qommon import errors
+from ..qommon import ods
+from ..qommon.form import *
+from ..qommon.storage import (Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or,
         Intersects, ILike, FtsMatch, Contains, Null)
 
 from wcs.api_utils import get_user_from_api_query_string
@@ -142,7 +142,7 @@ class SendCodeFormdefDirectory(Directory):
         if get_publisher().use_sms_feature:
             sms_cfg = get_cfg('sms', {})
             mode = sms_cfg.get('mode', 'none')
-            sms_class = qommon.sms.SMS.get_sms_class(mode)
+            sms_class = sms.SMS.get_sms_class(mode)
             if sms_class:
                 form.add(StringWidget, 'sms', title=_('SMS Number'), required=False)
                 form.add(RadiobuttonsWidget, 'method',
diff --git a/wcs/backoffice/root.py b/wcs/backoffice/root.py
index d598c1264..d1793b001 100644
--- a/wcs/backoffice/root.py
+++ b/wcs/backoffice/root.py
@@ -19,13 +19,13 @@ from django.utils.translation import pgettext
 from quixote import get_publisher, get_request, get_response, redirect
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon.backoffice import BackofficeRootDirectory
-from qommon.backoffice.menu import html_top
+from ..qommon import _
+from ..qommon.backoffice import BackofficeRootDirectory
+from ..qommon.backoffice.menu import html_top
 
-from qommon import misc, get_cfg
-from qommon import errors
-from qommon.form import *
+from ..qommon import misc, get_cfg
+from ..qommon import errors
+from ..qommon.form import *
 
 from wcs.formdef import FormDef
 
@@ -202,7 +202,7 @@ class RootDirectory(BackofficeRootDirectory):
         return r.getvalue()
 
     def get_sidebar(self):
-        from qommon.admin.menu import get_vc_version
+        from ..qommon.admin.menu import get_vc_version
         r = TemplateIO(html=True)
 
         r += htmltext('<div class="bo-block">')
diff --git a/wcs/backoffice/studio.py b/wcs/backoffice/studio.py
index ce799fea4..e49103d2e 100644
--- a/wcs/backoffice/studio.py
+++ b/wcs/backoffice/studio.py
@@ -16,9 +16,9 @@
 
 from quixote import get_publisher
 from quixote.directory import Directory
-from qommon import _
-from qommon.backoffice.menu import html_top
-from qommon import template
+from ..qommon import _
+from ..qommon.backoffice.menu import html_top
+from ..qommon import template
 
 
 class StudioDirectory(Directory):
diff --git a/wcs/backoffice/submission.py b/wcs/backoffice/submission.py
index 3ca6bc292..af358ff66 100644
--- a/wcs/backoffice/submission.py
+++ b/wcs/backoffice/submission.py
@@ -22,10 +22,10 @@ from quixote import get_publisher, get_request, get_response, get_session, redir
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon.backoffice.menu import html_top
-from qommon.form import *
-from qommon import errors, misc
+from ..qommon import _
+from ..qommon.backoffice.menu import html_top
+from ..qommon.form import *
+from ..qommon import errors, misc
 
 from wcs.formdata import FormData
 from wcs.formdef import FormDef
diff --git a/wcs/carddef.py b/wcs/carddef.py
index 4471ec8ab..c12eb7133 100644
--- a/wcs/carddef.py
+++ b/wcs/carddef.py
@@ -18,7 +18,7 @@ import new
 import sys
 
 from quixote import get_publisher
-from qommon import _
+from .qommon import _
 
 from wcs.carddata import CardData
 from wcs.formdef import FormDef
diff --git a/wcs/categories.py b/wcs/categories.py
index 611e7f1f4..0253864b1 100644
--- a/wcs/categories.py
+++ b/wcs/categories.py
@@ -17,11 +17,11 @@
 from quixote import get_publisher, get_response
 from quixote.html import htmltext
 
-from qommon import _
-from qommon.storage import StorableObject
-from qommon.misc import simplify
-from qommon.substitution import Substitutions
-from qommon.xml_storage import XmlStorableObject
+from .qommon import _
+from .qommon.storage import StorableObject
+from .qommon.misc import simplify
+from .qommon.substitution import Substitutions
+from .qommon.xml_storage import XmlStorableObject
 
 class Category(XmlStorableObject):
     _names = 'categories'
diff --git a/wcs/conditions.py b/wcs/conditions.py
index 89727c180..630fe229f 100644
--- a/wcs/conditions.py
+++ b/wcs/conditions.py
@@ -19,8 +19,8 @@ import sys
 from quixote import get_publisher
 from django.template import Context, Template, TemplateSyntaxError
 
-from qommon import _, get_logger
-from qommon.misc import site_encode
+from .qommon import _, get_logger
+from .qommon.misc import site_encode
 
 
 class ValidationError(ValueError):
diff --git a/wcs/ctl/backup.py b/wcs/ctl/backup.py
index cbd678eda..694987af7 100644
--- a/wcs/ctl/backup.py
+++ b/wcs/ctl/backup.py
@@ -18,7 +18,7 @@ import tarfile
 import time
 import os
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 
 class CmdBackup(Command):
diff --git a/wcs/ctl/check_hobos.py b/wcs/ctl/check_hobos.py
index 4dd3d0e0a..32afd9951 100644
--- a/wcs/ctl/check_hobos.py
+++ b/wcs/ctl/check_hobos.py
@@ -25,9 +25,9 @@ import urlparse
 import hashlib
 
 from quixote import cleanup
-from qommon import misc
-from qommon.ctl import Command, make_option
-from qommon.storage import atomic_write
+from ..qommon import misc
+from ..qommon.ctl import Command, make_option
+from ..qommon.storage import atomic_write
 
 from wcs.admin.settings import UserFieldsFormDef
 from wcs.fields import StringField, EmailField, DateField
@@ -299,7 +299,7 @@ class CmdCheckHobos(Command):
 
         # initialize service provider side
         if not pub.cfg['sp'].get('publickey'):
-            from qommon.ident.idp import MethodAdminDirectory
+            from ..qommon.ident.idp import MethodAdminDirectory
             spconfig = pub.cfg['sp']
             spconfig['saml2_base_url'] = str(service.get('base_url')) + '/saml'
             spconfig['saml2_providerid'] = spconfig['saml2_base_url'] + '/metadata'
@@ -329,7 +329,7 @@ class CmdCheckHobos(Command):
             (bfd, metadata_pathname) = tempfile.mkstemp('.metadata')
             atomic_write(metadata_pathname, s)
 
-            from qommon.ident.idp import AdminIDPDir
+            from ..qommon.ident.idp import AdminIDPDir
             admin_dir = AdminIDPDir()
             key_provider_id = admin_dir.submit_new_remote(
                     metadata_pathname, None, metadata_url, None)
diff --git a/wcs/ctl/delete_tenant.py b/wcs/ctl/delete_tenant.py
index bffc767b3..20d6ad62a 100644
--- a/wcs/ctl/delete_tenant.py
+++ b/wcs/ctl/delete_tenant.py
@@ -21,7 +21,7 @@ import psycopg2.errorcodes
 from datetime import datetime
 from shutil import rmtree
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 
 class CmdDeleteTenant(Command):
diff --git a/wcs/ctl/export_settings.py b/wcs/ctl/export_settings.py
index 4f38b7724..4f1a50fdd 100644
--- a/wcs/ctl/export_settings.py
+++ b/wcs/ctl/export_settings.py
@@ -16,7 +16,7 @@
 
 import os
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 class CmdExportSettings(Command):
     name = 'export_settings'
diff --git a/wcs/ctl/hobo_notify.py b/wcs/ctl/hobo_notify.py
index a8be001ac..7558ae94e 100644
--- a/wcs/ctl/hobo_notify.py
+++ b/wcs/ctl/hobo_notify.py
@@ -20,8 +20,8 @@ import json
 
 from quixote import get_publisher
 from wcs.roles import Role
-from qommon.ctl import Command
-from qommon.publisher import get_cfg
+from ..qommon.ctl import Command
+from ..qommon.publisher import get_cfg
 from wcs.admin.settings import UserFieldsFormDef
 from wcs.qommon.misc import json_encode_helper
 
diff --git a/wcs/ctl/management/commands/__init__.py b/wcs/ctl/management/commands/__init__.py
index e6d3d54a4..d3c2eccb5 100644
--- a/wcs/ctl/management/commands/__init__.py
+++ b/wcs/ctl/management/commands/__init__.py
@@ -18,7 +18,7 @@ import os
 
 from django.core.management.base import BaseCommand, CommandError
 
-from qommon.publisher import get_publisher_class
+from wcs.qommon.publisher import get_publisher_class
 
 
 class TenantCommand(BaseCommand):
diff --git a/wcs/ctl/management/commands/convert_to_sql.py b/wcs/ctl/management/commands/convert_to_sql.py
index 4cc99af06..4516b78f1 100644
--- a/wcs/ctl/management/commands/convert_to_sql.py
+++ b/wcs/ctl/management/commands/convert_to_sql.py
@@ -23,7 +23,7 @@ import traceback
 from django.core.management.base import BaseCommand
 from django.core.management.base import CommandError
 
-from qommon.publisher import get_publisher_class
+from wcs.qommon.publisher import get_publisher_class
 
 from wcs import sql
 from wcs.formdef import FormDef
diff --git a/wcs/ctl/management/commands/runscript.py b/wcs/ctl/management/commands/runscript.py
index b9364c0fc..96649baf1 100644
--- a/wcs/ctl/management/commands/runscript.py
+++ b/wcs/ctl/management/commands/runscript.py
@@ -21,7 +21,7 @@ import sys
 
 from django.core.management.base import CommandError
 
-from qommon.publisher import get_publisher_class
+from wcs.qommon.publisher import get_publisher_class
 
 from . import TenantCommand
 
diff --git a/wcs/ctl/process_bounce.py b/wcs/ctl/process_bounce.py
index 18cbe8b87..32ab89dc8 100644
--- a/wcs/ctl/process_bounce.py
+++ b/wcs/ctl/process_bounce.py
@@ -21,7 +21,7 @@ import email.Parser
 
 from Bouncers import BouncerAPI
 
-from qommon.ctl import Command
+from ..qommon.ctl import Command
 
 COMMA_SPACE = ', '
 
@@ -29,10 +29,10 @@ class CmdProcessBounce(Command):
     name = 'process_bounce'
 
     def execute(self, base_options, sub_options, args):
-        from qommon.tokens import Token
-        from qommon.bounces import Bounce
+        from ..qommon.tokens import Token
+        from ..qommon.bounces import Bounce
 
-        import publisher
+        from .. import publisher
 
         try:
             publisher.WcsPublisher.configure(self.config)
diff --git a/wcs/ctl/rebuild_indexes.py b/wcs/ctl/rebuild_indexes.py
index 9b865a0a8..5e5ee493d 100644
--- a/wcs/ctl/rebuild_indexes.py
+++ b/wcs/ctl/rebuild_indexes.py
@@ -16,7 +16,7 @@
 
 import os
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 def rebuild_vhost_indexes(pub, destroy=False):
     from wcs.formdef import FormDef
diff --git a/wcs/ctl/restore.py b/wcs/ctl/restore.py
index 60269195e..163657178 100644
--- a/wcs/ctl/restore.py
+++ b/wcs/ctl/restore.py
@@ -18,7 +18,7 @@ import sys
 import tarfile
 import os
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 
 class CmdRestore(Command):
diff --git a/wcs/ctl/runscript.py b/wcs/ctl/runscript.py
index b01a271a0..4fd04bf75 100644
--- a/wcs/ctl/runscript.py
+++ b/wcs/ctl/runscript.py
@@ -19,7 +19,7 @@ import runpy
 import warnings
 import sys
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 class CmdRunScript(Command):
     '''Run a script within a given host publisher context'''
diff --git a/wcs/ctl/shell.py b/wcs/ctl/shell.py
index 58d55e0a4..a8520b3dd 100644
--- a/wcs/ctl/shell.py
+++ b/wcs/ctl/shell.py
@@ -21,7 +21,7 @@
 
 import os.path
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 class CmdShell(Command):
     '''Launch a shell and initialize a publisher on a given host'''
diff --git a/wcs/ctl/wipe_data.py b/wcs/ctl/wipe_data.py
index 74595025a..341f28923 100644
--- a/wcs/ctl/wipe_data.py
+++ b/wcs/ctl/wipe_data.py
@@ -17,7 +17,7 @@
 import os
 import sys
 
-from qommon.ctl import Command, make_option
+from ..qommon.ctl import Command, make_option
 
 class CmdWipeData(Command):
     name = 'wipe-data'
diff --git a/wcs/data_sources.py b/wcs/data_sources.py
index d34179dfa..1f1384e24 100644
--- a/wcs/data_sources.py
+++ b/wcs/data_sources.py
@@ -24,18 +24,18 @@ from django.utils.six.moves.urllib import parse as urlparse
 from quixote import get_publisher, get_request, get_session
 from quixote.html import TemplateIO
 
-from qommon import _
-from qommon.form import *
-from qommon.humantime import seconds2humanduration
-from qommon.misc import get_variadic_url
-import qommon.misc
-from qommon import get_logger
+from .qommon import _
+from .qommon.form import *
+from .qommon.humantime import seconds2humanduration
+from .qommon.misc import get_variadic_url
+from .qommon import misc
+from .qommon import get_logger
 
-from qommon.storage import StorableObject
-from qommon.template import Template
-from qommon.xml_storage import XmlStorableObject
+from .qommon.storage import StorableObject
+from .qommon.template import Template
+from .qommon.xml_storage import XmlStorableObject
 
-from wcs.api_utils import sign_url_auto_orig
+from .api_utils import sign_url_auto_orig
 
 
 data_source_functions = {}
@@ -63,7 +63,7 @@ class DataSourceSelectionWidget(CompositeWidget):
                 ('carddef:%s' % x.url_name, x.name, 'carddef:%s' % x.url_name)
                 for x in CardDef.select(lightweight=True, ignore_errors=True)
                 if x.digest_template])
-            options.sort(key=lambda x: qommon.misc.simplify(x[1]))
+            options.sort(key=lambda x: misc.simplify(x[1]))
 
         options.insert(0, (None, _('None'), None))
         options.append(('json', _('JSON URL'), 'json'))
@@ -124,7 +124,7 @@ def get_structured_items(data_source, mode=None):
         items = [x.get_data_source_structured_item()
                  for x in carddef.data_class().select()
                  if not x.is_draft()]
-        items.sort(key=lambda x: qommon.misc.simplify(x['text']))
+        items.sort(key=lambda x: misc.simplify(x['text']))
         return items
 
     if data_source.get('type') not in ('json', 'jsonp', 'formula'):
@@ -154,7 +154,7 @@ def get_structured_items(data_source, mode=None):
                 return []
             if len(value) == 0:
                 return []
-            value = qommon.misc.json_encode_helper(value, get_publisher().site_charset)
+            value = misc.json_encode_helper(value, get_publisher().site_charset)
             if isinstance(value[0], list) or isinstance(value[0], tuple):
                 if len(value[0]) >= 3:
                     return [{'id': x[0], 'text': x[1], 'key': x[2]} for x in value]
@@ -196,7 +196,7 @@ def get_structured_items(data_source, mode=None):
         unsigned_url = url
         url = sign_url_auto_orig(url)
         try:
-            entries = qommon.misc.json_loads(qommon.misc.urlopen(url).read())
+            entries = misc.json_loads(misc.urlopen(url).read())
             if type(entries) is not dict:
                 raise ValueError('not a json dict')
             if type(entries.get('data')) is not list:
@@ -216,7 +216,7 @@ def get_structured_items(data_source, mode=None):
                 cache.set(cache_key, items, cache_duration)
 
             return items
-        except qommon.misc.ConnectionError as e:
+        except misc.ConnectionError as e:
             get_logger().warn('Error loading JSON data source (%s)' % str(e))
         except ValueError as e:
             get_logger().warn('Error reading JSON data source output (%s)' % str(e))
@@ -300,7 +300,7 @@ class NamedDataSource(XmlStorableObject):
         super(NamedDataSource, self).store()
 
     def get_new_slug(self):
-        new_slug = qommon.misc.simplify(self.name, space='_')
+        new_slug = misc.simplify(self.name, space='_')
         base_new_slug = new_slug
         suffix_no = 0
         while True:
@@ -369,7 +369,7 @@ class NamedDataSource(XmlStorableObject):
 
         unsigned_url = url
         url = sign_url_auto_orig(url)
-        resp = qommon.misc.urlopen(url).read()
+        resp = misc.urlopen(url).read()
         if hasattr(request, 'datasources_cache'):
             request.datasources_cache[unsigned_url] = resp
         return resp
@@ -384,7 +384,7 @@ class NamedDataSource(XmlStorableObject):
         value = None
         if self.type == 'json' and self.id_parameter:
             resp = self.load_json(self.id_parameter, option_id)
-            response = qommon.misc.json_loads(resp)
+            response = misc.json_loads(resp)
             if response['data']:
                 value = response['data'][0]
         else:
diff --git a/wcs/fields.py b/wcs/fields.py
index 717cc8c65..3f6537e85 100644
--- a/wcs/fields.py
+++ b/wcs/fields.py
@@ -33,16 +33,16 @@ from django.utils.formats import date_format as django_date_format
 from django.utils.html import urlize
 from django.utils.six.moves.html_parser import HTMLParser
 
-from qommon import _
-from qommon import evalutils
-from qommon.form import *
-from qommon.misc import localstrftime, strftime, date_format, ellipsize, can_thumbnail
-from qommon.template import Template, TemplateError
-from qommon import get_cfg, get_logger
-
-import data_sources
-import portfolio
-from conditions import Condition
+from .qommon import _
+from .qommon import evalutils
+from .qommon.form import *
+from .qommon.misc import localstrftime, strftime, date_format, ellipsize, can_thumbnail
+from .qommon.template import Template, TemplateError
+from .qommon import get_cfg, get_logger
+
+from . import data_sources
+from . import portfolio
+from .conditions import Condition
 
 
 class PrefillSelectionWidget(CompositeWidget):
diff --git a/wcs/formdata.py b/wcs/formdata.py
index bfb98d543..b99522411 100644
--- a/wcs/formdata.py
+++ b/wcs/formdata.py
@@ -25,16 +25,16 @@ import time
 from quixote import get_request, get_publisher, get_session
 from quixote.http_request import Upload
 
-from qommon import _
-from qommon.storage import StorableObject, Intersects, Contains
-import qommon.misc
-from qommon.evalutils import make_datetime
-from qommon.publisher import get_cfg
-from qommon.substitution import Substitutions, invalidate_substitution_cache
-from qommon.template import Template
+from .qommon import _
+from .qommon.storage import StorableObject, Intersects, Contains
+from .qommon import misc
+from .qommon.evalutils import make_datetime
+from .qommon.publisher import get_cfg
+from .qommon.substitution import Substitutions, invalidate_substitution_cache
+from .qommon.template import Template
 
-from roles import Role
-from fields import FileField
+from .roles import Role
+from .fields import FileField
 
 
 def get_dict_with_varnames(fields, data, formdata=None, varnames_only=False):
@@ -58,7 +58,7 @@ def get_dict_with_varnames(fields, data, formdata=None, varnames_only=False):
             new_data['f%s' % field.id.replace('-', '_')] = value
 
             # also add it as 'field_' + normalized(field label)
-            identifier_name = qommon.misc.simplify(field.label, space = '_')
+            identifier_name = misc.simplify(field.label, space = '_')
             new_data['field_' + identifier_name] = value
 
         # and finally add it as its manually defined variable name
@@ -638,9 +638,9 @@ class FormData(StorableObject):
         if field.type == 'display_name':
             return self.get_display_name()
         if field.type == 'time':
-            return qommon.misc.localstrftime(self.receipt_time)
+            return misc.localstrftime(self.receipt_time)
         if field.type == 'last_update_time':
-            return qommon.misc.localstrftime(self.last_update_time)
+            return misc.localstrftime(self.last_update_time)
         if field.type == 'user-label':
             return self.get_user_label() or '-'
         if field.type == 'status':
@@ -685,8 +685,8 @@ class FormData(StorableObject):
 
         if self.id:
             d.update({
-                'form_receipt_date': qommon.misc.strftime(qommon.misc.date_format(), self.receipt_time),
-                'form_receipt_time': qommon.misc.strftime('%H:%M', self.receipt_time),
+                'form_receipt_date': misc.strftime(misc.date_format(), self.receipt_time),
+                'form_receipt_time': misc.strftime('%H:%M', self.receipt_time),
                 'form_number': str(self.get_display_id()),
                 'form_number_raw': '%s' % self.id,
                 'form_url': self.get_url(),
@@ -823,7 +823,7 @@ class FormData(StorableObject):
         return d
 
     def get_substitution_variables(self, minimal=False):
-        from qommon.substitution import CompatibilityNamesDict
+        from .qommon.substitution import CompatibilityNamesDict
         from wcs.variables import LazyFormData
         from wcs.workflows import AttachmentsSubstitutionProxy
         variables = CompatibilityNamesDict({
@@ -1080,7 +1080,7 @@ class FormData(StorableObject):
     def export_to_json(self, include_files=True, anonymise=False):
         data = self.get_json_export_dict(include_files=include_files, anonymise=anonymise)
         return json.dumps(data,
-                cls=qommon.misc.JSONEncoder,
+                cls=misc.JSONEncoder,
                 encoding=get_publisher().site_charset)
 
     def mark_as_being_visited(self):
diff --git a/wcs/formdef.py b/wcs/formdef.py
index 665e495a3..716a80fe1 100644
--- a/wcs/formdef.py
+++ b/wcs/formdef.py
@@ -27,20 +27,20 @@ import datetime
 from quixote import get_request, get_publisher
 from quixote.http_request import Upload
 
-from qommon import _
-from qommon.storage import StorableObject, fix_key
-from qommon.cron import CronJob
-from qommon.form import *
-from qommon.misc import simplify, get_as_datetime
-from qommon import get_cfg
-from qommon.substitution import Substitutions
-from qommon.publisher import get_publisher_class
-
-from formdata import FormData
-from roles import Role, logged_users_role
-from categories import Category
-import fields
-import data_sources
+from .qommon import _
+from .qommon.storage import StorableObject, fix_key
+from .qommon.cron import CronJob
+from .qommon.form import *
+from .qommon.misc import simplify, get_as_datetime
+from .qommon import get_cfg
+from .qommon.substitution import Substitutions
+from .qommon.publisher import get_publisher_class
+
+from .formdata import FormData
+from .roles import Role, logged_users_role
+from .categories import Category
+from . import fields
+from . import data_sources
 
 
 class FormdefImportError(Exception):
@@ -1252,7 +1252,7 @@ class FormDef(StorableObject):
         return d
 
     def get_substitution_variables(self, minimal=False):
-        from qommon.substitution import CompatibilityNamesDict
+        from .qommon.substitution import CompatibilityNamesDict
         from wcs.variables import LazyFormDef
         return CompatibilityNamesDict({'form': LazyFormDef(self)})
 
@@ -1462,7 +1462,7 @@ class FormDef(StorableObject):
         return pickle.dumps(object, protocol=2) + pickle.dumps(object.fields, protocol=2)
 
 
-from qommon.admin.emails import EmailsDirectory
+from .qommon.admin.emails import EmailsDirectory
 
 EmailsDirectory.register('new_user', N_('Notification of creation to user'),
         enabled=False,
diff --git a/wcs/forms/actions.py b/wcs/forms/actions.py
index f61e403d1..fc613d6d1 100644
--- a/wcs/forms/actions.py
+++ b/wcs/forms/actions.py
@@ -17,11 +17,11 @@
 from quixote import redirect
 from quixote.directory import Directory
 
-from qommon import errors
-from qommon import misc
-from qommon import template
-from qommon import tokens
-from qommon.form import Form
+from ..qommon import errors
+from ..qommon import misc
+from ..qommon import template
+from ..qommon import tokens
+from ..qommon.form import Form
 
 from wcs.formdef import FormDef
 from wcs.forms.common import FormTemplateMixin
diff --git a/wcs/forms/backoffice.py b/wcs/forms/backoffice.py
index c3d0aeae8..e857296f6 100644
--- a/wcs/forms/backoffice.py
+++ b/wcs/forms/backoffice.py
@@ -19,10 +19,10 @@ import urllib
 from quixote import get_request, get_publisher, redirect
 from quixote.html import htmltext, TemplateIO
 
-from qommon import _
-from qommon import misc
-from qommon.form import *
-from qommon.backoffice.listing import pagination_links
+from ..qommon import _
+from ..qommon import misc
+from ..qommon.form import *
+from ..qommon.backoffice.listing import pagination_links
 from wcs.roles import logged_users_role
 
 class FormDefUI(object):
diff --git a/wcs/forms/common.py b/wcs/forms/common.py
index c2a94a5dc..76cf5d6e8 100644
--- a/wcs/forms/common.py
+++ b/wcs/forms/common.py
@@ -26,15 +26,15 @@ from wcs.api_utils import get_user_from_api_query_string, is_url_signed
 from wcs.fields import WidgetField, FileField
 from wcs.workflows import EditableWorkflowStatusItem
 
-from qommon import _
-from qommon import misc
-from qommon import template
-from qommon import get_logger
-from qommon.form import *
+from ..qommon import _
+from ..qommon import misc
+from ..qommon import template
+from ..qommon import get_logger
+from ..qommon.form import *
 
 from wcs.qommon.admin.texts import TextsDirectory
 
-from qommon import errors
+from ..qommon import errors
 
 
 class FileDirectory(Directory):
diff --git a/wcs/forms/preview.py b/wcs/forms/preview.py
index 455f3bf49..9377f8ab3 100644
--- a/wcs/forms/preview.py
+++ b/wcs/forms/preview.py
@@ -17,7 +17,7 @@
 from quixote import get_publisher
 from quixote.directory import Directory, AccessControlled
 from quixote.html import htmltext, TemplateIO
-from qommon import errors, _
+from ..qommon import errors, _
 
 from .root import FormPage
 
diff --git a/wcs/forms/root.py b/wcs/forms/root.py
index ed628cb32..f841c2e0d 100644
--- a/wcs/forms/root.py
+++ b/wcs/forms/root.py
@@ -38,14 +38,14 @@ from quixote.util import randbytes
 from quixote.form.widget import *
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon.admin.emails import EmailsDirectory
-from qommon import errors, get_cfg
-from qommon import misc, get_logger
-from qommon import template
-from qommon.form import *
-from qommon.logger import BotFilter
-from qommon import emails
+from ..qommon import _
+from ..qommon.admin.emails import EmailsDirectory
+from ..qommon import errors, get_cfg
+from ..qommon import misc, get_logger
+from ..qommon import template
+from ..qommon.form import *
+from ..qommon.logger import BotFilter
+from ..qommon import emails
 
 from wcs import data_sources
 from wcs.categories import Category
diff --git a/wcs/forms/workflows.py b/wcs/forms/workflows.py
index 342cc764f..b3285376d 100644
--- a/wcs/forms/workflows.py
+++ b/wcs/forms/workflows.py
@@ -19,7 +19,7 @@ import json
 from quixote import get_request, get_response
 from quixote.directory import Directory
 
-from qommon import errors
+from ..qommon import errors
 
 from wcs.api import get_user_from_api_query_string, is_url_signed
 from wcs.roles import logged_users_role
diff --git a/wcs/logged_errors.py b/wcs/logged_errors.py
index 93a0cd13c..fd47f11ad 100644
--- a/wcs/logged_errors.py
+++ b/wcs/logged_errors.py
@@ -16,8 +16,8 @@
 
 import datetime
 
-from qommon.misc import simplify
-from qommon.xml_storage import XmlStorableObject
+from .qommon.misc import simplify
+from .qommon.xml_storage import XmlStorableObject
 from wcs.formdef import FormDef
 from wcs.workflows import Workflow
 
diff --git a/wcs/myspace.py b/wcs/myspace.py
index f90048a26..e0a2ed396 100644
--- a/wcs/myspace.py
+++ b/wcs/myspace.py
@@ -15,9 +15,9 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
 from quixote import get_request, redirect
-import qommon.myspace
+from .qommon import myspace
 
-class MyspaceDirectory(qommon.myspace.MyspaceDirectory):
+class MyspaceDirectory(myspace.MyspaceDirectory):
     _q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms']
 
     def drafts(self):
diff --git a/wcs/portfolio.py b/wcs/portfolio.py
index c19a27bf8..49990796c 100644
--- a/wcs/portfolio.py
+++ b/wcs/portfolio.py
@@ -17,12 +17,12 @@
 import json
 import hashlib
 import urllib
-import urlparse
 import base64
 
-from qommon import get_logger
-from qommon.misc import http_get_page, json_loads, http_post_request, urlopen
-import qommon.form
+from django.utils.six.moves.urllib import parse as urlparse
+
+from .qommon import get_logger
+from .qommon.misc import http_get_page, json_loads, http_post_request, urlopen
 from quixote import get_publisher, get_request, get_response, redirect, get_session
 from quixote.directory import Directory
 from quixote.html import TemplateIO, htmltext
@@ -131,7 +131,8 @@ class FargoDirectory(Directory):
             scheme, netloc, path, qs, frag = urlparse.urlsplit(url)
             path = map(None, path.split('/'))
             name = urllib.unquote(path[-1])
-            download = qommon.form.PicklableUpload(name, content_type='application/pdf')
+            from .qommon.form import PicklableUpload
+            download = PicklableUpload(name, content_type='application/pdf')
             download.__setstate__({
                 'data': document,
             })
diff --git a/wcs/publisher.py b/wcs/publisher.py
index 429741597..536143dea 100644
--- a/wcs/publisher.py
+++ b/wcs/publisher.py
@@ -29,7 +29,7 @@ try:
 except ImportError:
     pass
 
-from qommon.publisher import set_publisher_class, QommonPublisher
+from .qommon.publisher import set_publisher_class, QommonPublisher
 
 # this is terribly ugly but import RootDirectory will import a bunch of things,
 # and some of them need a publisher to be set
@@ -38,22 +38,22 @@ class StubWcsPublisher(QommonPublisher):
 set_publisher_class(StubWcsPublisher)
 
 
-from root import RootDirectory
-from backoffice import RootDirectory as BackofficeRootDirectory
-from admin import RootDirectory as AdminRootDirectory
-import sessions
-from qommon.cron import CronJob
+from .root import RootDirectory
+from .backoffice import RootDirectory as BackofficeRootDirectory
+from .admin import RootDirectory as AdminRootDirectory
+from . import sessions
+from .qommon.cron import CronJob
 
-from users import User
-from tracking_code import TrackingCode
-from logged_errors import LoggedError
+from .users import User
+from .tracking_code import TrackingCode
+from .logged_errors import LoggedError
 
 import pickle
 
 class UnpicklerClass(pickle.Unpickler):
     def find_class(self, module, name):
-        if module == 'wcs.form':
-            module = 'qommon.form'
+        if module == 'qommon.form':
+            module = 'wcs.qommon.form'
         __import__(module)
         mod = sys.modules[module]
         klass = getattr(mod, name)
diff --git a/wcs/qommon/__init__.py b/wcs/qommon/__init__.py
index e8e11b53e..72d430517 100644
--- a/wcs/qommon/__init__.py
+++ b/wcs/qommon/__init__.py
@@ -40,8 +40,8 @@ def ngettext(*args):
         return message
     return unicode(pub.ngettext(*args), 'utf-8').encode(pub.site_charset)
 
-from publisher import get_cfg, get_logger, get_publisher_class
-import publisher
+from .publisher import get_cfg, get_logger, get_publisher_class
+from . import publisher
 publisher._ = _
 
 
diff --git a/wcs/qommon/admin/cfg.py b/wcs/qommon/admin/cfg.py
index 91115ff81..9b5b8e1bc 100644
--- a/wcs/qommon/admin/cfg.py
+++ b/wcs/qommon/admin/cfg.py
@@ -16,7 +16,7 @@
 
 from quixote import get_publisher
 
-from qommon import get_cfg
+from .. import get_cfg
 
 def cfg_submit(form, cfg_key, fields):
     get_publisher().reload_cfg()
diff --git a/wcs/qommon/admin/emails.py b/wcs/qommon/admin/emails.py
index dd1607efa..879d25e8c 100644
--- a/wcs/qommon/admin/emails.py
+++ b/wcs/qommon/admin/emails.py
@@ -18,11 +18,11 @@ from quixote import redirect
 from quixote.directory import Directory
 from quixote.html import htmltext, TemplateIO
 
-from qommon import _
-from qommon.form import *
-from qommon import misc, get_cfg
-from qommon.backoffice.menu import html_top
-from qommon.admin.cfg import cfg_submit
+from .. import _
+from ..form import *
+from .. import misc, get_cfg
+from ..backoffice.menu import html_top
+from ..admin.cfg import cfg_submit
 
 class EmailsDirectory(Directory):
     emails_dict = {}
diff --git a/wcs/qommon/admin/logger.py b/wcs/qommon/admin/logger.py
index 6b8d6076d..279b5b4e9 100644
--- a/wcs/qommon/admin/logger.py
+++ b/wcs/qommon/admin/logger.py
@@ -21,10 +21,10 @@ from quixote import get_publisher, get_request, get_response
 from quixote.html import htmltext, TemplateIO
 from quixote.directory import Directory
 
-from qommon import _
-from qommon import logger, errors
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import error_page
+from .. import _
+from .. import logger, errors
+from ..backoffice.menu import html_top
+from ..admin.menu import error_page
 
 class ByUserDirectory(Directory):
     def _q_lookup(self, component):
diff --git a/wcs/qommon/admin/menu.py b/wcs/qommon/admin/menu.py
index 6ca9e54fb..d4e7054b8 100644
--- a/wcs/qommon/admin/menu.py
+++ b/wcs/qommon/admin/menu.py
@@ -17,8 +17,8 @@
 from quixote import get_publisher, get_request
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon.backoffice.menu import html_top
+from .. import _
+from ..backoffice.menu import html_top
 import re
 
 def _find_vc_version():
diff --git a/wcs/qommon/admin/settings.py b/wcs/qommon/admin/settings.py
index 47bf1e912..bdbd71ee2 100644
--- a/wcs/qommon/admin/settings.py
+++ b/wcs/qommon/admin/settings.py
@@ -18,10 +18,10 @@ from quixote import redirect
 from quixote.directory import Directory, AccessControlled
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon.form import *
-from qommon.admin.cfg import cfg_submit
-from qommon.backoffice.menu import html_top
+from .. import _
+from ..form import *
+from ..admin.cfg import cfg_submit
+from ..backoffice.menu import html_top
 
 class SettingsDirectory(AccessControlled, Directory):
     def _q_access(self):
diff --git a/wcs/qommon/admin/texts.py b/wcs/qommon/admin/texts.py
index c983bf611..bf8882d4e 100644
--- a/wcs/qommon/admin/texts.py
+++ b/wcs/qommon/admin/texts.py
@@ -20,11 +20,11 @@ from quixote import redirect, get_publisher
 from quixote.html import TemplateIO, htmltext
 from quixote.directory import Directory
 
-from qommon import _
-from qommon.form import *
-from qommon import misc, get_cfg, ezt
-from qommon.backoffice.menu import html_top
-from qommon.template import Template
+from wcs.qommon import _
+from wcs.qommon.form import *
+from wcs.qommon import misc, get_cfg, ezt
+from wcs.qommon.backoffice.menu import html_top
+from wcs.qommon.template import Template
 
 
 class TextsDirectory(Directory):
diff --git a/wcs/qommon/afterjobs.py b/wcs/qommon/afterjobs.py
index ce2ca5da0..06f2ce5c9 100644
--- a/wcs/qommon/afterjobs.py
+++ b/wcs/qommon/afterjobs.py
@@ -17,9 +17,9 @@
 from quixote.directory import Directory
 from quixote import get_response
 
-import errors
-from http_response import AfterJob
-from qommon import _
+from . import errors
+from .http_response import AfterJob
+from . import _
 
 class AfterJobStatusDirectory(Directory):
     def _q_lookup(self, component):
diff --git a/wcs/qommon/backoffice/__init__.py b/wcs/qommon/backoffice/__init__.py
index 3b46505c3..7d271cd20 100644
--- a/wcs/qommon/backoffice/__init__.py
+++ b/wcs/qommon/backoffice/__init__.py
@@ -14,4 +14,4 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from root import BackofficeRootDirectory
+from .root import BackofficeRootDirectory
diff --git a/wcs/qommon/backoffice/listing.py b/wcs/qommon/backoffice/listing.py
index 9ee05ac6c..388416013 100644
--- a/wcs/qommon/backoffice/listing.py
+++ b/wcs/qommon/backoffice/listing.py
@@ -19,7 +19,7 @@ import urllib
 from quixote.html import htmltext, TemplateIO
 from quixote import get_request, get_response
 
-from qommon import _
+from .. import _
 
 def pagination_links(offset, limit, total_count):
     get_response().add_javascript(['jquery.js', 'wcs.listing.js'])
diff --git a/wcs/qommon/backoffice/menu.py b/wcs/qommon/backoffice/menu.py
index 82f5f8ce8..6048ceea3 100644
--- a/wcs/qommon/backoffice/menu.py
+++ b/wcs/qommon/backoffice/menu.py
@@ -17,8 +17,8 @@
 from quixote import get_response, get_request, get_publisher, get_session
 from quixote.html import htmltext, TemplateIO
 
-from qommon import get_cfg
-from qommon import _
+from .. import get_cfg
+from .. import _
 
 def generate_header_menu(selected = None):
     return get_publisher().get_backoffice_root().generate_header_menu(selected=selected)
diff --git a/wcs/qommon/backoffice/root.py b/wcs/qommon/backoffice/root.py
index 86614d69b..b7a951ccb 100644
--- a/wcs/qommon/backoffice/root.py
+++ b/wcs/qommon/backoffice/root.py
@@ -17,8 +17,8 @@
 from quixote.directory import Directory, AccessControlled
 from quixote import get_publisher, get_request, get_response
 
-from qommon import _
-from qommon import errors
+from .. import _
+from .. import errors
 
 class BackofficeRootDirectory(AccessControlled, Directory):
 
diff --git a/wcs/qommon/bounces.py b/wcs/qommon/bounces.py
index 79f688762..120c25802 100644
--- a/wcs/qommon/bounces.py
+++ b/wcs/qommon/bounces.py
@@ -14,7 +14,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from qommon.storage import StorableObject
+from .storage import StorableObject
 
 class Bounce(StorableObject):
     _names = 'bounces'
diff --git a/wcs/qommon/ctl.py b/wcs/qommon/ctl.py
index 5b9dc1a28..94d5fbcd5 100644
--- a/wcs/qommon/ctl.py
+++ b/wcs/qommon/ctl.py
@@ -24,8 +24,8 @@ __all__ = [
     'Command',
     ]
 
-import qommon
-from qommon import _
+from wcs import qommon
+from . import _
 qommon._commands = {}
 
 class Command(object):
diff --git a/wcs/qommon/emails.py b/wcs/qommon/emails.py
index a9e1a6288..472ab8256 100644
--- a/wcs/qommon/emails.py
+++ b/wcs/qommon/emails.py
@@ -27,7 +27,6 @@ from email.mime.multipart import MIMEMultipart
 from email.mime.nonmultipart import MIMENonMultipart
 from email.mime.text import MIMEText
 from email.utils import formataddr
-import email.Charset as Charset
 import smtplib
 import socket
 
@@ -47,13 +46,17 @@ from django.utils.safestring import mark_safe
 
 from quixote import get_request, get_response, get_publisher
 
-from publisher import get_cfg, get_logger
-import errors
-import tokens
-from admin.emails import EmailsDirectory
-from template import Template
+from .publisher import get_cfg, get_logger
+from . import errors
+from . import tokens
+from .admin.emails import EmailsDirectory
+from .template import Template
 
-Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')
+try:
+    import email.Charset as Charset
+    Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8')
+except ImportError:
+    pass
 
 
 if docutils:
diff --git a/wcs/qommon/errors.py b/wcs/qommon/errors.py
index 7572b2a43..8bc57bb29 100644
--- a/wcs/qommon/errors.py
+++ b/wcs/qommon/errors.py
@@ -21,7 +21,7 @@ import quixote
 from quixote.errors import *
 from quixote.html import TemplateIO, htmltext
 
-import template
+from . import template
 
 
 class AccessForbiddenError(AccessError):
@@ -30,7 +30,7 @@ class AccessForbiddenError(AccessError):
         self.location_hint = location_hint
 
     def render(self):
-        from qommon import _
+        from . import _
         if self.public_msg:
             return template.error_page(self.public_msg, _('Access Forbidden'),
                     continue_to = (get_publisher().get_root_url(), _('the homepage')),
@@ -63,7 +63,7 @@ class EmailError(Exception):
 
 class InternalServerError(object):
     def render(self):
-        from qommon import _
+        from . import _
         template.html_top(_('Oops, the server borked severely'))
         r = TemplateIO(html=True)
 
@@ -116,7 +116,7 @@ TraversalError.description = N_(
 
 
 def format_publish_error(exc):
-    from qommon import _
+    from . import _
     if getattr(exc, 'public_msg', None):
         return template.error_page(exc.format(), _(exc.title))
     else:
diff --git a/wcs/qommon/form.py b/wcs/qommon/form.py
index c882fbf9b..aab00d059 100644
--- a/wcs/qommon/form.py
+++ b/wcs/qommon/form.py
@@ -35,7 +35,7 @@ try:
 except ImportError:
     Image = None
 
-from storage import atomic_write
+from .storage import atomic_write
 
 try:
     from feedparser import _sanitizeHTML
@@ -69,14 +69,14 @@ from django.conf import settings
 from django.utils.safestring import mark_safe
 
 from .template import render as render_template, Template, TemplateError
-from wcs.portfolio import has_portfolio
+from ..portfolio import has_portfolio
 from wcs.conditions import Condition, ValidationError
 
-from qommon import _, ngettext
-import misc
+from . import _, ngettext
+from . import misc
 from .humantime import humanduration2seconds, seconds2humanduration, timewords
 from .misc import strftime, C_, HAS_PDFTOPPM
-from publisher import get_cfg
+from .publisher import get_cfg
 from .template_utils import render_block_to_string
 
 QuixoteForm = Form
@@ -1484,6 +1484,8 @@ class WysiwygTextWidget(TextWidget):
         if self.value:
             if _sanitizeHTML:
                 self.value = _sanitizeHTML(self.value, get_request().charset, 'text/html')
+            elif isinstance(self.value, unicode):
+                self.value = self.value.encode(get_publisher().site_charset)
             if self.value.startswith('<br />'):
                 self.value = self.value[6:]
             if self.value.endswith('<br />'):
diff --git a/wcs/qommon/http_request.py b/wcs/qommon/http_request.py
index eaee44006..ff1d9a4b3 100644
--- a/wcs/qommon/http_request.py
+++ b/wcs/qommon/http_request.py
@@ -23,7 +23,7 @@ from quixote import get_session, get_publisher
 import quixote.http_request
 from quixote.errors import RequestError
 
-from http_response import HTTPResponse
+from .http_response import HTTPResponse
 
 class HTTPRequest(quixote.http_request.HTTPRequest):
     signed = False
@@ -51,7 +51,7 @@ class HTTPRequest(quixote.http_request.HTTPRequest):
         if auth_header.startswith('Basic '):
             auth_header = auth_header.split(' ', 1)[1]
             username, password = base64.decodestring(auth_header).split(':', 1)
-            from qommon.ident.password_accounts import PasswordAccount
+            from .ident.password_accounts import PasswordAccount
             try:
                 self._user = PasswordAccount.get_with_credentials(username, password)
             except KeyError:
diff --git a/wcs/qommon/http_response.py b/wcs/qommon/http_response.py
index 0659a0874..df3dfd208 100644
--- a/wcs/qommon/http_response.py
+++ b/wcs/qommon/http_response.py
@@ -24,7 +24,7 @@ from quixote.util import randbytes
 import quixote.http_response
 from quixote import get_publisher, get_request
 
-from qommon.storage import StorableObject
+from .storage import StorableObject
 
 class AfterJob(StorableObject):
     _names = 'afterjobs'
@@ -99,7 +99,7 @@ class HTTPResponse(quixote.http_response.HTTPResponse):
     def get_javascript_for_header(self):
         s = ''
         if self.javascript_scripts:
-            from qommon.admin.menu import get_vc_version
+            from .admin.menu import get_vc_version
             version_hash = hashlib.md5(str(get_vc_version())).hexdigest()
             root_url = get_publisher().get_root_url() + get_publisher().qommon_static_dir
             s += '\n'.join(['<script type="text/javascript" src="%sjs/%s?%s"></script>' % (
@@ -120,7 +120,7 @@ class HTTPResponse(quixote.http_response.HTTPResponse):
     def get_css_includes_for_header(self):
         if not self.css_includes:
             return ''
-        from qommon.admin.menu import get_vc_version
+        from .admin.menu import get_vc_version
         version_hash = hashlib.md5(str(get_vc_version())).hexdigest()
         root_url = get_publisher().get_root_url() + get_publisher().qommon_static_dir
         return '\n'.join(['<link rel="stylesheet" type="text/css" href="%scss/%s?%s" />' % (
diff --git a/wcs/qommon/humantime.py b/wcs/qommon/humantime.py
index 0fb27c630..cb3b3201b 100644
--- a/wcs/qommon/humantime.py
+++ b/wcs/qommon/humantime.py
@@ -16,7 +16,7 @@
 
 import re
 
-from qommon import _
+from . import _
 
 _minute = 60
 _hour = 60 * 60
diff --git a/wcs/qommon/ident/__init__.py b/wcs/qommon/ident/__init__.py
index ef63d628a..ec1fddcc7 100644
--- a/wcs/qommon/ident/__init__.py
+++ b/wcs/qommon/ident/__init__.py
@@ -16,7 +16,7 @@
 
 from quixote import get_publisher
 
-import base
+from . import base
 
 def login(method):
     m = get_publisher().ident_methods.get(method)
diff --git a/wcs/qommon/ident/franceconnect.py b/wcs/qommon/ident/franceconnect.py
index 976654b3e..de8a819d5 100644
--- a/wcs/qommon/ident/franceconnect.py
+++ b/wcs/qommon/ident/franceconnect.py
@@ -24,12 +24,12 @@ from quixote import redirect, get_session, get_publisher, get_request, get_sessi
 from quixote.directory import Directory
 from quixote.html import htmltext, TemplateIO
 
-from qommon import _
-from qommon.backoffice.menu import html_top
-from qommon import template, get_cfg, get_logger
-from qommon.form import (Form, StringWidget, CompositeWidget, ComputedExpressionWidget,
+from .. import _
+from ..backoffice.menu import html_top
+from .. import template, get_cfg, get_logger
+from ..form import (Form, StringWidget, CompositeWidget, ComputedExpressionWidget,
                          SingleSelectWidget, WidgetListAsTable)
-from qommon.misc import http_post_request, http_get_page, json_loads
+from ..misc import http_post_request, http_get_page, json_loads
 
 from wcs.workflows import WorkflowStatusItem
 from wcs.formdata import flatten_dict
diff --git a/wcs/qommon/ident/idp.py b/wcs/qommon/ident/idp.py
index cb57973f5..bb67bdb08 100644
--- a/wcs/qommon/ident/idp.py
+++ b/wcs/qommon/ident/idp.py
@@ -26,22 +26,22 @@ from quixote.directory import Directory
 from quixote import redirect, get_session, get_response, get_publisher
 from quixote.html import htmltext, TemplateIO
 
-from qommon import _
-from qommon import misc, get_cfg, get_logger
-from qommon.form import *
-from qommon.tokens import Token
+from .. import _
+from .. import misc, get_cfg, get_logger
+from ..form import *
+from ..tokens import Token
 
-from qommon import template
-from qommon import errors
+from .. import template
+from .. import errors
 
-from qommon.backoffice.menu import html_top
-from qommon.admin.menu import command_icon
+from ..backoffice.menu import html_top
+from ..admin.menu import command_icon
 
-from base import AuthMethod
-from qommon.storage import atomic_write
+from .base import AuthMethod
+from ..storage import atomic_write
 
-import qommon.x509utils as x509utils
-import qommon.saml2utils as saml2utils
+from .. import x509utils
+from .. import saml2utils
 
 ADMIN_TITLE = N_('SAML2')
 
@@ -1024,7 +1024,7 @@ class MethodAdminDirectory(Directory):
         return r.getvalue()
 
     def identities_submit(self, form):
-        from qommon.admin.settings import cfg_submit
+        from wcs.qommon.admin.settings import cfg_submit
         cfg_submit(form, 'saml_identities',
                 ('grab-user-with-wsf', 'identity-creation', 'notify-on-register',
                  'email-confirmation', 'registration-url'))
diff --git a/wcs/qommon/ident/password.py b/wcs/qommon/ident/password.py
index e9fa716aa..cb286eff6 100644
--- a/wcs/qommon/ident/password.py
+++ b/wcs/qommon/ident/password.py
@@ -18,34 +18,34 @@ import random
 import time
 import csv
 
-from base import AuthMethod, NoSuchMethodForUserError
+from .base import AuthMethod, NoSuchMethodForUserError
 
 from quixote import redirect, get_publisher
 from quixote.directory import AccessControlled, Directory
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _, ngettext
-from qommon.form import *
+from .. import _, ngettext
+from ..form import *
 
-from qommon.publisher import get_publisher_class
-from qommon import misc, get_cfg, get_logger
-from qommon import emails
-from qommon import template
-from qommon import tokens
-from qommon import errors
+from ..publisher import get_publisher_class
+from .. import misc, get_cfg, get_logger
+from .. import emails
+from .. import template
+from .. import tokens
+from .. import errors
 
-from qommon.admin.menu import command_icon
+from ..admin.menu import command_icon
 
-from qommon.backoffice.menu import html_top
+from ..backoffice.menu import html_top
 
-from qommon.admin.emails import EmailsDirectory
+from ..admin.emails import EmailsDirectory
 from wcs.qommon.admin.texts import TextsDirectory
 
-from qommon.cron import CronJob
-from qommon.afterjobs import AfterJob
-import qommon.storage as st
+from ..cron import CronJob
+from ..afterjobs import AfterJob
+from .. import storage as st
 
-from password_accounts import PasswordAccount, HASHING_ALGOS
+from .password_accounts import PasswordAccount, HASHING_ALGOS
 
 
 def notify_admins_user_registered(account):
@@ -756,7 +756,7 @@ class MethodAdminDirectory(Directory):
         return r.getvalue()
 
     def passwords_submit(self, form):
-        from admin.settings import cfg_submit
+        from wcs.admin.settings import cfg_submit
         cfg_submit(form, 'passwords',
                 ('can_change', 'generate',
                 'min_length', 'max_length',
@@ -806,7 +806,7 @@ class MethodAdminDirectory(Directory):
         return r.getvalue()
 
     def identities_submit(self, form):
-        from admin.settings import cfg_submit
+        from wcs.admin.settings import cfg_submit
         cfg_submit(form, 'identities',
                 ('creation', 'email-as-username', 'notify-on-register', 'email-confirmation',
                  'warn_about_unused_account_delay', 'remove_unused_account_delay'))
diff --git a/wcs/qommon/ident/password_accounts.py b/wcs/qommon/ident/password_accounts.py
index 8a61ace29..6707620e0 100644
--- a/wcs/qommon/ident/password_accounts.py
+++ b/wcs/qommon/ident/password_accounts.py
@@ -18,7 +18,7 @@ import hashlib
 
 from quixote import get_publisher
 
-from qommon.storage import StorableObject
+from ..storage import StorableObject
 
 HASHING_ALGOS = {
    'sha': hashlib.sha1,
diff --git a/wcs/qommon/management/commands/collectstatic.py b/wcs/qommon/management/commands/collectstatic.py
index e4c11f30f..c2c0e822e 100644
--- a/wcs/qommon/management/commands/collectstatic.py
+++ b/wcs/qommon/management/commands/collectstatic.py
@@ -18,7 +18,7 @@ import os
 import shutil
 
 from django.core.management.base import BaseCommand
-from qommon.publisher import get_publisher_class
+from wcs.qommon.publisher import get_publisher_class
 
 class Command(BaseCommand):
     help = "Collect static files in a single location."
diff --git a/wcs/qommon/management/commands/cron.py b/wcs/qommon/management/commands/cron.py
index 3a0b5b733..99d833a6d 100644
--- a/wcs/qommon/management/commands/cron.py
+++ b/wcs/qommon/management/commands/cron.py
@@ -20,10 +20,10 @@ import os
 
 from django.conf import settings
 from django.core.management.base import BaseCommand, CommandError
-from qommon.publisher import get_publisher_class
+from wcs.qommon.publisher import get_publisher_class
 
-from qommon.vendor import locket
-from qommon.cron import cron_worker
+from wcs.qommon.vendor import locket
+from wcs.qommon.cron import cron_worker
 from wcs.wf.jump import JUMP_TIMEOUT_INTERVAL
 
 
diff --git a/wcs/qommon/management/commands/migrate.py b/wcs/qommon/management/commands/migrate.py
index 4fe70a77f..0fb02da75 100644
--- a/wcs/qommon/management/commands/migrate.py
+++ b/wcs/qommon/management/commands/migrate.py
@@ -18,7 +18,7 @@ import os
 import quixote
 
 from django.core.management.base import BaseCommand
-from qommon.publisher import get_publisher_class
+from wcs.qommon.publisher import get_publisher_class
 
 class Command(BaseCommand):
     help = 'Migrate databases'
diff --git a/wcs/qommon/misc.py b/wcs/qommon/misc.py
index d1ac7c4c5..0bd590845 100644
--- a/wcs/qommon/misc.py
+++ b/wcs/qommon/misc.py
@@ -46,10 +46,10 @@ from django.utils.six.moves.urllib import parse as urlparse
 from quixote import get_publisher, get_response, get_request
 from quixote.html import htmltext
 
-from qommon import _
-from qommon import get_cfg, get_logger, ezt
-from qommon.errors import ConnectionError
-from qommon.template import Template
+from . import _
+from . import get_cfg, get_logger, ezt
+from .errors import ConnectionError
+from .template import Template
 
 from django.utils.six import StringIO
 
diff --git a/wcs/qommon/myspace.py b/wcs/qommon/myspace.py
index 5528abb1a..f9bb8845d 100644
--- a/wcs/qommon/myspace.py
+++ b/wcs/qommon/myspace.py
@@ -18,14 +18,13 @@ from quixote import get_publisher, get_request, redirect, get_response, get_sess
 from quixote.directory import Directory
 from quixote.html import htmltext, TemplateIO
 
-from qommon import _
-from qommon import template
-from qommon.form import *
-from qommon import get_cfg
-from qommon import errors
+from . import _
+from . import template
+from .form import *
+from . import get_cfg
+from . import errors
 
-import qommon.ident.password
-from qommon.ident.password_accounts import PasswordAccount
+from .ident.password_accounts import PasswordAccount
 
 from wcs.qommon.admin.texts import TextsDirectory
 
@@ -152,7 +151,8 @@ class MyspaceDirectory(Directory):
             return redirect('.')
 
         if form.is_submitted() and not form.has_errors():
-            qommon.ident.password.check_password(form, 'new_password')
+            from .qommon.ident.password import check_password
+            check_password(form, 'new_password')
             new_password = form.get_widget('new_password').parse()
             new2_password = form.get_widget('new2_password').parse()
             if new_password != new2_password:
diff --git a/wcs/qommon/pages.py b/wcs/qommon/pages.py
index 2556ee1ad..c5a6cf4b7 100644
--- a/wcs/qommon/pages.py
+++ b/wcs/qommon/pages.py
@@ -20,8 +20,8 @@ from quixote import get_publisher, redirect
 from quixote.directory import Directory
 from quixote.util import StaticDirectory
 
-from qommon import errors
-from qommon import template
+from . import errors
+from . import template
 
 class PagesDirectory(Directory):
     _q_exports = ['']
diff --git a/wcs/qommon/publisher.py b/wcs/qommon/publisher.py
index e49794350..e9c51143f 100644
--- a/wcs/qommon/publisher.py
+++ b/wcs/qommon/publisher.py
@@ -15,6 +15,7 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
 import collections
+from django.utils.six.moves import builtins
 from django.utils.six.moves import configparser as ConfigParser
 from django.utils.six.moves import cPickle
 import datetime
@@ -32,8 +33,8 @@ import socket
 import sys
 import time
 import traceback
-import __builtin__
-__builtin__.__dict__['N_'] = lambda x: x
+
+builtins.__dict__['N_'] = lambda x: x
 
 import linecache
 import requests
@@ -46,18 +47,18 @@ from django.utils import translation
 from django.utils.translation import gettext, ngettext
 
 from quixote.publish import Publisher, get_request, get_response, get_publisher, redirect
-from http_request import HTTPRequest
-from http_response import HTTPResponse, AfterJob
+from .http_request import HTTPRequest
+from .http_response import HTTPResponse, AfterJob
 
-from cron import CronJob
-from substitution import Substitutions, CompatibilityNamesDict
+from .cron import CronJob
+from .substitution import Substitutions, CompatibilityNamesDict
 
-import errors
-import template
+from . import errors
+from . import template
 import logging
 import logging.handlers
-import logger
-import storage
+from . import logger
+from . import storage
 import urllib
 
 class ImmediateRedirectException(Exception):
@@ -556,12 +557,12 @@ class QommonPublisher(Publisher, object):
             lasso = None
         classes = []
         if lasso:
-            import qommon.ident.idp
-            classes.append(qommon.ident.idp.IdPAuthMethod)
-        import qommon.ident.franceconnect
-        classes.append(qommon.ident.franceconnect.FCAuthMethod)
-        import qommon.ident.password
-        classes.append(qommon.ident.password.PasswordAuthMethod)
+            from .ident import idp
+            classes.append(idp.IdPAuthMethod)
+        from .ident import franceconnect
+        classes.append(franceconnect.FCAuthMethod)
+        from .ident import password
+        classes.append(password.PasswordAuthMethod)
         self.ident_methods = {}
         for klass in classes:
             self.ident_methods[klass.key] = klass
@@ -1008,10 +1009,10 @@ def get_logger():
 
 
 def set_publisher_class(klass):
-    __builtin__.__dict__['__publisher_class'] = klass
+    builtins.__dict__['__publisher_class'] = klass
 
 def get_publisher_class():
-    return __builtin__.__dict__.get('__publisher_class')
+    return builtins.__dict__.get('__publisher_class')
 
 
 Substitutions.register('site_name', category=N_('General'), comment=N_('Site Name'))
diff --git a/wcs/qommon/saml2.py b/wcs/qommon/saml2.py
index 622657938..9bd10d2fc 100644
--- a/wcs/qommon/saml2.py
+++ b/wcs/qommon/saml2.py
@@ -31,14 +31,14 @@ from quixote.http_request import parse_header
 from quixote.directory import Directory
 from quixote import get_session, get_session_manager
 
-import misc
-from publisher import get_cfg, get_logger
-from qommon import _
-from qommon import template
-from template import error_page
+from . import misc
+from .publisher import get_cfg, get_logger
+from . import _
+from . import template
+from .template import error_page
 from wcs.roles import Role
 
-import errors
+from . import errors
 
 
 class SOAPException(Exception):
diff --git a/wcs/qommon/saml2utils.py b/wcs/qommon/saml2utils.py
index 6755c2db8..2f67abe8b 100644
--- a/wcs/qommon/saml2utils.py
+++ b/wcs/qommon/saml2utils.py
@@ -16,7 +16,7 @@
 
 import os
 
-import x509utils
+from . import x509utils
 
 def bool2xs(boolean):
     '''Convert a boolean value to XSchema boolean representation'''
diff --git a/wcs/qommon/sessions.py b/wcs/qommon/sessions.py
index a62a445bf..a885192b8 100644
--- a/wcs/qommon/sessions.py
+++ b/wcs/qommon/sessions.py
@@ -28,9 +28,9 @@ from quixote.util import randbytes
 from django.conf import settings
 from django.core.signing import Signer, BadSignature
 
-from qommon import misc
-from qommon.storage import StorableObject
-from publisher import get_cfg
+from . import misc
+from .storage import StorableObject
+from .publisher import get_cfg
 from quixote.publish import get_session, get_session_manager, get_request
 
 
diff --git a/wcs/qommon/sms.py b/wcs/qommon/sms.py
index 93f177ec4..27d554baa 100644
--- a/wcs/qommon/sms.py
+++ b/wcs/qommon/sms.py
@@ -17,9 +17,9 @@
 import re
 import urllib
 
-from qommon import errors, misc
-from qommon import get_cfg, get_logger
-from qommon.form import StringWidget, PasswordWidget
+from . import errors, misc
+from . import get_cfg, get_logger
+from .form import StringWidget, PasswordWidget
 from wcs.wscalls import call_webservice
 
 
diff --git a/wcs/qommon/storage.py b/wcs/qommon/storage.py
index 4e0d59a2b..c73ceaad1 100644
--- a/wcs/qommon/storage.py
+++ b/wcs/qommon/storage.py
@@ -23,12 +23,10 @@ import os.path
 import shutil
 import sys
 import tempfile
-try:
-    import thread as _thread
-except ImportError:
-    import dummy_thread as _thread
 
-from vendor import locket
+from django.utils.six.moves import _thread
+
+from .vendor import locket
 
 from quixote import get_publisher
 
diff --git a/wcs/qommon/substitution.py b/wcs/qommon/substitution.py
index df9f9b9e5..b044bb29a 100644
--- a/wcs/qommon/substitution.py
+++ b/wcs/qommon/substitution.py
@@ -120,7 +120,7 @@ class Substitutions(object):
 
     @classmethod
     def get_substitution_html_table(cls):
-        from qommon import _
+        from . import _
         r = TemplateIO(html=True)
         r += htmltext('<table id="substvars">')
         r += htmltext('<thead><tr><th>%s</th><th>%s</th><th>%s</th></tr></thead>' % (
diff --git a/wcs/qommon/template.py b/wcs/qommon/template.py
index 200864872..db7ac1702 100644
--- a/wcs/qommon/template.py
+++ b/wcs/qommon/template.py
@@ -32,8 +32,7 @@ from quixote.directory import Directory
 from quixote.util import StaticDirectory, StaticFile
 from quixote.html import htmltext, htmlescape, TemplateIO
 
-import errors
-import ezt
+from . import ezt
 
 
 def get_template_from_script(filename):
@@ -186,7 +185,7 @@ def html_top(title=None, default_org=None):
 
 def error_page(error_message, error_title = None, exception = None, continue_to = None,
             location_hint = None):
-    from qommon import _
+    from . import _
     if not error_title:
         error_title = _('Error')
     if exception:
@@ -195,8 +194,7 @@ def error_page(error_message, error_title = None, exception = None, continue_to
 
     kwargs = {'title': error_title}
     if location_hint == 'backoffice':
-        import qommon.backoffice.menu
-        error_html_top = qommon.backoffice.menu.html_top
+        from .backoffice.menu import html_top as error_html_top
         kwargs[str('section')]  = None
     else:
         error_html_top = html_top
@@ -432,7 +430,7 @@ class TemplateError(Exception):
 
 
 def ezt_raises(exception, on_parse=False):
-    from qommon import _
+    from . import _
     parts = []
     parts.append({
             ezt.ArgCountSyntaxError: _('wrong number of arguments'),
@@ -472,7 +470,7 @@ class Template(object):
                 self.template = engines['django'].from_string(value)
             except DjangoTemplateSyntaxError as e:
                 if raises:
-                    from qommon import _
+                    from . import _
                     raise TemplateError(_('syntax error in Django template: %s'), e)
                 self.render = self.null_render
 
@@ -497,7 +495,7 @@ class Template(object):
             rendered = self.template.render(context)
         except (DjangoTemplateSyntaxError, DjangoVariableDoesNotExist) as e:
             if self.raises:
-                from qommon import _
+                from . import _
                 raise TemplateError(_('failure to render Django template: %s'), e)
             else:
                 return self.value
diff --git a/wcs/qommon/tokens.py b/wcs/qommon/tokens.py
index ec45ed525..64514ca09 100644
--- a/wcs/qommon/tokens.py
+++ b/wcs/qommon/tokens.py
@@ -17,7 +17,7 @@
 import random
 import string
 
-from qommon.storage import StorableObject
+from .storage import StorableObject
 import time
 
 class Token(StorableObject):
diff --git a/wcs/roles.py b/wcs/roles.py
index 9c697807e..f5c490593 100644
--- a/wcs/roles.py
+++ b/wcs/roles.py
@@ -16,9 +16,8 @@
 
 from quixote import get_publisher
 
-from qommon import _
-from qommon.storage import StorableObject
-import qommon.misc
+from .qommon import _, misc
+from .qommon.storage import StorableObject
 
 class Role(StorableObject):
     _names = 'roles'
@@ -51,7 +50,7 @@ class Role(StorableObject):
         super(Role, self).store()
 
     def get_new_slug(self):
-        new_slug = qommon.misc.simplify(self.name)
+        new_slug = misc.simplify(self.name)
         base_new_slug = new_slug
         suffix_no = 0
         while True:
@@ -126,6 +125,6 @@ def logged_users_role():
 
 
 def get_user_roles():
-    t = sorted([(qommon.misc.simplify(x.name), x.id, x.name, x.id) for x in Role.select()])
+    t = sorted([(misc.simplify(x.name), x.id, x.name, x.id) for x in Role.select()])
     return [x[1:] for x in t]
 
diff --git a/wcs/root.py b/wcs/root.py
index 177be166c..c76b57489 100644
--- a/wcs/root.py
+++ b/wcs/root.py
@@ -25,30 +25,30 @@ from quixote.directory import Directory
 from quixote.html import htmltext, TemplateIO
 from quixote.util import StaticDirectory
 
-import forms.root
-from qommon import saml2
-
-from qommon import _
-from qommon import errors
-from qommon import get_cfg, get_logger
-from qommon import template
-from qommon.form import *
-import qommon.ident
-import qommon.pages
-
-from qommon.afterjobs import AfterJobStatusDirectory
-
-from categories import Category
-from formdef import FormDef
-from data_sources import NamedDataSource
-from wscalls import NamedWsCall
-from wcs.api import ApiDirectory
-from myspace import MyspaceDirectory
-from forms.preview import PreviewDirectory
-from wcs.forms.actions import ActionsDirectory
-from wcs.scripts import Script
-
-from wcs import portfolio
+from .forms import root
+from .qommon import saml2
+
+from .qommon import _
+from .qommon import errors
+from .qommon import get_cfg, get_logger
+from .qommon import template
+from .qommon.form import *
+from .qommon import ident
+from .qommon import pages
+
+from .qommon.afterjobs import AfterJobStatusDirectory
+
+from .categories import Category
+from .formdef import FormDef
+from .data_sources import NamedDataSource
+from .wscalls import NamedWsCall
+from .api import ApiDirectory
+from .myspace import MyspaceDirectory
+from .forms.preview import PreviewDirectory
+from .forms.actions import ActionsDirectory
+from .scripts import Script
+
+from . import portfolio
 
 class CompatibilityDirectory(Directory):
     _q_exports = ['']
@@ -61,7 +61,7 @@ class IdentDirectory(Directory):
     def _q_lookup(self, component):
         get_response().breadcrumb.append(('ident/', None))
         try:
-            return qommon.ident.get_method_directory(component)
+            return ident.get_method_directory(component)
         except KeyError:
             raise errors.TraversalError()
 
@@ -91,7 +91,7 @@ class LoginDirectory(Directory):
         if len(ident_methods) == 1:
             method = ident_methods[0]
             try:
-                return qommon.ident.login(method)
+                return ident.login(method)
             except KeyError:
                 msg = 'failed to login with method %s' % method
                 get_logger().error(msg)
@@ -100,7 +100,7 @@ class LoginDirectory(Directory):
             form = Form(enctype='multipart/form-data')
             form.add(RadiobuttonsWidget, 'method',
                     options = [(x.key, _(x.description)) \
-                            for x in qommon.ident.get_method_classes() if \
+                            for x in ident.get_method_classes() if \
                                     x.key in ident_methods],
                     delim = htmltext('<br/>'))
             form.add_submit('submit', _('Submit'))
@@ -115,7 +115,7 @@ class LoginDirectory(Directory):
                     return redirect(login_url)
                 else:
                     try:
-                        return qommon.ident.login(method)
+                        return ident.login(method)
                     except KeyError:
                         msg = 'failed to login with method %s' % method
                         get_logger().error(msg)
@@ -129,7 +129,7 @@ class LoginDirectory(Directory):
 
     def _q_lookup(self, component):
         try:
-            dir = qommon.ident.get_method_directory(component)
+            dir = ident.get_method_directory(component)
             # set the register page as the index page, so the url can be
             # /login/password/ instead of /login/password/login
             dir._q_exports.append('')
@@ -155,7 +155,7 @@ class RegisterDirectory(Directory):
         if len(ident_methods) == 1:
             method = ident_methods[0]
             try:
-                return qommon.ident.register(method)
+                return ident.register(method)
             except KeyError:
                 get_logger().error('failed to register with method %s' % method)
                 return errors.TraversalError()
@@ -163,7 +163,7 @@ class RegisterDirectory(Directory):
             form = Form(enctype='multipart/form-data')
             form.add(RadiobuttonsWidget, 'method',
                     options = [(x.key, _(x.description)) \
-                            for x in qommon.ident.get_method_classes() if \
+                            for x in ident.get_method_classes() if \
                                     x.key in ident_methods],
                     delim = htmltext('<br/>'))
             form.add_submit('submit', _('Submit'))
@@ -181,7 +181,7 @@ class RegisterDirectory(Directory):
 
     def _q_lookup(self, component):
         try:
-            dir = qommon.ident.get_method_directory(component)
+            dir = ident.get_method_directory(component)
             # set the register page as the index page, so the url can be
             # /register/password/ instead of /register/password/register
             dir._q_exports.append('')
@@ -246,16 +246,16 @@ class RootDirectory(Directory):
     api = ApiDirectory()
     themes = template.ThemesDirectory()
     myspace = MyspaceDirectory()
-    pages = qommon.pages.PagesDirectory()
+    pages = pages.PagesDirectory()
     fargo = portfolio.FargoDirectory()
     static = StaticsDirectory()
     actions = ActionsDirectory()
 
     def tryauth(self):
-        return forms.root.tryauth(get_publisher().get_root_url())
+        return root.tryauth(get_publisher().get_root_url())
 
     def auth(self):
-        return forms.root.auth(get_publisher().get_root_url())
+        return root.auth(get_publisher().get_root_url())
 
     def logout(self):
         get_logger().info('logout')
@@ -339,7 +339,7 @@ class RootDirectory(Directory):
         except errors.TraversalError:
             pass
 
-        return forms.root.RootDirectory()._q_traverse(path)
+        return root.RootDirectory()._q_traverse(path)
 
     def _q_lookup(self, component):
         # is this a category ?
@@ -352,10 +352,10 @@ class RootDirectory(Directory):
             try:
                 formdef = FormDef.get_by_urlname(component)
             except KeyError:
-                return forms.root.RootDirectory(category)
+                return root.RootDirectory(category)
 
         # or a form ?
-        return forms.root.RootDirectory()._q_lookup(component)
+        return root.RootDirectory()._q_lookup(component)
 
     def reload_top(self):
         get_response().filter = {}
diff --git a/wcs/sessions.py b/wcs/sessions.py
index 11d292f0e..2741f5f85 100644
--- a/wcs/sessions.py
+++ b/wcs/sessions.py
@@ -18,8 +18,8 @@ import os
 import time
 import uuid
 
-import qommon.sessions
-from qommon.sessions import Session
+from .qommon import sessions
+from .qommon.sessions import Session
 
 class BasicSession(Session):
 
@@ -155,5 +155,5 @@ class BasicSession(Session):
             return None
         return self.data_source_query_url_tokens.get(token)
 
-qommon.sessions.BasicSession = BasicSession
-StorageSessionManager = qommon.sessions.StorageSessionManager
+sessions.BasicSession = BasicSession
+StorageSessionManager = sessions.StorageSessionManager
diff --git a/wcs/sql.py b/wcs/sql.py
index 6ca8fc4dd..5b48207e3 100644
--- a/wcs/sql.py
+++ b/wcs/sql.py
@@ -22,10 +22,10 @@ import re
 import cPickle
 
 from quixote import get_publisher
-import qommon
-from qommon.storage import _take, parse_clause as parse_storage_clause
-from qommon.substitution import invalidate_substitution_cache
-from qommon import get_cfg
+from . import qommon
+from .qommon.storage import _take, parse_clause as parse_storage_clause
+from .qommon.substitution import invalidate_substitution_cache
+from .qommon import get_cfg
 
 import wcs.categories
 import wcs.carddata
@@ -593,7 +593,7 @@ def do_user_table():
         'anonymous', 'name_identifiers', 'verified_fields',
         'lasso_dump', 'last_seen', 'fts', 'ascii_name'])
 
-    from admin.settings import UserFieldsFormDef
+    from wcs.admin.settings import UserFieldsFormDef
     formdef = UserFieldsFormDef()
 
     for field in formdef.get_all_fields():
diff --git a/wcs/tracking_code.py b/wcs/tracking_code.py
index 549662a88..9011f956b 100644
--- a/wcs/tracking_code.py
+++ b/wcs/tracking_code.py
@@ -16,9 +16,9 @@
 
 import random
 
-from qommon.storage import StorableObject
+from .qommon.storage import StorableObject
 
-from formdef import FormDef
+from .formdef import FormDef
 
 class TrackingCode(StorableObject):
     _names = 'tracking-codes'
diff --git a/wcs/users.py b/wcs/users.py
index 0eb59822c..c79698bd6 100644
--- a/wcs/users.py
+++ b/wcs/users.py
@@ -14,13 +14,13 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from qommon import _
-from qommon.misc import simplify
-from qommon.storage import StorableObject
-from qommon import get_cfg
+from .qommon import _
+from .qommon.misc import simplify
+from .qommon.storage import StorableObject
+from .qommon import get_cfg
 import wcs.qommon.storage as st
 
-from qommon.substitution import Substitutions, invalidate_substitution_cache
+from .qommon.substitution import Substitutions, invalidate_substitution_cache
 
 class User(StorableObject):
     _names = 'users'
diff --git a/wcs/variables.py b/wcs/variables.py
index a57004b5f..d0f2d21d5 100644
--- a/wcs/variables.py
+++ b/wcs/variables.py
@@ -22,10 +22,10 @@ from quixote import get_publisher, get_request
 
 from pyproj import Geod
 
-import qommon.misc
-from qommon.evalutils import make_datetime
-from qommon.templatetags.qommon import parse_datetime
-from qommon.storage import (Or, Equal, NotEqual)
+from .qommon import misc
+from .qommon.evalutils import make_datetime
+from .qommon.templatetags.qommon import parse_datetime
+from .qommon.storage import (Or, Equal, NotEqual)
 
 
 class LazyFormDefObjectsManager(object):
@@ -214,11 +214,11 @@ class LazyFormData(LazyFormDef):
 
     @property
     def receipt_date(self):
-        return qommon.misc.strftime(qommon.misc.date_format(), self._formdata.receipt_time)
+        return misc.strftime(misc.date_format(), self._formdata.receipt_time)
 
     @property
     def receipt_time(self):
-        return qommon.misc.strftime('%H:%M', self._formdata.receipt_time)
+        return misc.strftime('%H:%M', self._formdata.receipt_time)
 
     @property
     def number(self):
@@ -334,7 +334,7 @@ class LazyFormData(LazyFormDef):
                 value = field.convert_value_to_str(value)
             elif value is None:
                 value = ''
-            identifier_name = qommon.misc.simplify(field.label, space='_')
+            identifier_name = misc.simplify(field.label, space='_')
             d[identifier_name] = value
 
         return d
@@ -529,7 +529,7 @@ class LazyFieldVar(object):
 
     def __contains__(self, value):
         if self._field.key == 'items':
-            return qommon.misc.site_encode(value) in self._data.get(self._field.id)
+            return misc.site_encode(value) in self._data.get(self._field.id)
         return value in self.get_value()
 
     def __unicode__(self):
diff --git a/wcs/wf/aggregation_email.py b/wcs/wf/aggregation_email.py
index 633df12b3..d1e8488b4 100644
--- a/wcs/wf/aggregation_email.py
+++ b/wcs/wf/aggregation_email.py
@@ -14,12 +14,12 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from qommon import _
-from qommon.publisher import get_publisher_class
-from qommon.storage import StorableObject
-from qommon.form import *
-from qommon.cron import CronJob
-from qommon import emails
+from ..qommon import _
+from ..qommon.publisher import get_publisher_class
+from ..qommon.storage import StorableObject
+from ..qommon.form import *
+from ..qommon.cron import CronJob
+from ..qommon import emails
 
 from wcs.workflows import WorkflowStatusItem, register_item_class, \
         get_role_translation
diff --git a/wcs/wf/attachment.py b/wcs/wf/attachment.py
index f72e1cfb8..fd835859d 100644
--- a/wcs/wf/attachment.py
+++ b/wcs/wf/attachment.py
@@ -17,9 +17,9 @@
 
 from quixote import redirect
 
-from qommon import _
+from ..qommon import _
 from wcs.workflows import *
-from qommon.errors import *
+from ..qommon.errors import *
 
 from wcs.forms.common import FormStatusPage, FileDirectory
 from wcs.portfolio import has_portfolio, push_document
diff --git a/wcs/wf/backoffice_fields.py b/wcs/wf/backoffice_fields.py
index 060413149..a8f7d4ea2 100644
--- a/wcs/wf/backoffice_fields.py
+++ b/wcs/wf/backoffice_fields.py
@@ -16,8 +16,8 @@
 
 import xml.etree.ElementTree as ET
 
-from qommon import _
-from qommon.form import (WidgetListAsTable, CompositeWidget, SingleSelectWidget,
+from ..qommon import _
+from ..qommon.form import (WidgetListAsTable, CompositeWidget, SingleSelectWidget,
         ComputedExpressionWidget)
 from wcs.fields import WidgetField
 from wcs.workflows import (WorkflowStatusItem,
diff --git a/wcs/wf/criticality.py b/wcs/wf/criticality.py
index b498a62f8..55e40379d 100644
--- a/wcs/wf/criticality.py
+++ b/wcs/wf/criticality.py
@@ -16,7 +16,7 @@
 
 from quixote import get_publisher
 
-from qommon import _
+from ..qommon import _
 from wcs.qommon.form import SingleSelectWidget
 from wcs.workflows import WorkflowStatusItem, register_item_class
 
diff --git a/wcs/wf/dispatch.py b/wcs/wf/dispatch.py
index 97679e723..10be91ee1 100644
--- a/wcs/wf/dispatch.py
+++ b/wcs/wf/dispatch.py
@@ -17,10 +17,10 @@
 import collections
 import xml.etree.ElementTree as ET
 
-from qommon import _
-from qommon.form import *
-from qommon.template import Template
-from qommon import get_logger
+from ..qommon import _
+from ..qommon.form import *
+from ..qommon.template import Template
+from ..qommon import get_logger
 from wcs.roles import Role, get_user_roles
 from wcs.workflows import XmlSerialisable, WorkflowStatusItem, register_item_class
 
diff --git a/wcs/wf/export_to_model.py b/wcs/wf/export_to_model.py
index 3be60fa0d..7fa21fbdd 100644
--- a/wcs/wf/export_to_model.py
+++ b/wcs/wf/export_to_model.py
@@ -29,15 +29,14 @@ from quixote import get_response, get_request, get_publisher
 from quixote.directory import Directory
 from quixote.html import htmltext
 
-from qommon import _, ezt
-from qommon import get_logger
-from qommon.form import (SingleSelectWidget, WidgetList, CheckboxWidget,
+from ..qommon import _, ezt, misc
+from ..qommon import get_logger
+from ..qommon.form import (SingleSelectWidget, WidgetList, CheckboxWidget,
                          StringWidget, UploadWidget, WysiwygTextWidget, Upload,
                          UploadedFile, UploadValidationError, VarnameWidget,
                          RadiobuttonsWidget, PicklableUpload, ComputedExpressionWidget)
-from qommon.errors import PublishError
-from qommon.template import TemplateError
-import qommon
+from ..qommon.errors import PublishError
+from ..qommon.template import TemplateError
 
 from wcs.fields import SubtitleField, TitleField, CommentField, PageField
 from wcs.workflows import (WorkflowStatusItem, AttachmentEvolutionPart,
@@ -381,7 +380,7 @@ class ExportToModel(WorkflowStatusItem):
         return filename
 
     def get_directory_name(self):
-        return qommon.misc.simplify(self.label or 'export_to_model', space='_')
+        return misc.simplify(self.label or 'export_to_model', space='_')
     directory_name = property(get_directory_name)
 
     def apply_template_to_formdata(self, formdata):
diff --git a/wcs/wf/form.py b/wcs/wf/form.py
index 4f0b6074c..e88109512 100644
--- a/wcs/wf/form.py
+++ b/wcs/wf/form.py
@@ -16,8 +16,8 @@
 
 import xml.etree.ElementTree as ET
 
-from qommon import _
-from qommon.form import *
+from ..qommon import _
+from ..qommon.form import *
 
 from wcs.workflows import WorkflowStatusItem, register_item_class
 from wcs.formdef import FormDef, lax_int
diff --git a/wcs/wf/geolocate.py b/wcs/wf/geolocate.py
index 8034cf0e3..a91dbf551 100644
--- a/wcs/wf/geolocate.py
+++ b/wcs/wf/geolocate.py
@@ -26,11 +26,11 @@ except ImportError:
 
 from quixote import get_publisher
 
-from qommon import _
-from qommon import get_logger
-from qommon.errors import ConnectionError
-from qommon.form import RadiobuttonsWidget, ComputedExpressionWidget, CheckboxWidget
-from qommon.misc import http_get_page, normalize_geolocation
+from ..qommon import _
+from ..qommon import get_logger
+from ..qommon.errors import ConnectionError
+from ..qommon.form import RadiobuttonsWidget, ComputedExpressionWidget, CheckboxWidget
+from ..qommon.misc import http_get_page, normalize_geolocation
 from wcs.workflows import WorkflowStatusItem, register_item_class
 
 class GeolocateWorkflowStatusItem(WorkflowStatusItem):
diff --git a/wcs/wf/jump.py b/wcs/wf/jump.py
index 21960096b..6d5c4ede2 100644
--- a/wcs/wf/jump.py
+++ b/wcs/wf/jump.py
@@ -21,12 +21,12 @@ import sys
 from quixote import get_publisher, get_request, redirect
 
 from quixote.directory import Directory
-from qommon import _
-from qommon.humantime import *
-from qommon.form import *
-from qommon import errors
-from qommon.publisher import get_publisher_class
-from qommon.cron import CronJob
+from ..qommon import _
+from ..qommon.humantime import *
+from ..qommon.form import *
+from ..qommon import errors
+from ..qommon.publisher import get_publisher_class
+from ..qommon.cron import CronJob
 
 from wcs.workflows import Workflow, WorkflowStatusJumpItem, register_item_class
 from wcs.api import get_user_from_api_query_string, is_url_signed
diff --git a/wcs/wf/notification.py b/wcs/wf/notification.py
index c171a0a4c..aecde984f 100644
--- a/wcs/wf/notification.py
+++ b/wcs/wf/notification.py
@@ -16,10 +16,10 @@
 
 from quixote import get_publisher
 
-from qommon import _, ezt
-from qommon.form import *
-from qommon.template import TemplateError
-from qommon import get_logger
+from ..qommon import _, ezt
+from ..qommon.form import *
+from ..qommon.template import TemplateError
+from ..qommon import get_logger
 
 from wcs.roles import Role
 from wcs.workflows import (WorkflowStatusItem, register_item_class,
diff --git a/wcs/wf/profile.py b/wcs/wf/profile.py
index 22db00072..7998cb360 100644
--- a/wcs/wf/profile.py
+++ b/wcs/wf/profile.py
@@ -23,12 +23,12 @@ import xml.etree.ElementTree as ET
 
 from quixote import get_publisher, get_response
 
-from qommon import _
-from qommon.form import (CompositeWidget, SingleSelectWidget,
+from ..qommon import _
+from ..qommon.form import (CompositeWidget, SingleSelectWidget,
         WidgetListAsTable, ComputedExpressionWidget)
-from qommon.ident.idp import is_idp_managing_user_attributes
-from qommon.misc import http_patch_request, JSONEncoder
-from qommon.publisher import get_cfg, get_logger
+from ..qommon.ident.idp import is_idp_managing_user_attributes
+from ..qommon.misc import http_patch_request, JSONEncoder
+from ..qommon.publisher import get_cfg, get_logger
 
 from wcs.api_utils import sign_url, get_secret_and_orig, MissingSecret
 from wcs.workflows import XmlSerialisable, WorkflowStatusItem, register_item_class
diff --git a/wcs/wf/redirect_to_url.py b/wcs/wf/redirect_to_url.py
index 46d130323..a3eef8aad 100644
--- a/wcs/wf/redirect_to_url.py
+++ b/wcs/wf/redirect_to_url.py
@@ -14,8 +14,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from qommon import _
-from qommon.form import ComputedExpressionWidget
+from ..qommon import _
+from ..qommon.form import ComputedExpressionWidget
 from wcs.workflows import WorkflowStatusItem, register_item_class
 
 
diff --git a/wcs/wf/register_comment.py b/wcs/wf/register_comment.py
index 5cb9970fe..e99942807 100644
--- a/wcs/wf/register_comment.py
+++ b/wcs/wf/register_comment.py
@@ -16,10 +16,10 @@
 
 import cgi
 
-from qommon import _, ezt
-from qommon.form import *
-from qommon.template import TemplateError
-from qommon import get_logger
+from ..qommon import _, ezt
+from ..qommon.form import *
+from ..qommon.template import TemplateError
+from ..qommon import get_logger
 
 from wcs.workflows import (WorkflowStatusItem, register_item_class, template_on_formdata,
                            AttachmentEvolutionPart)
diff --git a/wcs/wf/remove.py b/wcs/wf/remove.py
index 6e56f145e..a681e239d 100644
--- a/wcs/wf/remove.py
+++ b/wcs/wf/remove.py
@@ -15,7 +15,7 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
 from quixote import get_publisher, get_request, get_response, get_session
-from qommon import _
+from ..qommon import _
 from wcs.workflows import WorkflowStatusItem, register_item_class
 
 class RemoveWorkflowStatusItem(WorkflowStatusItem):
diff --git a/wcs/wf/resubmit.py b/wcs/wf/resubmit.py
index 9f4f44ce1..8e18381cb 100644
--- a/wcs/wf/resubmit.py
+++ b/wcs/wf/resubmit.py
@@ -16,7 +16,7 @@
 
 from quixote import get_publisher, get_request, get_session
 
-from qommon import _
+from ..qommon import _
 from wcs.workflows import WorkflowStatusItem, register_item_class
 from wcs.formdef import FormDef
 from wcs.qommon.form import (WidgetList, SingleSelectWidget, StringWidget,
diff --git a/wcs/wf/roles.py b/wcs/wf/roles.py
index af37faa0f..0d0b6614c 100644
--- a/wcs/wf/roles.py
+++ b/wcs/wf/roles.py
@@ -21,13 +21,13 @@ from django.utils.six.moves.urllib import parse as urlparse
 
 from quixote import get_request, get_publisher, get_response
 
-from qommon import _
-from qommon.form import *
+from ..qommon import _
+from ..qommon.form import *
 from wcs.workflows import WorkflowStatusItem, register_item_class
 from wcs.roles import get_user_roles, Role
-from qommon.ident.idp import is_idp_managing_user_attributes
-from qommon.misc import http_post_request, http_delete_request
-from qommon.publisher import get_cfg, get_logger
+from ..qommon.ident.idp import is_idp_managing_user_attributes
+from ..qommon.misc import http_post_request, http_delete_request
+from ..qommon.publisher import get_cfg, get_logger
 from wcs.api_utils import sign_url, get_secret_and_orig, MissingSecret
 
 
diff --git a/wcs/wf/wscall.py b/wcs/wf/wscall.py
index 2bc02df61..5eaafd132 100644
--- a/wcs/wf/wscall.py
+++ b/wcs/wf/wscall.py
@@ -25,10 +25,10 @@ from StringIO import StringIO
 
 from quixote.html import TemplateIO, htmltext
 
-from qommon import _
-from qommon.errors import ConnectionError
-from qommon.form import *
-from qommon.misc import json_loads, site_encode
+from ..qommon import _
+from ..qommon.errors import ConnectionError
+from ..qommon.form import *
+from ..qommon.misc import json_loads, site_encode
 from wcs.workflows import (WorkflowStatusItem, register_item_class,
         AbortActionException, AttachmentEvolutionPart)
 from wcs.wscalls import call_webservice
diff --git a/wcs/workflows.py b/wcs/workflows.py
index 7db1442b8..ac24ce7f3 100644
--- a/wcs/workflows.py
+++ b/wcs/workflows.py
@@ -14,7 +14,7 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 
-from qommon import ezt
+from .qommon import ezt
 import collections
 import copy
 import datetime
@@ -29,21 +29,21 @@ from django.utils.six import StringIO
 
 from quixote import get_request, get_response, redirect
 
-from qommon import _
-from qommon.misc import C_, get_as_datetime, file_digest, get_foreground_colour
-from qommon.storage import StorableObject, atomic_write, NotEqual, Contains, Null
-from qommon.form import *
-from qommon.humantime import seconds2humanduration
-from qommon import emails, get_cfg, get_logger
+from .qommon import _
+from .qommon.misc import C_, get_as_datetime, file_digest, get_foreground_colour
+from .qommon.storage import StorableObject, atomic_write, NotEqual, Contains, Null
+from .qommon.form import *
+from .qommon.humantime import seconds2humanduration
+from .qommon import emails, get_cfg, get_logger
 from quixote.html import htmltext
-import qommon.errors
-from qommon.template import Template, TemplateError
+from .qommon import errors
+from .qommon.template import Template, TemplateError
 
-from wcs.conditions import Condition
-from wcs.roles import Role, logged_users_role, get_user_roles
-from wcs.fields import FileField
-from wcs.formdef import FormDef
-from wcs.formdata import Evolution
+from .conditions import Condition
+from .roles import Role, logged_users_role, get_user_roles
+from .fields import FileField
+from .formdef import FormDef
+from .formdata import Evolution
 
 if not __name__.startswith('wcs.') and not __name__ == "__main__":
     raise ImportError('Import of workflows module must be absolute (import wcs.workflows)')
@@ -677,7 +677,7 @@ class Workflow(StorableObject):
 
     @classmethod
     def get_default_workflow(cls):
-        from qommon.admin.emails import EmailsDirectory
+        from .qommon.admin.emails import EmailsDirectory
 
         workflow = Workflow(name=_('Default'))
         workflow.id = '_default'
@@ -2667,14 +2667,14 @@ class SendSMSWorkflowStatusItem(WorkflowStatusItem):
                                'sms could not be generated' % (url, str(e)))
             return
 
-        import qommon.sms
+        from .qommon import sms
 
         sms_cfg = get_cfg('sms', {})
         sender = sms_cfg.get('sender', 'AuQuotidien')[:11]
         mode = sms_cfg.get('mode', 'none')
         try:
-            qommon.sms.SMS.get_sms_class(mode).send(sender, destinations, sms_body[:160])
-        except qommon.errors.SMSError as e:
+            sms.SMS.get_sms_class(mode).send(sender, destinations, sms_body[:160])
+        except errors.SMSError as e:
             get_logger().error(e)
 
 register_item_class(SendSMSWorkflowStatusItem)
@@ -2862,24 +2862,24 @@ register_item_class(EditableWorkflowStatusItem)
 
 
 def load_extra():
-    import wf.aggregation_email
-    import wf.timeout_jump
-    import wf.jump
-    import wf.attachment
-    import wf.remove
-    import wf.roles
-    import wf.dispatch
-    import wf.geolocate
-    import wf.wscall
-    import wf.form
-    import wf.register_comment
-    import wf.anonymise
-    import wf.export_to_model
-    import wf.resubmit
-    import wf.criticality
-    import wf.profile
-    import wf.backoffice_fields
-    import wf.redirect_to_url
-    import wf.notification
-
-from wf.export_to_model import ExportToModel
+    from .wf import aggregation_email
+    from .wf import timeout_jump
+    from .wf import jump
+    from .wf import attachment
+    from .wf import remove
+    from .wf import roles
+    from .wf import dispatch
+    from .wf import geolocate
+    from .wf import wscall
+    from .wf import form
+    from .wf import register_comment
+    from .wf import anonymise
+    from .wf import export_to_model
+    from .wf import resubmit
+    from .wf import criticality
+    from .wf import profile
+    from .wf import backoffice_fields
+    from .wf import redirect_to_url
+    from .wf import notification
+
+from .wf.export_to_model import ExportToModel
diff --git a/wcs/wscalls.py b/wcs/wscalls.py
index 4fc24cb11..21321ef21 100644
--- a/wcs/wscalls.py
+++ b/wcs/wscalls.py
@@ -24,13 +24,13 @@ from django.utils.six.moves.urllib import parse as urlparse
 
 from quixote import get_publisher, get_request
 
-from qommon import _
-from qommon.misc import simplify, get_variadic_url, JSONEncoder, json_loads
-from qommon.xml_storage import XmlStorableObject
-from qommon.form import (CompositeWidget, StringWidget, WidgetDict,
+from .qommon import _
+from .qommon.misc import simplify, get_variadic_url, JSONEncoder, json_loads
+from .qommon.xml_storage import XmlStorableObject
+from .qommon.form import (CompositeWidget, StringWidget, WidgetDict,
         ComputedExpressionWidget, RadiobuttonsWidget, CheckboxWidget)
-import qommon.misc
-from qommon.template import Template
+from .qommon import misc
+from .qommon.template import Template
 
 from wcs.api_utils import sign_url, get_secret_and_orig, MissingSecret
 from wcs.workflows import WorkflowStatusItem
@@ -109,13 +109,13 @@ def call_webservice(url, qs_data=None, request_signature_key=None,
             headers['Content-type'] = 'application/json'
             payload = json.dumps(payload, cls=JSONEncoder,
                     encoding=get_publisher().site_charset)
-        response, status, data, auth_header = qommon.misc._http_request(
+        response, status, data, auth_header = misc._http_request(
                 url, method=method, body=payload, headers=headers)
     elif method == 'DELETE':
-        response, status, data, auth_header = qommon.misc._http_request(
+        response, status, data, auth_header = misc._http_request(
             url, method='DELETE', headers=headers)
     else:
-        response, status, data, auth_header = qommon.misc.http_get_page(
+        response, status, data, auth_header = misc.http_get_page(
                 url, headers=headers)
         request = get_request()
         if cache is True and request and hasattr(request, 'wscalls_cache'):
-- 
2.23.0

