diff --git a/.gitignore b/.gitignore index 47a624a3..f9e2c706 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ dist/ downloads/ eggs/ .eggs/ -lib/ +/lib/ lib64/ parts/ sdist/ @@ -94,3 +94,6 @@ ENV/ settings_production.py /sql-logfile.txt /logfile.txt +/tulius/static/node_modules/ +/tulius/static/app/index_bundle.js +/tulius/static/package-lock.json diff --git a/Dockerfile b/Dockerfile index 4a82a913..9d880789 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,16 @@ FROM kozzztik/tulius:base_3.0.3 +RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - +RUN apt-get update && apt-get install nodejs git -y +RUN npm install @vue/cli -g +RUN pip install hypercorn==0.11.1 +CMD [ "hypercorn", "-b", "0.0.0.0:7000", "-w", "2", "asgi:application" ] + ADD tulius /opt/tulius/tulius ADD djfw /opt/tulius/djfw ADD manage.py /opt/tulius/manage.py ADD requirements.txt /opt/tulius/requirements.txt -ADD wsgi.py /opt/tulius/wsgi.py -ADD async_app.py /opt/tulius/async_app.py +ADD asgi.py /opt/tulius/asgi.py ADD settings.py /opt/tulius/settings.py ADD .pylintrc /opt/tulius/.pylintrc ADD tests /opt/tulius/tests @@ -22,3 +27,4 @@ ADD .git /opt/tulius/.git ENV TULIUS_BRANCH local RUN python manage.py compilemessages +RUN cd tulius/static && npm install && npm run build diff --git a/README.md b/README.md index 7f217e64..ff3f24c1 100644 --- a/README.md +++ b/README.md @@ -88,10 +88,10 @@ Repo for http://tulius.com project. ``` Edit settings files. Change DB passwords and sentry DSN. -11. Install nginx. Configure it using templates: +11. Configure Nginx using templates: ```bash - cp /home/travis/master/scripts/tulius/nginx/sentry.conf /etc/nginx/conf.d/sentry.conf - cp /home/travis/master/scripts/tulius/nginx/tulius.conf /etc/nginx/conf.d/tulius.conf + cp /home/travis/master/scripts/tulius/nginx_production.conf /etc/nginx/conf.d/tulius_prod.conf + cp /home/travis/master/scripts/tulius/nginx_dev.conf /etc/nginx/conf.d/tulius_dev.conf ``` 12. Install letsEncrypt and configure SSL. @@ -115,10 +115,21 @@ Update repo if needed (use separate branch and PR) ``` 16. Check that everything works. Profit. -## Running on local environment +# Running on local environment -To use Tulius on local dev environment you need to run 3 instances. For both of them -it is needed to set environment variable: +To run frontend part you need to install node.js & npm: +- for Windows use installer https://nodejs.org/en/download/ +- for Linux (Debian based) ```apt-get install nodejs``` + +Then switch to tulius/static folder and run +``` +npm install @vue/cli -g +npm install -D +``` + +To use Tulius on local dev environment you need to at least 2 instances +3 for correct work of heavy requests). +For all of them it is needed to set environment variable: ```bash TULIUS_BRANCH=local @@ -128,10 +139,10 @@ If you need some special configuration options, you can create `settings_product file from template and set needed options there. Instances, that needed to run: -1. `manage.py runserver` - Django instance for normal HTTP requests -2. `async_app.py` - for web sockets support -3. `celery -A tulius worker -l info` - for deferred tasks - +1. `manage.py runserver` - Django instance for backend HTTP requests +2. `celery -A tulius worker -l info` - for deferred tasks (optional) +3. `npm run serve` in tulius/static directory for frontend webpack dev server + On Windows, as Celery not supports it yet, install gevent: ```pip install gevent``` @@ -140,6 +151,14 @@ and start celery with: ```celery -A tulius worker -l info -P gevent``` +or, instead of starting Celery, you can switch it off, by adding: + +```CELERY_TASK_ALWAYS_EAGER = True``` + +to settings_production.py. However, some heavy requests, like reindexing may +became too slow to render pages, as deferred tasks will be resolved in request +context. But for most things it will be enough. + ## Running tests ``` diff --git a/asgi.py b/asgi.py new file mode 100644 index 00000000..fe962a5d --- /dev/null +++ b/asgi.py @@ -0,0 +1,18 @@ +import os + +from django.conf import settings +from django.contrib.staticfiles import handlers as static_handlers + +from tulius.websockets.asgi.asgi_handler import get_asgi_application + +if os.path.exists('settings_production.py'): + settings_file = 'settings_production' +else: + settings_file = 'settings' +os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_file) + + +application = get_asgi_application() + +if settings.DEBUG: + application = static_handlers.ASGIStaticFilesHandler(application) diff --git a/async_app.py b/async_app.py deleted file mode 100644 index 3bc767a1..00000000 --- a/async_app.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -import django - -from tulius.websockets import app - - -if os.path.exists('settings_production.py'): - settings_file = 'settings_production' -else: - settings_file = 'settings' - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_file) -django.setup() -app.main() diff --git a/djfw/flatpages/middleware.py b/djfw/flatpages/middleware.py index c93b83e2..8d0aa912 100755 --- a/djfw/flatpages/middleware.py +++ b/djfw/flatpages/middleware.py @@ -1,9 +1,18 @@ +import asyncio +import functools + from django import http from django.conf import settings from djfw.flatpages import views +def flatpage_middleware(get_response): + if asyncio.iscoroutinefunction(get_response): + return AsyncFlatpageFallbackMiddleware(get_response) + return FlatpageFallbackMiddleware(get_response) + + class FlatpageFallbackMiddleware: def __init__(self, get_response): self.get_response = get_response @@ -20,7 +29,32 @@ def __call__(self, request): # is a middleware, we can't assume the errors will be caught elsewhere. except http.Http404: return response + + +class AsyncFlatpageFallbackMiddleware: + _is_coroutine = asyncio.coroutines._is_coroutine + + def __init__(self, get_response): + self.get_response = get_response + + async def __call__(self, request): + response = await self.get_response(request) + + if response.status_code != 404: + # No need to check for a flatpage for non-404 responses. + return response + try: + return await asyncio.get_event_loop().run_in_executor( + None, functools.partial( + views.flatpage, request, request.path_info)) + # Return the original response if any errors happened. Because this + # is a middleware, we can't assume the errors will be caught elsewhere. + except http.Http404: + return response except: if settings.DEBUG: raise return response + + +flatpage_middleware.async_capable = True diff --git a/djfw/pagination/middleware.py b/djfw/pagination/middleware.py index cf435728..5c7b005e 100755 --- a/djfw/pagination/middleware.py +++ b/djfw/pagination/middleware.py @@ -1,3 +1,6 @@ +import asyncio + + def get_page(self): """ A function which will be monkeypatched onto the request to get the current @@ -15,6 +18,12 @@ def get_page(self): return 1 +def pagination_middleware(get_response): + if asyncio.iscoroutinefunction(get_response): + return AsyncPaginationMiddleware(get_response) + return PaginationMiddleware(get_response) + + class PaginationMiddleware: """ Inserts a variable representing the current page onto the request object if @@ -26,3 +35,17 @@ def __init__(self, get_response): def __call__(self, request): request.page = get_page(request) return self.get_response(request) + + +class AsyncPaginationMiddleware: + _is_coroutine = asyncio.coroutines._is_coroutine + + def __init__(self, get_response): + self.get_response = get_response + + async def __call__(self, request): + request.page = get_page(request) + return await self.get_response(request) + + +pagination_middleware.async_capable = True diff --git a/scripts/BaseDockerfile b/scripts/BaseDockerfile index efcfb528..4f9af22f 100644 --- a/scripts/BaseDockerfile +++ b/scripts/BaseDockerfile @@ -1,22 +1,17 @@ FROM python:3.7 EXPOSE 7000 -RUN apt-get update && apt-get install gettext -y +RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - +RUN apt-get update && apt-get install gettext git nodejs -y +RUN npm install @vue/cli -g ENV PYTHONUNBUFFERED 1 ENV TULIUS_BRANCH local RUN mkdir /opt/tulius WORKDIR /opt/tulius -CMD [ "uwsgi", "--socket", "0.0.0.0:7000", \ - "--protocol", "uwsgi", \ - "--max-requests", "5000", \ - "--threads", "4", \ - "--processes", "2", \ - "--master", \ - "--disable-write-exception", \ - "--wsgi", "wsgi:application" ] +CMD [ "hypercorn", "-b", "0.0.0.0:7000", "-w", "2", "asgi:application" ] ## install requirements, so they can be cached by Docker -RUN pip install uwsgi django==3.1.1 pytz==2020.1 pillow==6.2.0 \ +RUN pip install hypercorn==0.11.1 django==3.1.1 pytz==2020.1 pillow==6.2.0 \ mysqlclient==2.0.1 pyyaml==5.3.1 django-hamlpy==1.1.1 \ redis==3.5.3 django-redis-cache==2.1.1 aioredis==1.3.1 \ celery==4.4.7 django-celery-results==1.2.1 \ diff --git a/scripts/on_update.sh b/scripts/on_update.sh index 0b2f35cf..f965c4e3 100644 --- a/scripts/on_update.sh +++ b/scripts/on_update.sh @@ -14,7 +14,7 @@ fi echo "Stop existing compose" cd scripts/tulius/$ENV # First stop web then wait till celery will finish all tasks -docker-compose stop uwsgi +docker-compose stop web docker-compose exec celery python manage.py wait_celery || true docker-compose down --remove-orphans docker system prune --force diff --git a/scripts/tulius/dev/docker-compose.yml b/scripts/tulius/dev/docker-compose.yml index 1dda0d60..ade33f91 100644 --- a/scripts/tulius/dev/docker-compose.yml +++ b/scripts/tulius/dev/docker-compose.yml @@ -1,6 +1,6 @@ version: '3.5' services: - uwsgi: + web: image: kozzztik/tulius:dev networks: tuliusnet: @@ -18,23 +18,6 @@ services: max-size: "100m" max-file: "10" - websockets: - image: kozzztik/tulius:dev - networks: - tuliusnet: - ipv4_address: 10.5.0.21 - restart: unless-stopped - command: ["python3", "/opt/tulius/async_app.py"] - environment: - TULIUS_BRANCH: dev - volumes: - - ../../../settings_production.py:/opt/tulius/settings_production.py - logging: - driver: json-file - options: - max-size: "100m" - max-file: "2" - celery: image: kozzztik/tulius:dev networks: diff --git a/scripts/tulius/docker-compose.yml b/scripts/tulius/docker-compose.yml index 41fe49b4..627a5085 100644 --- a/scripts/tulius/docker-compose.yml +++ b/scripts/tulius/docker-compose.yml @@ -21,21 +21,6 @@ services: - ./mysql.cnf:/etc/my.cnf:ro container_name: tulius_mysql - nginx: - image: nginx - restart: always - networks: - tuliusnet: - ipv4_address: 10.5.0.4 - ports: - - "127.0.0.1:8080:80" - volumes: - - ./nginx.conf:/etc/nginx/nginx.conf:ro - - /home/travis/master/data:/opt/master_data - - /home/travis/dev/data:/opt/dev_data - command: ['nginx', '-g', 'daemon off;'] - container_name: tulius_nginx - mail: build: context: ./postfix diff --git a/scripts/tulius/master/docker-compose.yml b/scripts/tulius/master/docker-compose.yml index b0a39635..0479ed54 100644 --- a/scripts/tulius/master/docker-compose.yml +++ b/scripts/tulius/master/docker-compose.yml @@ -1,6 +1,6 @@ version: '3.5' services: - uwsgi: + web: image: kozzztik/tulius:master networks: tuliusnet: @@ -17,23 +17,6 @@ services: max-size: "100m" max-file: "10" - websockets: - image: kozzztik/tulius:master - networks: - tuliusnet: - ipv4_address: 10.5.0.11 - restart: unless-stopped - command: ["python3", "/opt/tulius/async_app.py"] - environment: - TULIUS_BRANCH: master - volumes: - - ../../../settings_production.py:/opt/tulius/settings_production.py - logging: - driver: json-file - options: - max-size: "100m" - max-file: "2" - celery: image: kozzztik/tulius:master networks: diff --git a/scripts/tulius/nginx.conf b/scripts/tulius/nginx.conf index 46c7a06d..d87186dc 100644 --- a/scripts/tulius/nginx.conf +++ b/scripts/tulius/nginx.conf @@ -25,7 +25,6 @@ http { gzip on; gzip_disable "msie6"; - server { listen 80; server_name tulius.com; @@ -49,22 +48,12 @@ http { location /favicon.ico { alias /opt/master_data/static/favicon.ico; } - location /ws/ { - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://10.5.0.11:7000; - } - location /ws_new/ { - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://10.5.0.11:7000; - } # Finally, send all non-media requests to the Django server. location / { - uwsgi_pass uwsgi://10.5.0.10:7000; - include uwsgi_params; # the uwsgi_params file you installed + proxy_set_header X-Forwarded-Proto-Version $http2; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://10.5.0.10:7000; } } @@ -93,22 +82,12 @@ http { location /favicon.ico { alias /opt/dev_data/static/favicon.ico; } - location /ws/ { - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://10.5.0.21:7000; - } - location /ws_new/ { - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://10.5.0.21:7000; - } # Finally, send all non-media requests to the Django server. location / { - uwsgi_pass uwsgi://10.5.0.20:7000; - include uwsgi_params; # the uwsgi_params file you installed + proxy_set_header X-Forwarded-Proto-Version $http2; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://10.5.0.20:7000; } } diff --git a/scripts/tulius/nginx/sentry.conf b/scripts/tulius/nginx/sentry.conf deleted file mode 100644 index e8028fec..00000000 --- a/scripts/tulius/nginx/sentry.conf +++ /dev/null @@ -1,24 +0,0 @@ -server { - listen 80; - server_name sentry.co-de.org; - - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_pass http://192.168.0.2:80; - proxy_redirect off; - } - - listen 443 ssl; # managed by Certbot - ssl_certificate /etc/letsencrypt/live/svn.milana.co-de.org/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/svn.milana.co-de.org/privkey.pem; # managed by Certbot - ssl_session_cache shared:le_nginx_SSL:1m; # managed by Certbot - ssl_session_timeout 1440m; # managed by Certbot - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # managed by Certbot - ssl_prefer_server_ciphers on; # managed by Certbot - - ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA"; # managed by Certbot -} diff --git a/scripts/tulius/nginx/tulius.conf b/scripts/tulius/nginx/tulius.conf deleted file mode 100644 index ceb93f43..00000000 --- a/scripts/tulius/nginx/tulius.conf +++ /dev/null @@ -1,106 +0,0 @@ -server { - listen 80; - server_name www.tulius.com; - return 302 http://tulius.com$request_uri; - - listen 443 ssl; # managed by Certbot - ssl_certificate /etc/letsencrypt/live/svn.milana.co-de.org/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/svn.milana.co-de.org/privkey.pem; # managed by Certbot - ssl_session_cache shared:le_nginx_SSL:1m; # managed by Certbot - ssl_session_timeout 1440m; # managed by Certbot - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # managed by Certbot - ssl_prefer_server_ciphers on; # managed by Certbot - - ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA"; # managed by Certbot -} - -server { - listen 80; - server_name test.tulius.com; - server_name test.tulius.co-de.org; - server_name dev.tulius.co-de.org; - server_name dev.tulius.kozzz.ru; -# if ($remote_addr != 178.236.141.69) { -# return 503; -# } - location / { - proxy_set_header Host $host; - proxy_pass http://127.0.0.1:8080; - } - location /ws/ { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://127.0.0.1:8080; - } - location /ws_new/ { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://127.0.0.1:8080; - } - listen 443 ssl; # managed by Certbot - ssl_certificate /etc/letsencrypt/live/svn.milana.co-de.org/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/svn.milana.co-de.org/privkey.pem; # managed by Certbot - - ssl_session_cache shared:le_nginx_SSL:1m; # managed by Certbot - ssl_session_timeout 1440m; # managed by Certbot - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # managed by Certbot - ssl_prefer_server_ciphers on; # managed by Certbot - - ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA"; # managed by Certbot -} - -server { - listen 80; - server_name kibana.test.tulius.co-de.org; - server_name kibana.tulius.co-de.org; - - location / { - proxy_set_header Host $host; - proxy_pass http://127.0.0.1:8080; - auth_basic "Restricted"; - auth_basic_user_file /etc/nginx/htpasswd; - } -} - -server { - listen 80; - listen 443 ssl; - server_name tulius.com; - server_name tulius.co-de.org; - server_name master.tulius.co-de.org; - ssl_certificate /etc/letsencrypt/live/svn.milana.co-de.org/fullchain.pem; # managed by Certbot - ssl_certificate_key /etc/letsencrypt/live/svn.milana.co-de.org/privkey.pem; # managed by Certbot - -# if ($remote_addr != 178.236.141.69) { -# return 503; -# } - - location / { - proxy_set_header Host $host; - proxy_pass http://127.0.0.1:8080; - } - location /ws/ { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://127.0.0.1:8080; - } - location /ws_new/ { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $host; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://127.0.0.1:8080; - } -} diff --git a/scripts/tulius/nginx_dev.conf b/scripts/tulius/nginx_dev.conf new file mode 100644 index 00000000..8ce79286 --- /dev/null +++ b/scripts/tulius/nginx_dev.conf @@ -0,0 +1,88 @@ +#server { +# listen 80; +# listen [::]:80; +# +# server_name test.tulius.com; +# server_name test.tulius.co-de.org; +# server_name dev.tulius.co-de.org; +# server_name dev.tulius.kozzz.ru; +# +# return 301 https://$server_name$request_uri; +#} + +server { + listen 80; + # the domain name it will serve for + server_name test.tulius.com; + server_name test.tulius.co-de.org; + server_name dev.tulius.co-de.org; + server_name dev.tulius.kozzz.ru; + charset utf-8; + +# if ($remote_addr != 178.236.141.69) { +# return 503; +# } + + # max upload size + client_max_body_size 75M; # adjust to taste + + # Django media + location /media { + # your Django project's media files - amend as required + alias /home/travis/dev/data/media; + } + location /static { + # your Django project's static files - amend as required + alias /home/travis/dev/data/static; + } + location /robots.txt { + alias /home/travis/dev/data/static/no-robots.txt; + } + location /favicon.ico { + alias /home/travis/dev/data/static/favicon.ico; + } + # Finally, send all non-media requests to the Django server. + location / { + proxy_set_header Host $host; + proxy_set_header User-Agent $http_user_agent; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto-Version $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://10.5.0.20:7000; + } +} + +server { + listen 80; + server_name kibana.tulius.com; + server_name kibana.tulius.co-de.org; + charset utf-8; + location / { + proxy_pass http://10.5.0.13:5601; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + auth_basic "Restricted"; + auth_basic_user_file /etc/nginx/htpasswd; + } +} + +server { + listen 80; + server_name kibana.test.tulius.co-de.org; + charset utf-8; + location / { + proxy_pass http://10.5.0.23:5601; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + auth_basic "Restricted"; + auth_basic_user_file /etc/nginx/htpasswd; + } +} diff --git a/scripts/tulius/nginx_production.conf b/scripts/tulius/nginx_production.conf new file mode 100644 index 00000000..f5c9f71a --- /dev/null +++ b/scripts/tulius/nginx_production.conf @@ -0,0 +1,50 @@ +server { + listen 80; + server_name www.tulius.com; +# server_name tulius.com; +# server_name tulius.co-de.org; +# server_name master.tulius.co-de.org; + return 302 https://tulius.com$request_uri; +} + +server { + listen 80; + server_name tulius.com; + server_name tulius.co-de.org; + server_name master.tulius.co-de.org; + charset utf-8; + +# if ($remote_addr != 178.236.141.69) { +# return 503; +# } + + # max upload size + client_max_body_size 75M; # adjust to taste + + # Django media + location /media { + # your Django project's media files - amend as required + alias /home/travis/master/data/media; + } + location /static { + # your Django project's static files - amend as required + alias /home/travis/master/data/static; + } + location /robots.txt { + alias /home/travis/master/data/static/robots.txt; + } + location /favicon.ico { + alias /home/travis/master/data/static/favicon.ico; + } + # Finally, send all non-media requests to the Django server. + location / { + proxy_set_header Host $host; + proxy_set_header User-Agent $http_user_agent; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto-Version $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://10.5.0.10:7000; + } +} diff --git a/settings.py b/settings.py index dbd8654f..0b340c2f 100644 --- a/settings.py +++ b/settings.py @@ -88,20 +88,20 @@ 'tulius.events.EventsConfig', 'tulius.vk', 'tulius.counters', - 'tulius.websockets', + 'tulius.websockets.WebsocketsConfig', ) MIDDLEWARE = ( # 'raven.contrib.django.raven_compat.middleware.Sentry404CatchMiddleware', - 'tulius.core.profiler.ProfilerMiddleware', + 'tulius.core.profiler.profiler_middleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', - 'djfw.pagination.middleware.PaginationMiddleware', - 'djfw.flatpages.middleware.FlatpageFallbackMiddleware', + 'djfw.pagination.middleware.pagination_middleware', + 'djfw.flatpages.middleware.flatpage_middleware', ) STATICFILES_FINDERS = ( @@ -127,7 +127,6 @@ 'django.template.context_processors.media', 'django.template.context_processors.request', 'django.template.context_processors.static', - 'tulius.websockets.context_processors.default', 'djfw.flatpages.context_processors.flatpages', 'djfw.datablocks.context_processors.datablocks', ], @@ -138,6 +137,18 @@ }, ] +if env == 'dev': + VUE_BUNDLE = [ + 'http://localhost:9000/static/js/chunk-vendors.js', + 'http://localhost:9000/static/js/app.js' + ] +else: + VUE_BUNDLE = [ + '/static/dist/js/chunk-vendors.js', + '/static/dist/js/app.js' + ] + + AUTHENTICATION_BACKENDS = ( 'tulius.vk.backend.VKBackend', 'django.contrib.auth.backends.ModelBackend', @@ -298,14 +309,6 @@ 'password': '', } -ASYNC_SERVER = { - 'host': '127.0.0.1' if env == 'dev' else '0.0.0.0', - 'port': 7000 -} - -WEBSOCKET_URL = '/ws/' -WEBSOCKET_URL_NEW = '/ws_new/' - # Actual credentials are hold in settings_production.py file. DATABASES = { 'default': { diff --git a/tulius/core/profiler.py b/tulius/core/profiler.py index 1ab51f3f..55b23cf2 100644 --- a/tulius/core/profiler.py +++ b/tulius/core/profiler.py @@ -1,3 +1,4 @@ +import asyncio import threading import time import logging @@ -6,79 +7,107 @@ from ua_parser import user_agent_parser -class ProfilerMiddleware: +def get_user_data(request): + result = {} + try: + user_data = user_agent_parser.Parse( + request.META['HTTP_USER_AGENT'] + if 'HTTP_USER_AGENT' in request.META else '') + user_agent = user_data['user_agent'] + os = user_data['os'] + device_family = user_data['device']['family'] + result = { + 'browser': user_agent['family'], + 'browser_version': user_agent['major'], + 'os': os['family'], + 'os_version': os['major'], + 'device': device_family, + 'mobile': device_family not in [None, 'Spider', 'Other'], + + } + if user_agent['minor']: + result['browser_version'] += '.' + user_agent['minor'] + if not result['os_version']: + os_list = result['os'].split() + if len(os_list) == 2: + result['os'] = os_list[0] + result['os_version'] = os_list[1] + if os['minor']: + result['os_version'] += '.' + os['minor'] + except Exception: + logger = logging.getLogger('django.request') + logger.error( + 'Cant parse user agent %s', + request.META.get('HTTP_USER_AGENT')) + return result + + +def log_record(request, exec_time, response): + # get only cached user. Don't trigger auth just for profiling needs. + # Also, auth middleware may be not installed. + user = getattr(request, '_cached_user', None) + if isinstance(response, http.StreamingHttpResponse): + content_length = None + else: + content_length = len(response.content) + logging.getLogger('profiler').info(request.path, extra={ + 'method': request.method, + 'status_code': response.status_code, + 'content_length': content_length, + **({ + 'app_name': request.resolver_match.app_name, + 'url_name': request.resolver_match.url_name, + 'view_name': request.resolver_match.view_name, + 'url_args': request.resolver_match.args, + 'url_kwargs': [{ + 'name': name, + 'value': value + } for name, value in request.resolver_match.kwargs.items()] + } if request.resolver_match else {}), + 'user': { + 'id': user.id, + 'title': user.username + } if user and user.is_authenticated else None, + 'exec_time': exec_time / 1000000, + 'thread_id': threading.current_thread().ident, + 'ip': request.META['REMOTE_ADDR'], + **get_user_data(request), + **request.profiling_data, + }) + + +def profiler_middleware(get_response): + if asyncio.iscoroutinefunction(get_response): + return AsyncProfilerMiddleware(get_response) + return SyncProfilerMiddleware(get_response) + + +class SyncProfilerMiddleware: def __init__(self, get_response): self.get_response = get_response - @staticmethod - def get_user_data(request): - result = {} - try: - user_data = user_agent_parser.Parse( - request.META['HTTP_USER_AGENT'] - if 'HTTP_USER_AGENT' in request.META else '') - user_agent = user_data['user_agent'] - os = user_data['os'] - device_family = user_data['device']['family'] - result = { - 'browser': user_agent['family'], - 'browser_version': user_agent['major'], - 'os': os['family'], - 'os_version': os['major'], - 'device': device_family, - 'mobile': device_family not in [None, 'Spider', 'Other'], - - } - if user_agent['minor']: - result['browser_version'] += '.' + user_agent['minor'] - if not result['os_version']: - os_list = result['os'].split() - if len(os_list) == 2: - result['os'] = os_list[0] - result['os_version'] = os_list[1] - if os['minor']: - result['os_version'] += '.' + os['minor'] - except Exception: - logger = logging.getLogger('django.request') - logger.error( - 'Cant parse user agent %s', - request.META.get('HTTP_USER_AGENT')) - return result - - def log_record(self, request, exec_time, response): - if isinstance(response, http.StreamingHttpResponse): - content_length = None - else: - content_length = len(response.content) - logging.getLogger('profiler').info(request.path, extra={ - 'method': request.method, - 'status_code': response.status_code, - 'content_length': content_length, - **({ - 'app_name': request.resolver_match.app_name, - 'url_name': request.resolver_match.url_name, - 'view_name': request.resolver_match.view_name, - 'url_args': request.resolver_match.args, - 'url_kwargs': [{ - 'name': name, - 'value': value - } for name, value in request.resolver_match.kwargs.items()] - } if request.resolver_match else {}), - 'user': { - 'id': request.user.id, - 'title': request.user.username - } if request.user.is_authenticated else None, - 'exec_time': exec_time / 1000000, - 'thread_id': threading.current_thread().ident, - 'ip': request.META['REMOTE_ADDR'], - **self.get_user_data(request), - **request.profiling_data, - }) - def __call__(self, request): start_time = time.perf_counter_ns() request.profiling_data = {} response = self.get_response(request) exec_time = time.perf_counter_ns() - start_time - self.log_record(request, exec_time, response) + log_record(request, exec_time, response) + return response + + +class AsyncProfilerMiddleware: + _is_coroutine = asyncio.coroutines._is_coroutine + + def __init__(self, get_response): + self.get_response = get_response + + async def __call__(self, request): + start_time = time.perf_counter_ns() + request.profiling_data = {} + response = await self.get_response(request) + exec_time = time.perf_counter_ns() - start_time + log_record(request, exec_time, response) return response + + +profiler_middleware.async_capable = True diff --git a/tulius/forum/static/forum/snippets/latest_post.html b/tulius/forum/static/forum/snippets/latest_post.html deleted file mode 100644 index 3e840895..00000000 --- a/tulius/forum/static/forum/snippets/latest_post.html +++ /dev/null @@ -1,7 +0,0 @@ -
- - - -
- {{ forum_datetime(comment.create_time) }} -
diff --git a/tulius/forum/static/forum/snippets/latest_post.js b/tulius/forum/static/forum/snippets/latest_post.js deleted file mode 100644 index 932cf520..00000000 --- a/tulius/forum/static/forum/snippets/latest_post.js +++ /dev/null @@ -1,10 +0,0 @@ -export default LazyComponent('forum_latest_post', { - template: '/static/forum/snippets/latest_post.html', - props: ['comment'], - computed: { - urls() {return this.$parent.urls}, - }, - methods: { - forum_datetime: (v) => forum_datetime(new Date(v)), - }, -}) diff --git a/tulius/static/app/app.js b/tulius/static/app/app.js index 5e1f99ba..da13d5dc 100644 --- a/tulius/static/app/app.js +++ b/tulius/static/app/app.js @@ -1,9 +1,29 @@ +import Vue from 'vue' import routes from './routes.js' -import breadcrumbs from '/static/common/components/breadcrumbs.js' -import main_menu from '/static/common/components/main_menu.js' -import CKEditor from '/static/ckeditor4/ckeditor4-vue/index.js'; +import breadcrumbs from '../common/components/breadcrumbs.js' +import main_menu from '../common/components/main_menu.js' +import CKEditor from '../ckeditor4/ckeditor4-vue/index.js'; +import axios from '../common/js/axios.min.js'; +import VueLoading from '../common/js/vue-loading-overlay.js'; +import Tinybox from '../common/js/vue-tinybox.js'; +import VueMultiselect from '../common/components/vue-multiselect.min.js'; +import VueRouter from '../common/js/vue-router.js'; +import VueNativeSock from '../common/js/vue-native-websocket.js'; +import BootstrapVue from '../common/bootstrap-vue/bootstrap-vue.min.js' +import IconsPlugin from '../common/bootstrap-vue/bootstrap-vue-icons.min.js' +import popper from '../common/bootstrap-vue/popper.min.js' +axios.defaults.xsrfCookieName = 'csrftoken'; +axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"; + +Vue.use(VueRouter) +Vue.use(BootstrapVue) +Vue.use(IconsPlugin) Vue.use( CKEditor ); +Vue.use(VueLoading); +Vue.component('loading', VueLoading) +Vue.component('Tinybox', Tinybox); +Vue.component('multiselect', VueMultiselect.default) const NotFound = { template: '

Страница не найдена

' } @@ -12,61 +32,74 @@ const router = new VueRouter({ routes: routes, }) -axios.get('/api/app_settings/').then(response => { - Vue.use(VueNativeSock.default, response.data.websockets_url, { - reconnection: true, - reconnectionDelay: 3000, - format: 'json' - }); - var app = new Vue({ - el: '#vue_app', - router: router, - data: { - debug: response.data.debug, - breadcrumb_items: [], - loading: false, - loading_counter: 0, - show_footer: false, - footer_content: '', - messages: [], - user: response.data.user, +function production_url() { + var schema = window.location.protocol == 'https:' ? 'wss://' : 'ws://'; + return schema + window.location.host + '/api/ws/'; +} + +var websockets_url = production_url(); + +Vue.use(VueNativeSock, websockets_url, { + reconnection: true, + reconnectionDelay: 3000, + format: 'json' +}); + +var app = new Vue({ + el: '#vue_app', + router: router, + data: { + debug: false, + breadcrumb_items: [], + loading: true, + loading_counter: 0, + show_footer: false, + footer_content: '', + messages: [], + user: {}, + }, + methods: { + loading_start() { + this.loading_counter = this.loading_counter + 1; + const new_loading = (this.loading_counter > 0); + if (this.loading != new_loading) { + this.loading = new_loading; + } }, - methods: { - loading_start() { - this.loading_counter = this.loading_counter + 1; - const new_loading = (this.loading_counter > 0); - if (this.loading != new_loading) { - this.loading = new_loading; - } - }, - loading_end(items) { - if (items) { - if (items.length > 0) - document.title = items[items.length - 1].title; - this.breadcrumb_items = items; - } - this.loading_counter = this.loading_counter - 1; - if (this.loading_counter < 0) - this.loading_counter = 0; - const new_loading = (this.loading_counter > 0); - if (this.loading != new_loading) { - this.loading = new_loading; - } - }, - update_footer(show, content) { - this.show_footer = show; - this.footer_content = content; - }, - add_message(message, tag) { - if (tag == 'error') tag = 'danger'; - this.messages.push({'tag': tag, 'text': message}) + loading_end(items) { + if (items) { + if (items.length > 0) + document.title = items[items.length - 1].title; + this.breadcrumb_items = items; } + this.loading_counter = this.loading_counter - 1; + if (this.loading_counter < 0) + this.loading_counter = 0; + const new_loading = (this.loading_counter > 0); + if (this.loading != new_loading) { + this.loading = new_loading; + } + }, + update_footer(show, content) { + this.show_footer = show; + this.footer_content = content; }, - }); + add_message(message, tag) { + if (tag == 'error') tag = 'danger'; + this.messages.push({'tag': tag, 'text': message}) + } + }, + mounted() { + axios.get('/api/app_settings/').then(response => { + this.debug = response.data.debug; + this.user = response.data.user; + this.loading = false; + }) + }, +}); - Vue.app_error_handler = (message, tag) => app.add_message(message, tag); -}) +Vue.app_error_handler = (message, tag) => app.add_message(message, tag); // Add a request interceptor axios.interceptors.request.use( @@ -84,4 +117,6 @@ axios.interceptors.response.use( Vue.app_error_handler(error, "error") return Promise.reject(error); } -); \ No newline at end of file +); + +export default app; \ No newline at end of file diff --git a/tulius/static/app/index.html b/tulius/static/app/index.html new file mode 100644 index 00000000..da2b63cb --- /dev/null +++ b/tulius/static/app/index.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ + + +
+ + +
+
+ +
+ + + diff --git a/tulius/core/ckeditor/static/ckeditor4/CHANGES.md b/tulius/static/ckeditor4/CHANGES.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/CHANGES.md rename to tulius/static/ckeditor4/CHANGES.md diff --git a/tulius/core/ckeditor/static/ckeditor4/LICENSE.md b/tulius/static/ckeditor4/LICENSE.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/LICENSE.md rename to tulius/static/ckeditor4/LICENSE.md diff --git a/tulius/core/ckeditor/static/ckeditor4/README.md b/tulius/static/ckeditor4/README.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/README.md rename to tulius/static/ckeditor4/README.md diff --git a/tulius/core/ckeditor/static/ckeditor4/build-config.js b/tulius/static/ckeditor4/build-config.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/build-config.js rename to tulius/static/ckeditor4/build-config.js diff --git a/tulius/core/ckeditor/static/ckeditor4/ckeditor.js b/tulius/static/ckeditor4/ckeditor.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/ckeditor.js rename to tulius/static/ckeditor4/ckeditor.js diff --git a/tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/LICENSE.md b/tulius/static/ckeditor4/ckeditor4-vue/LICENSE.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/LICENSE.md rename to tulius/static/ckeditor4/ckeditor4-vue/LICENSE.md diff --git a/tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/ckeditor.js b/tulius/static/ckeditor4/ckeditor4-vue/ckeditor.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/ckeditor.js rename to tulius/static/ckeditor4/ckeditor4-vue/ckeditor.js diff --git a/tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/index.js b/tulius/static/ckeditor4/ckeditor4-vue/index.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/index.js rename to tulius/static/ckeditor4/ckeditor4-vue/index.js diff --git a/tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/utils/geteditornamespace.js b/tulius/static/ckeditor4/ckeditor4-vue/utils/geteditornamespace.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/ckeditor4-vue/utils/geteditornamespace.js rename to tulius/static/ckeditor4/ckeditor4-vue/utils/geteditornamespace.js diff --git a/tulius/core/ckeditor/static/ckeditor4/components/tulius_ckeditor.html b/tulius/static/ckeditor4/components/tulius_ckeditor.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/components/tulius_ckeditor.html rename to tulius/static/ckeditor4/components/tulius_ckeditor.html diff --git a/tulius/core/ckeditor/static/ckeditor4/components/tulius_ckeditor.js b/tulius/static/ckeditor4/components/tulius_ckeditor.js similarity index 96% rename from tulius/core/ckeditor/static/ckeditor4/components/tulius_ckeditor.js rename to tulius/static/ckeditor4/components/tulius_ckeditor.js index 4158f9fc..966ad2e1 100644 --- a/tulius/core/ckeditor/static/ckeditor4/components/tulius_ckeditor.js +++ b/tulius/static/ckeditor4/components/tulius_ckeditor.js @@ -1,3 +1,5 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; var cached_smiley_response = {data: null}; diff --git a/tulius/core/ckeditor/static/ckeditor4/config.js b/tulius/static/ckeditor4/config.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/config.js rename to tulius/static/ckeditor4/config.js diff --git a/tulius/core/ckeditor/static/ckeditor4/contents.css b/tulius/static/ckeditor4/contents.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/contents.css rename to tulius/static/ckeditor4/contents.css diff --git a/tulius/core/ckeditor/static/ckeditor4/lang/en.js b/tulius/static/ckeditor4/lang/en.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/lang/en.js rename to tulius/static/ckeditor4/lang/en.js diff --git a/tulius/core/ckeditor/static/ckeditor4/lang/ru.js b/tulius/static/ckeditor4/lang/ru.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/lang/ru.js rename to tulius/static/ckeditor4/lang/ru.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/a11yhelp.js b/tulius/static/ckeditor4/plugins/a11yhelp/dialogs/a11yhelp.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/a11yhelp.js rename to tulius/static/ckeditor4/plugins/a11yhelp/dialogs/a11yhelp.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/lang/_translationstatus.txt b/tulius/static/ckeditor4/plugins/a11yhelp/dialogs/lang/_translationstatus.txt similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/lang/_translationstatus.txt rename to tulius/static/ckeditor4/plugins/a11yhelp/dialogs/lang/_translationstatus.txt diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/lang/en.js b/tulius/static/ckeditor4/plugins/a11yhelp/dialogs/lang/en.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/lang/en.js rename to tulius/static/ckeditor4/plugins/a11yhelp/dialogs/lang/en.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/lang/ru.js b/tulius/static/ckeditor4/plugins/a11yhelp/dialogs/lang/ru.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/a11yhelp/dialogs/lang/ru.js rename to tulius/static/ckeditor4/plugins/a11yhelp/dialogs/lang/ru.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/about/dialogs/about.js b/tulius/static/ckeditor4/plugins/about/dialogs/about.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/about/dialogs/about.js rename to tulius/static/ckeditor4/plugins/about/dialogs/about.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/about/dialogs/hidpi/logo_ckeditor.png b/tulius/static/ckeditor4/plugins/about/dialogs/hidpi/logo_ckeditor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/about/dialogs/hidpi/logo_ckeditor.png rename to tulius/static/ckeditor4/plugins/about/dialogs/hidpi/logo_ckeditor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/about/dialogs/logo_ckeditor.png b/tulius/static/ckeditor4/plugins/about/dialogs/logo_ckeditor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/about/dialogs/logo_ckeditor.png rename to tulius/static/ckeditor4/plugins/about/dialogs/logo_ckeditor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/autogrow/plugin.js b/tulius/static/ckeditor4/plugins/autogrow/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/autogrow/plugin.js rename to tulius/static/ckeditor4/plugins/autogrow/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/clipboard/dialogs/paste.js b/tulius/static/ckeditor4/plugins/clipboard/dialogs/paste.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/clipboard/dialogs/paste.js rename to tulius/static/ckeditor4/plugins/clipboard/dialogs/paste.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/bgcolor.png b/tulius/static/ckeditor4/plugins/colorbutton/icons/bgcolor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/bgcolor.png rename to tulius/static/ckeditor4/plugins/colorbutton/icons/bgcolor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/hidpi/bgcolor.png b/tulius/static/ckeditor4/plugins/colorbutton/icons/hidpi/bgcolor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/hidpi/bgcolor.png rename to tulius/static/ckeditor4/plugins/colorbutton/icons/hidpi/bgcolor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/hidpi/textcolor.png b/tulius/static/ckeditor4/plugins/colorbutton/icons/hidpi/textcolor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/hidpi/textcolor.png rename to tulius/static/ckeditor4/plugins/colorbutton/icons/hidpi/textcolor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/textcolor.png b/tulius/static/ckeditor4/plugins/colorbutton/icons/textcolor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/icons/textcolor.png rename to tulius/static/ckeditor4/plugins/colorbutton/icons/textcolor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/lang/en.js b/tulius/static/ckeditor4/plugins/colorbutton/lang/en.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/lang/en.js rename to tulius/static/ckeditor4/plugins/colorbutton/lang/en.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/lang/ru.js b/tulius/static/ckeditor4/plugins/colorbutton/lang/ru.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/lang/ru.js rename to tulius/static/ckeditor4/plugins/colorbutton/lang/ru.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/plugin.js b/tulius/static/ckeditor4/plugins/colorbutton/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/colorbutton/plugin.js rename to tulius/static/ckeditor4/plugins/colorbutton/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/dialog/dialogDefinition.js b/tulius/static/ckeditor4/plugins/dialog/dialogDefinition.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/dialog/dialogDefinition.js rename to tulius/static/ckeditor4/plugins/dialog/dialogDefinition.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/dialog/styles/dialog.css b/tulius/static/ckeditor4/plugins/dialog/styles/dialog.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/dialog/styles/dialog.css rename to tulius/static/ckeditor4/plugins/dialog/styles/dialog.css diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/divarea/plugin.js b/tulius/static/ckeditor4/plugins/divarea/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/divarea/plugin.js rename to tulius/static/ckeditor4/plugins/divarea/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/divarea/samples/divarea.html b/tulius/static/ckeditor4/plugins/divarea/samples/divarea.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/divarea/samples/divarea.html rename to tulius/static/ckeditor4/plugins/divarea/samples/divarea.html diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/filebrowser/plugin.js b/tulius/static/ckeditor4/plugins/filebrowser/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/filebrowser/plugin.js rename to tulius/static/ckeditor4/plugins/filebrowser/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/font/lang/en.js b/tulius/static/ckeditor4/plugins/font/lang/en.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/font/lang/en.js rename to tulius/static/ckeditor4/plugins/font/lang/en.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/font/lang/ru.js b/tulius/static/ckeditor4/plugins/font/lang/ru.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/font/lang/ru.js rename to tulius/static/ckeditor4/plugins/font/lang/ru.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/font/plugin.js b/tulius/static/ckeditor4/plugins/font/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/font/plugin.js rename to tulius/static/ckeditor4/plugins/font/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/icons.png b/tulius/static/ckeditor4/plugins/icons.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/icons.png rename to tulius/static/ckeditor4/plugins/icons.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/icons_hidpi.png b/tulius/static/ckeditor4/plugins/icons_hidpi.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/icons_hidpi.png rename to tulius/static/ckeditor4/plugins/icons_hidpi.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/image/dialogs/image.js b/tulius/static/ckeditor4/plugins/image/dialogs/image.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/image/dialogs/image.js rename to tulius/static/ckeditor4/plugins/image/dialogs/image.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/image/images/noimage.png b/tulius/static/ckeditor4/plugins/image/images/noimage.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/image/images/noimage.png rename to tulius/static/ckeditor4/plugins/image/images/noimage.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/link/dialogs/anchor.js b/tulius/static/ckeditor4/plugins/link/dialogs/anchor.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/link/dialogs/anchor.js rename to tulius/static/ckeditor4/plugins/link/dialogs/anchor.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/link/dialogs/link.js b/tulius/static/ckeditor4/plugins/link/dialogs/link.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/link/dialogs/link.js rename to tulius/static/ckeditor4/plugins/link/dialogs/link.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/link/images/anchor.png b/tulius/static/ckeditor4/plugins/link/images/anchor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/link/images/anchor.png rename to tulius/static/ckeditor4/plugins/link/images/anchor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/link/images/hidpi/anchor.png b/tulius/static/ckeditor4/plugins/link/images/hidpi/anchor.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/link/images/hidpi/anchor.png rename to tulius/static/ckeditor4/plugins/link/images/hidpi/anchor.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/hidpi/icon-rtl.png b/tulius/static/ckeditor4/plugins/magicline/images/hidpi/icon-rtl.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/hidpi/icon-rtl.png rename to tulius/static/ckeditor4/plugins/magicline/images/hidpi/icon-rtl.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/hidpi/icon.png b/tulius/static/ckeditor4/plugins/magicline/images/hidpi/icon.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/hidpi/icon.png rename to tulius/static/ckeditor4/plugins/magicline/images/hidpi/icon.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/icon-rtl.png b/tulius/static/ckeditor4/plugins/magicline/images/icon-rtl.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/icon-rtl.png rename to tulius/static/ckeditor4/plugins/magicline/images/icon-rtl.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/icon.png b/tulius/static/ckeditor4/plugins/magicline/images/icon.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/magicline/images/icon.png rename to tulius/static/ckeditor4/plugins/magicline/images/icon.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/panelbutton/plugin.js b/tulius/static/ckeditor4/plugins/panelbutton/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/panelbutton/plugin.js rename to tulius/static/ckeditor4/plugins/panelbutton/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/pastefromgdocs/filter/default.js b/tulius/static/ckeditor4/plugins/pastefromgdocs/filter/default.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/pastefromgdocs/filter/default.js rename to tulius/static/ckeditor4/plugins/pastefromgdocs/filter/default.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/pastefromword/filter/default.js b/tulius/static/ckeditor4/plugins/pastefromword/filter/default.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/pastefromword/filter/default.js rename to tulius/static/ckeditor4/plugins/pastefromword/filter/default.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/pastetools/filter/common.js b/tulius/static/ckeditor4/plugins/pastetools/filter/common.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/pastetools/filter/common.js rename to tulius/static/ckeditor4/plugins/pastetools/filter/common.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/pastetools/filter/image.js b/tulius/static/ckeditor4/plugins/pastetools/filter/image.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/pastetools/filter/image.js rename to tulius/static/ckeditor4/plugins/pastetools/filter/image.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/replyformmax/icons/hidpi/replyformmax.png b/tulius/static/ckeditor4/plugins/replyformmax/icons/hidpi/replyformmax.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/replyformmax/icons/hidpi/replyformmax.png rename to tulius/static/ckeditor4/plugins/replyformmax/icons/hidpi/replyformmax.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/replyformmax/icons/replyformmax.png b/tulius/static/ckeditor4/plugins/replyformmax/icons/replyformmax.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/replyformmax/icons/replyformmax.png rename to tulius/static/ckeditor4/plugins/replyformmax/icons/replyformmax.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/replyformmax/plugin.js b/tulius/static/ckeditor4/plugins/replyformmax/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/replyformmax/plugin.js rename to tulius/static/ckeditor4/plugins/replyformmax/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/CHANGELOG.md b/tulius/static/ckeditor4/plugins/scayt/CHANGELOG.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/CHANGELOG.md rename to tulius/static/ckeditor4/plugins/scayt/CHANGELOG.md diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/LICENSE.md b/tulius/static/ckeditor4/plugins/scayt/LICENSE.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/LICENSE.md rename to tulius/static/ckeditor4/plugins/scayt/LICENSE.md diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/README.md b/tulius/static/ckeditor4/plugins/scayt/README.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/README.md rename to tulius/static/ckeditor4/plugins/scayt/README.md diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/dialogs/dialog.css b/tulius/static/ckeditor4/plugins/scayt/dialogs/dialog.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/dialogs/dialog.css rename to tulius/static/ckeditor4/plugins/scayt/dialogs/dialog.css diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/dialogs/options.js b/tulius/static/ckeditor4/plugins/scayt/dialogs/options.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/dialogs/options.js rename to tulius/static/ckeditor4/plugins/scayt/dialogs/options.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/dialogs/toolbar.css b/tulius/static/ckeditor4/plugins/scayt/dialogs/toolbar.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/dialogs/toolbar.css rename to tulius/static/ckeditor4/plugins/scayt/dialogs/toolbar.css diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/scayt/skins/moono-lisa/scayt.css b/tulius/static/ckeditor4/plugins/scayt/skins/moono-lisa/scayt.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/scayt/skins/moono-lisa/scayt.css rename to tulius/static/ckeditor4/plugins/scayt/skins/moono-lisa/scayt.css diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/smiley/dialogs/smiley.js b/tulius/static/ckeditor4/plugins/smiley/dialogs/smiley.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/smiley/dialogs/smiley.js rename to tulius/static/ckeditor4/plugins/smiley/dialogs/smiley.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/smiley/icons/hidpi/smiley.png b/tulius/static/ckeditor4/plugins/smiley/icons/hidpi/smiley.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/smiley/icons/hidpi/smiley.png rename to tulius/static/ckeditor4/plugins/smiley/icons/hidpi/smiley.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/smiley/icons/smiley.png b/tulius/static/ckeditor4/plugins/smiley/icons/smiley.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/smiley/icons/smiley.png rename to tulius/static/ckeditor4/plugins/smiley/icons/smiley.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/smiley/lang/en.js b/tulius/static/ckeditor4/plugins/smiley/lang/en.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/smiley/lang/en.js rename to tulius/static/ckeditor4/plugins/smiley/lang/en.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/smiley/lang/ru.js b/tulius/static/ckeditor4/plugins/smiley/lang/ru.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/smiley/lang/ru.js rename to tulius/static/ckeditor4/plugins/smiley/lang/ru.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/smiley/plugin.js b/tulius/static/ckeditor4/plugins/smiley/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/smiley/plugin.js rename to tulius/static/ckeditor4/plugins/smiley/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/lang/_translationstatus.txt b/tulius/static/ckeditor4/plugins/specialchar/dialogs/lang/_translationstatus.txt similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/lang/_translationstatus.txt rename to tulius/static/ckeditor4/plugins/specialchar/dialogs/lang/_translationstatus.txt diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/lang/en.js b/tulius/static/ckeditor4/plugins/specialchar/dialogs/lang/en.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/lang/en.js rename to tulius/static/ckeditor4/plugins/specialchar/dialogs/lang/en.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/lang/ru.js b/tulius/static/ckeditor4/plugins/specialchar/dialogs/lang/ru.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/lang/ru.js rename to tulius/static/ckeditor4/plugins/specialchar/dialogs/lang/ru.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/specialchar.js b/tulius/static/ckeditor4/plugins/specialchar/dialogs/specialchar.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/specialchar/dialogs/specialchar.js rename to tulius/static/ckeditor4/plugins/specialchar/dialogs/specialchar.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/table/dialogs/table.js b/tulius/static/ckeditor4/plugins/table/dialogs/table.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/table/dialogs/table.js rename to tulius/static/ckeditor4/plugins/table/dialogs/table.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/tableselection/styles/tableselection.css b/tulius/static/ckeditor4/plugins/tableselection/styles/tableselection.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/tableselection/styles/tableselection.css rename to tulius/static/ckeditor4/plugins/tableselection/styles/tableselection.css diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/tabletools/dialogs/tableCell.js b/tulius/static/ckeditor4/plugins/tabletools/dialogs/tableCell.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/tabletools/dialogs/tableCell.js rename to tulius/static/ckeditor4/plugins/tabletools/dialogs/tableCell.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/uploadimage/plugin.js b/tulius/static/ckeditor4/plugins/uploadimage/plugin.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/uploadimage/plugin.js rename to tulius/static/ckeditor4/plugins/uploadimage/plugin.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/widget/images/handle.png b/tulius/static/ckeditor4/plugins/widget/images/handle.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/widget/images/handle.png rename to tulius/static/ckeditor4/plugins/widget/images/handle.png diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/LICENSE.md b/tulius/static/ckeditor4/plugins/wsc/LICENSE.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/LICENSE.md rename to tulius/static/ckeditor4/plugins/wsc/LICENSE.md diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/README.md b/tulius/static/ckeditor4/plugins/wsc/README.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/README.md rename to tulius/static/ckeditor4/plugins/wsc/README.md diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/ciframe.html b/tulius/static/ckeditor4/plugins/wsc/dialogs/ciframe.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/ciframe.html rename to tulius/static/ckeditor4/plugins/wsc/dialogs/ciframe.html diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/tmpFrameset.html b/tulius/static/ckeditor4/plugins/wsc/dialogs/tmpFrameset.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/tmpFrameset.html rename to tulius/static/ckeditor4/plugins/wsc/dialogs/tmpFrameset.html diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/wsc.css b/tulius/static/ckeditor4/plugins/wsc/dialogs/wsc.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/wsc.css rename to tulius/static/ckeditor4/plugins/wsc/dialogs/wsc.css diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/wsc.js b/tulius/static/ckeditor4/plugins/wsc/dialogs/wsc.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/wsc.js rename to tulius/static/ckeditor4/plugins/wsc/dialogs/wsc.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/wsc_ie.js b/tulius/static/ckeditor4/plugins/wsc/dialogs/wsc_ie.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/dialogs/wsc_ie.js rename to tulius/static/ckeditor4/plugins/wsc/dialogs/wsc_ie.js diff --git a/tulius/core/ckeditor/static/ckeditor4/plugins/wsc/skins/moono-lisa/wsc.css b/tulius/static/ckeditor4/plugins/wsc/skins/moono-lisa/wsc.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/plugins/wsc/skins/moono-lisa/wsc.css rename to tulius/static/ckeditor4/plugins/wsc/skins/moono-lisa/wsc.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/css/samples.css b/tulius/static/ckeditor4/samples/css/samples.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/css/samples.css rename to tulius/static/ckeditor4/samples/css/samples.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/img/github-top.png b/tulius/static/ckeditor4/samples/img/github-top.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/img/github-top.png rename to tulius/static/ckeditor4/samples/img/github-top.png diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/img/header-bg.png b/tulius/static/ckeditor4/samples/img/header-bg.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/img/header-bg.png rename to tulius/static/ckeditor4/samples/img/header-bg.png diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/img/header-separator.png b/tulius/static/ckeditor4/samples/img/header-separator.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/img/header-separator.png rename to tulius/static/ckeditor4/samples/img/header-separator.png diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/img/logo.png b/tulius/static/ckeditor4/samples/img/logo.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/img/logo.png rename to tulius/static/ckeditor4/samples/img/logo.png diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/img/logo.svg b/tulius/static/ckeditor4/samples/img/logo.svg similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/img/logo.svg rename to tulius/static/ckeditor4/samples/img/logo.svg diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/img/navigation-tip.png b/tulius/static/ckeditor4/samples/img/navigation-tip.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/img/navigation-tip.png rename to tulius/static/ckeditor4/samples/img/navigation-tip.png diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/index.html b/tulius/static/ckeditor4/samples/index.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/index.html rename to tulius/static/ckeditor4/samples/index.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/js/sample.js b/tulius/static/ckeditor4/samples/js/sample.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/js/sample.js rename to tulius/static/ckeditor4/samples/js/sample.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/js/sf.js b/tulius/static/ckeditor4/samples/js/sf.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/js/sf.js rename to tulius/static/ckeditor4/samples/js/sf.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/ajax.html b/tulius/static/ckeditor4/samples/old/ajax.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/ajax.html rename to tulius/static/ckeditor4/samples/old/ajax.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/api.html b/tulius/static/ckeditor4/samples/old/api.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/api.html rename to tulius/static/ckeditor4/samples/old/api.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/appendto.html b/tulius/static/ckeditor4/samples/old/appendto.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/appendto.html rename to tulius/static/ckeditor4/samples/old/appendto.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/assets/inlineall/logo.png b/tulius/static/ckeditor4/samples/old/assets/inlineall/logo.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/assets/inlineall/logo.png rename to tulius/static/ckeditor4/samples/old/assets/inlineall/logo.png diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/assets/outputxhtml/outputxhtml.css b/tulius/static/ckeditor4/samples/old/assets/outputxhtml/outputxhtml.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/assets/outputxhtml/outputxhtml.css rename to tulius/static/ckeditor4/samples/old/assets/outputxhtml/outputxhtml.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/assets/sample.jpg b/tulius/static/ckeditor4/samples/old/assets/sample.jpg similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/assets/sample.jpg rename to tulius/static/ckeditor4/samples/old/assets/sample.jpg diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/assets/uilanguages/languages.js b/tulius/static/ckeditor4/samples/old/assets/uilanguages/languages.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/assets/uilanguages/languages.js rename to tulius/static/ckeditor4/samples/old/assets/uilanguages/languages.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/datafiltering.html b/tulius/static/ckeditor4/samples/old/datafiltering.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/datafiltering.html rename to tulius/static/ckeditor4/samples/old/datafiltering.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/dialog/assets/my_dialog.js b/tulius/static/ckeditor4/samples/old/dialog/assets/my_dialog.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/dialog/assets/my_dialog.js rename to tulius/static/ckeditor4/samples/old/dialog/assets/my_dialog.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/dialog/dialog.html b/tulius/static/ckeditor4/samples/old/dialog/dialog.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/dialog/dialog.html rename to tulius/static/ckeditor4/samples/old/dialog/dialog.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/divreplace.html b/tulius/static/ckeditor4/samples/old/divreplace.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/divreplace.html rename to tulius/static/ckeditor4/samples/old/divreplace.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/enterkey/enterkey.html b/tulius/static/ckeditor4/samples/old/enterkey/enterkey.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/enterkey/enterkey.html rename to tulius/static/ckeditor4/samples/old/enterkey/enterkey.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla b/tulius/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla rename to tulius/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf b/tulius/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf rename to tulius/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/swfobject.js b/tulius/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/swfobject.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/swfobject.js rename to tulius/static/ckeditor4/samples/old/htmlwriter/assets/outputforflash/swfobject.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/outputforflash.html b/tulius/static/ckeditor4/samples/old/htmlwriter/outputforflash.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/outputforflash.html rename to tulius/static/ckeditor4/samples/old/htmlwriter/outputforflash.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/outputhtml.html b/tulius/static/ckeditor4/samples/old/htmlwriter/outputhtml.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/htmlwriter/outputhtml.html rename to tulius/static/ckeditor4/samples/old/htmlwriter/outputhtml.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/index.html b/tulius/static/ckeditor4/samples/old/index.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/index.html rename to tulius/static/ckeditor4/samples/old/index.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/inlineall.html b/tulius/static/ckeditor4/samples/old/inlineall.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/inlineall.html rename to tulius/static/ckeditor4/samples/old/inlineall.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/inlinebycode.html b/tulius/static/ckeditor4/samples/old/inlinebycode.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/inlinebycode.html rename to tulius/static/ckeditor4/samples/old/inlinebycode.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/inlinetextarea.html b/tulius/static/ckeditor4/samples/old/inlinetextarea.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/inlinetextarea.html rename to tulius/static/ckeditor4/samples/old/inlinetextarea.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/jquery.html b/tulius/static/ckeditor4/samples/old/jquery.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/jquery.html rename to tulius/static/ckeditor4/samples/old/jquery.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/magicline/magicline.html b/tulius/static/ckeditor4/samples/old/magicline/magicline.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/magicline/magicline.html rename to tulius/static/ckeditor4/samples/old/magicline/magicline.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/readonly.html b/tulius/static/ckeditor4/samples/old/readonly.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/readonly.html rename to tulius/static/ckeditor4/samples/old/readonly.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/replacebyclass.html b/tulius/static/ckeditor4/samples/old/replacebyclass.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/replacebyclass.html rename to tulius/static/ckeditor4/samples/old/replacebyclass.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/replacebycode.html b/tulius/static/ckeditor4/samples/old/replacebycode.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/replacebycode.html rename to tulius/static/ckeditor4/samples/old/replacebycode.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/sample.css b/tulius/static/ckeditor4/samples/old/sample.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/sample.css rename to tulius/static/ckeditor4/samples/old/sample.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/sample.js b/tulius/static/ckeditor4/samples/old/sample.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/sample.js rename to tulius/static/ckeditor4/samples/old/sample.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/tabindex.html b/tulius/static/ckeditor4/samples/old/tabindex.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/tabindex.html rename to tulius/static/ckeditor4/samples/old/tabindex.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/toolbar/toolbar.html b/tulius/static/ckeditor4/samples/old/toolbar/toolbar.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/toolbar/toolbar.html rename to tulius/static/ckeditor4/samples/old/toolbar/toolbar.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/uicolor.html b/tulius/static/ckeditor4/samples/old/uicolor.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/uicolor.html rename to tulius/static/ckeditor4/samples/old/uicolor.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/uilanguages.html b/tulius/static/ckeditor4/samples/old/uilanguages.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/uilanguages.html rename to tulius/static/ckeditor4/samples/old/uilanguages.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/wysiwygarea/fullpage.html b/tulius/static/ckeditor4/samples/old/wysiwygarea/fullpage.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/wysiwygarea/fullpage.html rename to tulius/static/ckeditor4/samples/old/wysiwygarea/fullpage.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/old/xhtmlstyle.html b/tulius/static/ckeditor4/samples/old/xhtmlstyle.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/old/xhtmlstyle.html rename to tulius/static/ckeditor4/samples/old/xhtmlstyle.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/css/fontello.css b/tulius/static/ckeditor4/samples/toolbarconfigurator/css/fontello.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/css/fontello.css rename to tulius/static/ckeditor4/samples/toolbarconfigurator/css/fontello.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/LICENSE.txt b/tulius/static/ckeditor4/samples/toolbarconfigurator/font/LICENSE.txt similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/LICENSE.txt rename to tulius/static/ckeditor4/samples/toolbarconfigurator/font/LICENSE.txt diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/config.json b/tulius/static/ckeditor4/samples/toolbarconfigurator/font/config.json similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/config.json rename to tulius/static/ckeditor4/samples/toolbarconfigurator/font/config.json diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.eot b/tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.eot similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.eot rename to tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.eot diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.svg b/tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.svg similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.svg rename to tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.svg diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.ttf b/tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.ttf similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.ttf rename to tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.ttf diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.woff b/tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.woff similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/font/fontello.woff rename to tulius/static/ckeditor4/samples/toolbarconfigurator/font/fontello.woff diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/index.html b/tulius/static/ckeditor4/samples/toolbarconfigurator/index.html similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/index.html rename to tulius/static/ckeditor4/samples/toolbarconfigurator/index.html diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/fulltoolbareditor.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/js/fulltoolbareditor.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/fulltoolbareditor.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/js/fulltoolbareditor.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/toolbarmodifier.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/js/toolbarmodifier.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/toolbarmodifier.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/js/toolbarmodifier.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/toolbartextmodifier.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/js/toolbartextmodifier.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/js/toolbartextmodifier.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/js/toolbartextmodifier.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/LICENSE b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/LICENSE similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/LICENSE rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/LICENSE diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.css b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.css rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/codemirror.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/javascript.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/javascript.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/javascript.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/javascript.js diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/neo.css b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/neo.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/neo.css rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/neo.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.css b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.css rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.css diff --git a/tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.js b/tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.js rename to tulius/static/ckeditor4/samples/toolbarconfigurator/lib/codemirror/show-hint.js diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog.css b/tulius/static/ckeditor4/skins/moono-lisa/dialog.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog.css rename to tulius/static/ckeditor4/skins/moono-lisa/dialog.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog_ie.css b/tulius/static/ckeditor4/skins/moono-lisa/dialog_ie.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog_ie.css rename to tulius/static/ckeditor4/skins/moono-lisa/dialog_ie.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog_ie8.css b/tulius/static/ckeditor4/skins/moono-lisa/dialog_ie8.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog_ie8.css rename to tulius/static/ckeditor4/skins/moono-lisa/dialog_ie8.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog_iequirks.css b/tulius/static/ckeditor4/skins/moono-lisa/dialog_iequirks.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/dialog_iequirks.css rename to tulius/static/ckeditor4/skins/moono-lisa/dialog_iequirks.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor.css b/tulius/static/ckeditor4/skins/moono-lisa/editor.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor.css rename to tulius/static/ckeditor4/skins/moono-lisa/editor.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_gecko.css b/tulius/static/ckeditor4/skins/moono-lisa/editor_gecko.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_gecko.css rename to tulius/static/ckeditor4/skins/moono-lisa/editor_gecko.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_ie.css b/tulius/static/ckeditor4/skins/moono-lisa/editor_ie.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_ie.css rename to tulius/static/ckeditor4/skins/moono-lisa/editor_ie.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_ie8.css b/tulius/static/ckeditor4/skins/moono-lisa/editor_ie8.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_ie8.css rename to tulius/static/ckeditor4/skins/moono-lisa/editor_ie8.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_iequirks.css b/tulius/static/ckeditor4/skins/moono-lisa/editor_iequirks.css similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/editor_iequirks.css rename to tulius/static/ckeditor4/skins/moono-lisa/editor_iequirks.css diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/icons.png b/tulius/static/ckeditor4/skins/moono-lisa/icons.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/icons.png rename to tulius/static/ckeditor4/skins/moono-lisa/icons.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/icons_hidpi.png b/tulius/static/ckeditor4/skins/moono-lisa/icons_hidpi.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/icons_hidpi.png rename to tulius/static/ckeditor4/skins/moono-lisa/icons_hidpi.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/arrow.png b/tulius/static/ckeditor4/skins/moono-lisa/images/arrow.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/arrow.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/arrow.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/close.png b/tulius/static/ckeditor4/skins/moono-lisa/images/close.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/close.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/close.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/close.png b/tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/close.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/close.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/close.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/lock-open.png b/tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/lock-open.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/lock-open.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/lock-open.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/lock.png b/tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/lock.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/lock.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/lock.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/refresh.png b/tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/refresh.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/hidpi/refresh.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/hidpi/refresh.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/lock-open.png b/tulius/static/ckeditor4/skins/moono-lisa/images/lock-open.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/lock-open.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/lock-open.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/lock.png b/tulius/static/ckeditor4/skins/moono-lisa/images/lock.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/lock.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/lock.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/refresh.png b/tulius/static/ckeditor4/skins/moono-lisa/images/refresh.png similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/refresh.png rename to tulius/static/ckeditor4/skins/moono-lisa/images/refresh.png diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/spinner.gif b/tulius/static/ckeditor4/skins/moono-lisa/images/spinner.gif similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/images/spinner.gif rename to tulius/static/ckeditor4/skins/moono-lisa/images/spinner.gif diff --git a/tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/readme.md b/tulius/static/ckeditor4/skins/moono-lisa/readme.md similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/skins/moono-lisa/readme.md rename to tulius/static/ckeditor4/skins/moono-lisa/readme.md diff --git a/tulius/core/ckeditor/static/ckeditor4/styles.js b/tulius/static/ckeditor4/styles.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/styles.js rename to tulius/static/ckeditor4/styles.js diff --git a/tulius/core/ckeditor/static/ckeditor4/vendor/promise.js b/tulius/static/ckeditor4/vendor/promise.js similarity index 100% rename from tulius/core/ckeditor/static/ckeditor4/vendor/promise.js rename to tulius/static/ckeditor4/vendor/promise.js diff --git a/tulius/static/common/components/breadcrumbs.js b/tulius/static/common/components/breadcrumbs.js index aa6845a0..67279b0f 100644 --- a/tulius/static/common/components/breadcrumbs.js +++ b/tulius/static/common/components/breadcrumbs.js @@ -1,3 +1,6 @@ +import {LazyComponent} from '../js/vue-common.js' + + export default LazyComponent('breadcrumbs', { template: '/static/common/components/breadcrumbs.html', props: ['upper', 'items'], diff --git a/tulius/static/common/components/main_menu.js b/tulius/static/common/components/main_menu.js index 5082d900..628f955f 100644 --- a/tulius/static/common/components/main_menu.js +++ b/tulius/static/common/components/main_menu.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../js/vue-common.js' +import axios from '../js/axios.min.js'; + + export default LazyComponent('main_menu', { template: '/static/common/components/main_menu.html', props: ['user'], diff --git a/tulius/static/common/js/vue-common.js b/tulius/static/common/js/vue-common.js index b9330ab3..5386e2a2 100644 --- a/tulius/static/common/js/vue-common.js +++ b/tulius/static/common/js/vue-common.js @@ -1,4 +1,7 @@ -function LazyComponent(name, defs) { +import Vue from 'vue' + + +export function LazyComponent(name, defs) { var template_resolved = false; return Vue.component(name, function(resolve, reject) { if (template_resolved) @@ -13,23 +16,7 @@ function LazyComponent(name, defs) { }) } -function getCookie(name) { - var cookieValue = null; - if (document.cookie && document.cookie !== '') { - var cookies = document.cookie.split(';'); - for (var i = 0; i < cookies.length; i++) { - var cookie = cookies[i].trim(); - // Does this cookie string begin with the name we want? - if (cookie.substring(0, name.length + 1) === (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; -} - -function forum_datetime(d) { +export function forum_datetime(d) { return (( '0' + d.getDate()).slice(-2) + '.' + ('0' + (d.getMonth() + 1)).slice(-2) + '.' + @@ -37,11 +24,3 @@ function forum_datetime(d) { ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2)); } - -axios.defaults.xsrfCookieName = 'csrftoken'; -axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"; - -Vue.use(VueLoading); -Vue.component('loading', VueLoading) -Vue.use(Tinybox); -Vue.component('multiselect', VueMultiselect.default) diff --git a/tulius/core/debug_mail/static/debug_mail/mail.html b/tulius/static/debug_mail/mail.html similarity index 100% rename from tulius/core/debug_mail/static/debug_mail/mail.html rename to tulius/static/debug_mail/mail.html diff --git a/tulius/core/debug_mail/static/debug_mail/mail.js b/tulius/static/debug_mail/mail.js similarity index 91% rename from tulius/core/debug_mail/static/debug_mail/mail.js rename to tulius/static/debug_mail/mail.js index 488dffcc..0c60e141 100644 --- a/tulius/core/debug_mail/static/debug_mail/mail.js +++ b/tulius/static/debug_mail/mail.js @@ -1,4 +1,6 @@ import APILoadMixin from '../app/components/api_load_mixin.js' +import {LazyComponent} from '../common/js/vue-common.js' +import axios from '../common/js/axios.min.js'; export default LazyComponent('debug_mail_box', { diff --git a/tulius/core/debug_mail/static/debug_mail/mailbox.html b/tulius/static/debug_mail/mailbox.html similarity index 100% rename from tulius/core/debug_mail/static/debug_mail/mailbox.html rename to tulius/static/debug_mail/mailbox.html diff --git a/tulius/core/debug_mail/static/debug_mail/mailbox.js b/tulius/static/debug_mail/mailbox.js similarity index 90% rename from tulius/core/debug_mail/static/debug_mail/mailbox.js rename to tulius/static/debug_mail/mailbox.js index 0fcc20f3..b53d8775 100644 --- a/tulius/core/debug_mail/static/debug_mail/mailbox.js +++ b/tulius/static/debug_mail/mailbox.js @@ -1,4 +1,6 @@ import APILoadMixin from '../app/components/api_load_mixin.js' +import {LazyComponent} from '../common/js/vue-common.js' +import axios from '../common/js/axios.min.js'; export default LazyComponent('debug_mail_box', { diff --git a/tulius/core/debug_mail/static/debug_mail/routes.js b/tulius/static/debug_mail/routes.js similarity index 100% rename from tulius/core/debug_mail/static/debug_mail/routes.js rename to tulius/static/debug_mail/routes.js diff --git a/tulius/core/debug_mail/static/debug_mail/users.html b/tulius/static/debug_mail/users.html similarity index 100% rename from tulius/core/debug_mail/static/debug_mail/users.html rename to tulius/static/debug_mail/users.html diff --git a/tulius/core/debug_mail/static/debug_mail/users.js b/tulius/static/debug_mail/users.js similarity index 88% rename from tulius/core/debug_mail/static/debug_mail/users.js rename to tulius/static/debug_mail/users.js index 5343051d..3e999dc7 100644 --- a/tulius/core/debug_mail/static/debug_mail/users.js +++ b/tulius/static/debug_mail/users.js @@ -1,4 +1,6 @@ import APILoadMixin from '../app/components/api_load_mixin.js' +import {LazyComponent} from '../common/js/vue-common.js' +import axios from '../common/js/axios.min.js'; export default LazyComponent('debug_mail_users', { diff --git a/tulius/forum/static/forum/app/app.js b/tulius/static/forum/app/app.js similarity index 97% rename from tulius/forum/static/forum/app/app.js rename to tulius/static/forum/app/app.js index 6a16eb8d..ce57d77e 100644 --- a/tulius/forum/static/forum/app/app.js +++ b/tulius/static/forum/app/app.js @@ -1,3 +1,4 @@ +import Vue from 'vue' import urls from './urls.js' export default Vue.component('forum_app', { diff --git a/tulius/forum/static/forum/app/comment_redirect.js b/tulius/static/forum/app/comment_redirect.js similarity index 87% rename from tulius/forum/static/forum/app/comment_redirect.js rename to tulius/static/forum/app/comment_redirect.js index 643e396c..07bb972f 100644 --- a/tulius/forum/static/forum/app/comment_redirect.js +++ b/tulius/static/forum/app/comment_redirect.js @@ -1,4 +1,7 @@ +import Vue from 'vue' import APILoadMixin from '../../app/components/api_load_mixin.js' +import axios from '../../common/js/axios.min.js'; + export default Vue.component('forum_comment_redirect', { mixins: [APILoadMixin,], diff --git a/tulius/forum/static/forum/app/routes.js b/tulius/static/forum/app/routes.js similarity index 100% rename from tulius/forum/static/forum/app/routes.js rename to tulius/static/forum/app/routes.js diff --git a/tulius/forum/static/forum/app/urls.js b/tulius/static/forum/app/urls.js similarity index 100% rename from tulius/forum/static/forum/app/urls.js rename to tulius/static/forum/app/urls.js diff --git a/tulius/forum/static/forum/components/comments.html b/tulius/static/forum/components/comments.html similarity index 100% rename from tulius/forum/static/forum/components/comments.html rename to tulius/static/forum/components/comments.html diff --git a/tulius/forum/static/forum/components/comments.js b/tulius/static/forum/components/comments.js similarity index 98% rename from tulius/forum/static/forum/components/comments.js rename to tulius/static/forum/components/comments.js index 01410abf..3900feca 100644 --- a/tulius/forum/static/forum/components/comments.js +++ b/tulius/static/forum/components/comments.js @@ -1,5 +1,7 @@ import comment_component from '../snippets/comment.js' import pagination_component from '../components/pagination.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_thread_comments', { diff --git a/tulius/forum/static/forum/components/edit_room.html b/tulius/static/forum/components/edit_room.html similarity index 100% rename from tulius/forum/static/forum/components/edit_room.html rename to tulius/static/forum/components/edit_room.html diff --git a/tulius/forum/static/forum/components/edit_room.js b/tulius/static/forum/components/edit_room.js similarity index 89% rename from tulius/forum/static/forum/components/edit_room.js rename to tulius/static/forum/components/edit_room.js index 6756a3ce..adf9ace4 100644 --- a/tulius/forum/static/forum/components/edit_room.js +++ b/tulius/static/forum/components/edit_room.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_edit_room', { props: { page: {type: Object}, diff --git a/tulius/forum/static/forum/components/favorites.html b/tulius/static/forum/components/favorites.html similarity index 100% rename from tulius/forum/static/forum/components/favorites.html rename to tulius/static/forum/components/favorites.html diff --git a/tulius/forum/static/forum/components/favorites.js b/tulius/static/forum/components/favorites.js similarity index 88% rename from tulius/forum/static/forum/components/favorites.js rename to tulius/static/forum/components/favorites.js index 2b5aa406..442aa498 100644 --- a/tulius/forum/static/forum/components/favorites.js +++ b/tulius/static/forum/components/favorites.js @@ -1,6 +1,8 @@ import comment_component from '../snippets/comment.js' import APILoadMixin from '../../app/components/api_load_mixin.js' import urls from '../app/urls.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_favorites', { diff --git a/tulius/forum/static/forum/components/media/base.js b/tulius/static/forum/components/media/base.js similarity index 100% rename from tulius/forum/static/forum/components/media/base.js rename to tulius/static/forum/components/media/base.js diff --git a/tulius/forum/static/forum/components/media/html.html b/tulius/static/forum/components/media/html.html similarity index 100% rename from tulius/forum/static/forum/components/media/html.html rename to tulius/static/forum/components/media/html.html diff --git a/tulius/forum/static/forum/components/media/html.js b/tulius/static/forum/components/media/html.js similarity index 93% rename from tulius/forum/static/forum/components/media/html.js rename to tulius/static/forum/components/media/html.js index af3803ed..eb3f9c02 100644 --- a/tulius/forum/static/forum/components/media/html.js +++ b/tulius/static/forum/components/media/html.js @@ -1,4 +1,7 @@ import baseMixin from './base.js' +import {LazyComponent} from '../../../common/js/vue-common.js' +import axios from '../../../common/js/axios.min.js'; + export default LazyComponent('forum_html_media', { template: '/static/forum/components/media/html.html', diff --git a/tulius/forum/static/forum/components/media/images.html b/tulius/static/forum/components/media/images.html similarity index 100% rename from tulius/forum/static/forum/components/media/images.html rename to tulius/static/forum/components/media/images.html diff --git a/tulius/forum/static/forum/components/media/images.js b/tulius/static/forum/components/media/images.js similarity index 96% rename from tulius/forum/static/forum/components/media/images.js rename to tulius/static/forum/components/media/images.js index 14c25232..f47b1829 100644 --- a/tulius/forum/static/forum/components/media/images.js +++ b/tulius/static/forum/components/media/images.js @@ -1,4 +1,7 @@ import baseMixin from './base.js' +import {LazyComponent} from '../../../common/js/vue-common.js' +import axios from '../../../common/js/axios.min.js'; + export default LazyComponent('forum_images', { template: '/static/forum/components/media/images.html', diff --git a/tulius/forum/static/forum/components/media/youtube.html b/tulius/static/forum/components/media/youtube.html similarity index 100% rename from tulius/forum/static/forum/components/media/youtube.html rename to tulius/static/forum/components/media/youtube.html diff --git a/tulius/forum/static/forum/components/media/youtube.js b/tulius/static/forum/components/media/youtube.js similarity index 96% rename from tulius/forum/static/forum/components/media/youtube.js rename to tulius/static/forum/components/media/youtube.js index f9e6703f..305fbfb9 100644 --- a/tulius/forum/static/forum/components/media/youtube.js +++ b/tulius/static/forum/components/media/youtube.js @@ -1,4 +1,6 @@ import baseMixin from './base.js' +import {LazyComponent} from '../../../common/js/vue-common.js' + export default LazyComponent('forum_youtube_media', { template: '/static/forum/components/media/youtube.html', diff --git a/tulius/forum/static/forum/components/move_thread.html b/tulius/static/forum/components/move_thread.html similarity index 100% rename from tulius/forum/static/forum/components/move_thread.html rename to tulius/static/forum/components/move_thread.html diff --git a/tulius/forum/static/forum/components/move_thread.js b/tulius/static/forum/components/move_thread.js similarity index 93% rename from tulius/forum/static/forum/components/move_thread.js rename to tulius/static/forum/components/move_thread.js index 3eb45da1..2bafeeb2 100644 --- a/tulius/forum/static/forum/components/move_thread.js +++ b/tulius/static/forum/components/move_thread.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('move_thread', { template: '/static/forum/components/move_thread.html', props: { diff --git a/tulius/forum/static/forum/components/pagination.html b/tulius/static/forum/components/pagination.html similarity index 100% rename from tulius/forum/static/forum/components/pagination.html rename to tulius/static/forum/components/pagination.html diff --git a/tulius/forum/static/forum/components/pagination.js b/tulius/static/forum/components/pagination.js similarity index 92% rename from tulius/forum/static/forum/components/pagination.js rename to tulius/static/forum/components/pagination.js index 6a7c02b6..70576269 100644 --- a/tulius/forum/static/forum/components/pagination.js +++ b/tulius/static/forum/components/pagination.js @@ -1,3 +1,5 @@ +import {LazyComponent} from '../../common/js/vue-common.js' + export default LazyComponent('pagination', { template: '/static/forum/components/pagination.html', props: ['pagination', 'page_num'], diff --git a/tulius/forum/static/forum/components/reply_form.html b/tulius/static/forum/components/reply_form.html similarity index 100% rename from tulius/forum/static/forum/components/reply_form.html rename to tulius/static/forum/components/reply_form.html diff --git a/tulius/forum/static/forum/components/reply_form.js b/tulius/static/forum/components/reply_form.js similarity index 97% rename from tulius/forum/static/forum/components/reply_form.js rename to tulius/static/forum/components/reply_form.js index 74d98103..520f0b4f 100644 --- a/tulius/forum/static/forum/components/reply_form.js +++ b/tulius/static/forum/components/reply_form.js @@ -3,6 +3,8 @@ import voting from './voting.js' import images from './media/images.js' import html_editor from './media/html.js' import youtube from './media/youtube.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_reply_form', { diff --git a/tulius/forum/static/forum/components/thread_access.html b/tulius/static/forum/components/thread_access.html similarity index 100% rename from tulius/forum/static/forum/components/thread_access.html rename to tulius/static/forum/components/thread_access.html diff --git a/tulius/forum/static/forum/components/thread_access.js b/tulius/static/forum/components/thread_access.js similarity index 98% rename from tulius/forum/static/forum/components/thread_access.js rename to tulius/static/forum/components/thread_access.js index facef70c..951a7ef0 100644 --- a/tulius/forum/static/forum/components/thread_access.js +++ b/tulius/static/forum/components/thread_access.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_thread_access', { template: '/static/forum/components/thread_access.html', props: { diff --git a/tulius/forum/static/forum/components/thread_selector.html b/tulius/static/forum/components/thread_selector.html similarity index 100% rename from tulius/forum/static/forum/components/thread_selector.html rename to tulius/static/forum/components/thread_selector.html diff --git a/tulius/forum/static/forum/components/thread_selector.js b/tulius/static/forum/components/thread_selector.js similarity index 94% rename from tulius/forum/static/forum/components/thread_selector.js rename to tulius/static/forum/components/thread_selector.js index fe67d7b7..2c4e5a2d 100644 --- a/tulius/forum/static/forum/components/thread_selector.js +++ b/tulius/static/forum/components/thread_selector.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('thread_selector', { template: '/static/forum/components/thread_selector.html', props: { diff --git a/tulius/forum/static/forum/components/voting.html b/tulius/static/forum/components/voting.html similarity index 100% rename from tulius/forum/static/forum/components/voting.html rename to tulius/static/forum/components/voting.html diff --git a/tulius/forum/static/forum/components/voting.js b/tulius/static/forum/components/voting.js similarity index 96% rename from tulius/forum/static/forum/components/voting.js rename to tulius/static/forum/components/voting.js index eaa0687c..81c0b4d1 100644 --- a/tulius/forum/static/forum/components/voting.js +++ b/tulius/static/forum/components/voting.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_voting', { template: '/static/forum/components/voting.html', props: { diff --git a/tulius/forum/elastic_search/static/forum/elastic_search/reindex_all.html b/tulius/static/forum/elastic_search/reindex_all.html similarity index 100% rename from tulius/forum/elastic_search/static/forum/elastic_search/reindex_all.html rename to tulius/static/forum/elastic_search/reindex_all.html diff --git a/tulius/forum/elastic_search/static/forum/elastic_search/reindex_all.js b/tulius/static/forum/elastic_search/reindex_all.js similarity index 91% rename from tulius/forum/elastic_search/static/forum/elastic_search/reindex_all.js rename to tulius/static/forum/elastic_search/reindex_all.js index 2697ccc6..6a7a493d 100644 --- a/tulius/forum/elastic_search/static/forum/elastic_search/reindex_all.js +++ b/tulius/static/forum/elastic_search/reindex_all.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_elastic_reindex_all', { template: '/static/forum/elastic_search/reindex_all.html', data: function () { diff --git a/tulius/forum/elastic_search/static/forum/elastic_search/reindex_thread.html b/tulius/static/forum/elastic_search/reindex_thread.html similarity index 100% rename from tulius/forum/elastic_search/static/forum/elastic_search/reindex_thread.html rename to tulius/static/forum/elastic_search/reindex_thread.html diff --git a/tulius/forum/elastic_search/static/forum/elastic_search/reindex_thread.js b/tulius/static/forum/elastic_search/reindex_thread.js similarity index 93% rename from tulius/forum/elastic_search/static/forum/elastic_search/reindex_thread.js rename to tulius/static/forum/elastic_search/reindex_thread.js index 579d2d4e..f4d45f7a 100644 --- a/tulius/forum/elastic_search/static/forum/elastic_search/reindex_thread.js +++ b/tulius/static/forum/elastic_search/reindex_thread.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_elastic_reindex_thread', { template: '/static/forum/elastic_search/reindex_thread.html', data: function () { diff --git a/tulius/forum/static/forum/img/closed.gif b/tulius/static/forum/img/closed.gif similarity index 100% rename from tulius/forum/static/forum/img/closed.gif rename to tulius/static/forum/img/closed.gif diff --git a/tulius/forum/static/forum/img/delete_post.png b/tulius/static/forum/img/delete_post.png similarity index 100% rename from tulius/forum/static/forum/img/delete_post.png rename to tulius/static/forum/img/delete_post.png diff --git a/tulius/forum/static/forum/img/editbutton.gif b/tulius/static/forum/img/editbutton.gif similarity index 100% rename from tulius/forum/static/forum/img/editbutton.gif rename to tulius/static/forum/img/editbutton.gif diff --git a/tulius/forum/static/forum/img/important_not_readed.gif b/tulius/static/forum/img/important_not_readed.gif similarity index 100% rename from tulius/forum/static/forum/img/important_not_readed.gif rename to tulius/static/forum/img/important_not_readed.gif diff --git a/tulius/forum/static/forum/img/important_readed.gif b/tulius/static/forum/img/important_readed.gif similarity index 100% rename from tulius/forum/static/forum/img/important_readed.gif rename to tulius/static/forum/img/important_readed.gif diff --git a/tulius/forum/static/forum/img/like.gif b/tulius/static/forum/img/like.gif similarity index 100% rename from tulius/forum/static/forum/img/like.gif rename to tulius/static/forum/img/like.gif diff --git a/tulius/forum/static/forum/img/loading.gif b/tulius/static/forum/img/loading.gif similarity index 100% rename from tulius/forum/static/forum/img/loading.gif rename to tulius/static/forum/img/loading.gif diff --git a/tulius/forum/static/forum/img/move.gif b/tulius/static/forum/img/move.gif similarity index 100% rename from tulius/forum/static/forum/img/move.gif rename to tulius/static/forum/img/move.gif diff --git a/tulius/forum/static/forum/img/online.png b/tulius/static/forum/img/online.png similarity index 100% rename from tulius/forum/static/forum/img/online.png rename to tulius/static/forum/img/online.png diff --git a/tulius/forum/static/forum/img/quote.gif b/tulius/static/forum/img/quote.gif similarity index 100% rename from tulius/forum/static/forum/img/quote.gif rename to tulius/static/forum/img/quote.gif diff --git a/tulius/forum/static/forum/img/quote_help1.png b/tulius/static/forum/img/quote_help1.png similarity index 100% rename from tulius/forum/static/forum/img/quote_help1.png rename to tulius/static/forum/img/quote_help1.png diff --git a/tulius/forum/static/forum/img/quote_help2.png b/tulius/static/forum/img/quote_help2.png similarity index 100% rename from tulius/forum/static/forum/img/quote_help2.png rename to tulius/static/forum/img/quote_help2.png diff --git a/tulius/forum/static/forum/img/readedmark.gif b/tulius/static/forum/img/readedmark.gif similarity index 100% rename from tulius/forum/static/forum/img/readedmark.gif rename to tulius/static/forum/img/readedmark.gif diff --git a/tulius/forum/static/forum/img/refresh-loading.gif b/tulius/static/forum/img/refresh-loading.gif similarity index 100% rename from tulius/forum/static/forum/img/refresh-loading.gif rename to tulius/static/forum/img/refresh-loading.gif diff --git a/tulius/forum/static/forum/img/refresh.gif b/tulius/static/forum/img/refresh.gif similarity index 100% rename from tulius/forum/static/forum/img/refresh.gif rename to tulius/static/forum/img/refresh.gif diff --git a/tulius/forum/static/forum/img/replybutton.gif b/tulius/static/forum/img/replybutton.gif similarity index 100% rename from tulius/forum/static/forum/img/replybutton.gif rename to tulius/static/forum/img/replybutton.gif diff --git a/tulius/forum/static/forum/img/unlike.gif b/tulius/static/forum/img/unlike.gif similarity index 100% rename from tulius/forum/static/forum/img/unlike.gif rename to tulius/static/forum/img/unlike.gif diff --git a/tulius/forum/static/forum/img/unreadedmark.gif b/tulius/static/forum/img/unreadedmark.gif similarity index 100% rename from tulius/forum/static/forum/img/unreadedmark.gif rename to tulius/static/forum/img/unreadedmark.gif diff --git a/tulius/forum/static/forum/pages/add_room.html b/tulius/static/forum/pages/add_room.html similarity index 100% rename from tulius/forum/static/forum/pages/add_room.html rename to tulius/static/forum/pages/add_room.html diff --git a/tulius/forum/static/forum/pages/add_room.js b/tulius/static/forum/pages/add_room.js similarity index 95% rename from tulius/forum/static/forum/pages/add_room.js rename to tulius/static/forum/pages/add_room.js index e9268831..a553047c 100644 --- a/tulius/forum/static/forum/pages/add_room.js +++ b/tulius/static/forum/pages/add_room.js @@ -1,5 +1,7 @@ import thread_access from '../components/thread_access.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_add_room_page', { diff --git a/tulius/forum/static/forum/pages/deleted_threads.html b/tulius/static/forum/pages/deleted_threads.html similarity index 100% rename from tulius/forum/static/forum/pages/deleted_threads.html rename to tulius/static/forum/pages/deleted_threads.html diff --git a/tulius/forum/static/forum/pages/deleted_threads.js b/tulius/static/forum/pages/deleted_threads.js similarity index 94% rename from tulius/forum/static/forum/pages/deleted_threads.js rename to tulius/static/forum/pages/deleted_threads.js index 54255efe..a5fc1a00 100644 --- a/tulius/forum/static/forum/pages/deleted_threads.js +++ b/tulius/static/forum/pages/deleted_threads.js @@ -3,6 +3,8 @@ import thread_list from '../snippets/thread_list.js' import thread_actions from '../snippets/thread_actions.js' import online_status from '../snippets/online_status.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_room_page_deleted', { diff --git a/tulius/forum/static/forum/pages/edit_comment.html b/tulius/static/forum/pages/edit_comment.html similarity index 100% rename from tulius/forum/static/forum/pages/edit_comment.html rename to tulius/static/forum/pages/edit_comment.html diff --git a/tulius/forum/static/forum/pages/edit_comment.js b/tulius/static/forum/pages/edit_comment.js similarity index 91% rename from tulius/forum/static/forum/pages/edit_comment.js rename to tulius/static/forum/pages/edit_comment.js index 580f1f7b..72a53acf 100644 --- a/tulius/forum/static/forum/pages/edit_comment.js +++ b/tulius/static/forum/pages/edit_comment.js @@ -1,5 +1,7 @@ import reply_form_component from '../components/reply_form.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_edit_comment_page', { diff --git a/tulius/forum/static/forum/pages/edit_thread.html b/tulius/static/forum/pages/edit_thread.html similarity index 100% rename from tulius/forum/static/forum/pages/edit_thread.html rename to tulius/static/forum/pages/edit_thread.html diff --git a/tulius/forum/static/forum/pages/edit_thread.js b/tulius/static/forum/pages/edit_thread.js similarity index 97% rename from tulius/forum/static/forum/pages/edit_thread.js rename to tulius/static/forum/pages/edit_thread.js index 14c6c037..bc412fca 100644 --- a/tulius/forum/static/forum/pages/edit_thread.js +++ b/tulius/static/forum/pages/edit_thread.js @@ -1,5 +1,8 @@ import thread_access from '../components/thread_access.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + function cleanup_form(target, source) { for (const [key, value] of Object.entries(source)) diff --git a/tulius/forum/static/forum/pages/extended_search.html b/tulius/static/forum/pages/extended_search.html similarity index 100% rename from tulius/forum/static/forum/pages/extended_search.html rename to tulius/static/forum/pages/extended_search.html diff --git a/tulius/forum/static/forum/pages/extended_search.js b/tulius/static/forum/pages/extended_search.js similarity index 97% rename from tulius/forum/static/forum/pages/extended_search.js rename to tulius/static/forum/pages/extended_search.js index 4c0e3ab7..7e6fadd5 100644 --- a/tulius/forum/static/forum/pages/extended_search.js +++ b/tulius/static/forum/pages/extended_search.js @@ -1,5 +1,7 @@ import APILoadMixin from '../../app/components/api_load_mixin.js' import thread_selector from '../components/thread_selector.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_extended_search_page', { diff --git a/tulius/forum/static/forum/pages/fix_counters.html b/tulius/static/forum/pages/fix_counters.html similarity index 100% rename from tulius/forum/static/forum/pages/fix_counters.html rename to tulius/static/forum/pages/fix_counters.html diff --git a/tulius/forum/static/forum/pages/fix_counters.js b/tulius/static/forum/pages/fix_counters.js similarity index 91% rename from tulius/forum/static/forum/pages/fix_counters.js rename to tulius/static/forum/pages/fix_counters.js index 34305db5..95d99b65 100644 --- a/tulius/forum/static/forum/pages/fix_counters.js +++ b/tulius/static/forum/pages/fix_counters.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_fix_counters', { template: '/static/forum/pages/fix_counters.html', data: function () { diff --git a/tulius/forum/static/forum/pages/index.html b/tulius/static/forum/pages/index.html similarity index 100% rename from tulius/forum/static/forum/pages/index.html rename to tulius/static/forum/pages/index.html diff --git a/tulius/forum/static/forum/pages/index.js b/tulius/static/forum/pages/index.js similarity index 96% rename from tulius/forum/static/forum/pages/index.js rename to tulius/static/forum/pages/index.js index cfb84129..607ee981 100644 --- a/tulius/forum/static/forum/pages/index.js +++ b/tulius/static/forum/pages/index.js @@ -1,5 +1,7 @@ import room_list from '../snippets/room_list.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_index_page', { diff --git a/tulius/forum/static/forum/pages/room.html b/tulius/static/forum/pages/room.html similarity index 100% rename from tulius/forum/static/forum/pages/room.html rename to tulius/static/forum/pages/room.html diff --git a/tulius/forum/static/forum/pages/room.js b/tulius/static/forum/pages/room.js similarity index 92% rename from tulius/forum/static/forum/pages/room.js rename to tulius/static/forum/pages/room.js index a6b7c2e6..28206ac1 100644 --- a/tulius/forum/static/forum/pages/room.js +++ b/tulius/static/forum/pages/room.js @@ -3,6 +3,8 @@ import thread_list from '../snippets/thread_list.js' import thread_actions from '../snippets/thread_actions.js' import online_status from '../snippets/online_status.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_room_page', { diff --git a/tulius/forum/static/forum/pages/search_results.html b/tulius/static/forum/pages/search_results.html similarity index 100% rename from tulius/forum/static/forum/pages/search_results.html rename to tulius/static/forum/pages/search_results.html diff --git a/tulius/forum/static/forum/pages/search_results.js b/tulius/static/forum/pages/search_results.js similarity index 94% rename from tulius/forum/static/forum/pages/search_results.js rename to tulius/static/forum/pages/search_results.js index 5d5bc605..52565dd0 100644 --- a/tulius/forum/static/forum/pages/search_results.js +++ b/tulius/static/forum/pages/search_results.js @@ -1,6 +1,8 @@ import thread_actions from '../snippets/thread_actions.js' import comment from '../snippets/comment.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_search_results', { diff --git a/tulius/forum/static/forum/pages/thread.html b/tulius/static/forum/pages/thread.html similarity index 100% rename from tulius/forum/static/forum/pages/thread.html rename to tulius/static/forum/pages/thread.html diff --git a/tulius/forum/static/forum/pages/thread.js b/tulius/static/forum/pages/thread.js similarity index 92% rename from tulius/forum/static/forum/pages/thread.js rename to tulius/static/forum/pages/thread.js index c85a2e58..4faa6d5c 100644 --- a/tulius/forum/static/forum/pages/thread.js +++ b/tulius/static/forum/pages/thread.js @@ -3,6 +3,8 @@ import online_status from '../snippets/online_status.js' import comments_component from '../components/comments.js' import reply_form_component from '../components/reply_form.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_thread_page', { diff --git a/tulius/forum/static/forum/snippets/avatar.html b/tulius/static/forum/snippets/avatar.html similarity index 100% rename from tulius/forum/static/forum/snippets/avatar.html rename to tulius/static/forum/snippets/avatar.html diff --git a/tulius/forum/static/forum/snippets/avatar.js b/tulius/static/forum/snippets/avatar.js similarity index 93% rename from tulius/forum/static/forum/snippets/avatar.js rename to tulius/static/forum/snippets/avatar.js index 6152ab0c..590ebe2a 100644 --- a/tulius/forum/static/forum/snippets/avatar.js +++ b/tulius/static/forum/snippets/avatar.js @@ -1,3 +1,6 @@ +import {LazyComponent} from '../../common/js/vue-common.js' + + export default LazyComponent('user_avatar', { template: '/static/forum/snippets/avatar.html', props: ['user', 'thread'], diff --git a/tulius/forum/static/forum/snippets/comment.html b/tulius/static/forum/snippets/comment.html similarity index 100% rename from tulius/forum/static/forum/snippets/comment.html rename to tulius/static/forum/snippets/comment.html diff --git a/tulius/forum/static/forum/snippets/comment.js b/tulius/static/forum/snippets/comment.js similarity index 91% rename from tulius/forum/static/forum/snippets/comment.js rename to tulius/static/forum/snippets/comment.js index 88451505..53b191ae 100644 --- a/tulius/forum/static/forum/snippets/comment.js +++ b/tulius/static/forum/snippets/comment.js @@ -1,5 +1,8 @@ import avatar from '../snippets/avatar.js' import voting from '../components/voting.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; +import {forum_datetime} from '../../common/js/vue-common.js' export default LazyComponent('forum_comment', { diff --git a/tulius/static/forum/snippets/latest_post.vue b/tulius/static/forum/snippets/latest_post.vue new file mode 100644 index 00000000..e8fb5895 --- /dev/null +++ b/tulius/static/forum/snippets/latest_post.vue @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/tulius/forum/static/forum/snippets/online_status.html b/tulius/static/forum/snippets/online_status.html similarity index 100% rename from tulius/forum/static/forum/snippets/online_status.html rename to tulius/static/forum/snippets/online_status.html diff --git a/tulius/forum/static/forum/snippets/online_status.js b/tulius/static/forum/snippets/online_status.js similarity index 90% rename from tulius/forum/static/forum/snippets/online_status.js rename to tulius/static/forum/snippets/online_status.js index 2e2c6ba9..65ee55fd 100644 --- a/tulius/forum/static/forum/snippets/online_status.js +++ b/tulius/static/forum/snippets/online_status.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('forum_online_status', { template: '/static/forum/snippets/online_status.html', props: ['thread'], diff --git a/tulius/forum/static/forum/snippets/room_list.html b/tulius/static/forum/snippets/room_list.html similarity index 100% rename from tulius/forum/static/forum/snippets/room_list.html rename to tulius/static/forum/snippets/room_list.html diff --git a/tulius/forum/static/forum/snippets/room_list.js b/tulius/static/forum/snippets/room_list.js similarity index 76% rename from tulius/forum/static/forum/snippets/room_list.js rename to tulius/static/forum/snippets/room_list.js index 796626a5..07f700b0 100644 --- a/tulius/forum/static/forum/snippets/room_list.js +++ b/tulius/static/forum/snippets/room_list.js @@ -1,4 +1,7 @@ -import latest_post from './latest_post.js' +import latest_post from './latest_post.vue' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + export default LazyComponent('forum_room_list', { template: '/static/forum/snippets/room_list.html', diff --git a/tulius/forum/static/forum/snippets/thread_actions.html b/tulius/static/forum/snippets/thread_actions.html similarity index 100% rename from tulius/forum/static/forum/snippets/thread_actions.html rename to tulius/static/forum/snippets/thread_actions.html diff --git a/tulius/forum/static/forum/snippets/thread_actions.js b/tulius/static/forum/snippets/thread_actions.js similarity index 95% rename from tulius/forum/static/forum/snippets/thread_actions.js rename to tulius/static/forum/snippets/thread_actions.js index 051b6aff..218b419b 100644 --- a/tulius/forum/static/forum/snippets/thread_actions.js +++ b/tulius/static/forum/snippets/thread_actions.js @@ -1,6 +1,8 @@ import thread_access from '../components/thread_access.js' import edit_room from '../components/edit_room.js' import move_thread from '../components/move_thread.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('forum_thread_actions', { diff --git a/tulius/forum/static/forum/snippets/thread_list.html b/tulius/static/forum/snippets/thread_list.html similarity index 100% rename from tulius/forum/static/forum/snippets/thread_list.html rename to tulius/static/forum/snippets/thread_list.html diff --git a/tulius/forum/static/forum/snippets/thread_list.js b/tulius/static/forum/snippets/thread_list.js similarity index 76% rename from tulius/forum/static/forum/snippets/thread_list.js rename to tulius/static/forum/snippets/thread_list.js index 3074ca6b..2c1360fc 100644 --- a/tulius/forum/static/forum/snippets/thread_list.js +++ b/tulius/static/forum/snippets/thread_list.js @@ -1,4 +1,7 @@ -import latest_post from './latest_post.js' +import latest_post from './latest_post.vue' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + export default LazyComponent('forum_thread_list', { template: '/static/forum/snippets/thread_list.html', diff --git a/tulius/gameforum/static/gameforum/app/app.html b/tulius/static/gameforum/app/app.html similarity index 100% rename from tulius/gameforum/static/gameforum/app/app.html rename to tulius/static/gameforum/app/app.html diff --git a/tulius/gameforum/static/gameforum/app/app.js b/tulius/static/gameforum/app/app.js similarity index 95% rename from tulius/gameforum/static/gameforum/app/app.js rename to tulius/static/gameforum/app/app.js index a0010779..6f8d661f 100644 --- a/tulius/gameforum/static/gameforum/app/app.js +++ b/tulius/static/gameforum/app/app.js @@ -1,5 +1,7 @@ import APILoadMixin from '../../app/components/api_load_mixin.js' import urls from './urls.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('gameforum_app', { diff --git a/tulius/gameforum/static/gameforum/app/game_redirect.js b/tulius/static/gameforum/app/game_redirect.js similarity index 87% rename from tulius/gameforum/static/gameforum/app/game_redirect.js rename to tulius/static/gameforum/app/game_redirect.js index e2927f10..d599e5fc 100644 --- a/tulius/gameforum/static/gameforum/app/game_redirect.js +++ b/tulius/static/gameforum/app/game_redirect.js @@ -1,5 +1,8 @@ +import Vue from 'vue' import APILoadMixin from '../../app/components/api_load_mixin.js' import urls from './urls.js' +import axios from '../../common/js/axios.min.js'; + export default Vue.component('game_redirect', { mixins: [APILoadMixin,], diff --git a/tulius/gameforum/static/gameforum/app/redirect.js b/tulius/static/gameforum/app/redirect.js similarity index 93% rename from tulius/gameforum/static/gameforum/app/redirect.js rename to tulius/static/gameforum/app/redirect.js index 1bcba1c8..cfb78fd0 100644 --- a/tulius/gameforum/static/gameforum/app/redirect.js +++ b/tulius/static/gameforum/app/redirect.js @@ -1,3 +1,7 @@ +import Vue from 'vue' +import axios from '../../common/js/axios.min.js'; + + export default Vue.component('game_thread_redirect', { template: '
', data: function () { diff --git a/tulius/gameforum/static/gameforum/app/routes.js b/tulius/static/gameforum/app/routes.js similarity index 100% rename from tulius/gameforum/static/gameforum/app/routes.js rename to tulius/static/gameforum/app/routes.js diff --git a/tulius/gameforum/static/gameforum/app/urls.js b/tulius/static/gameforum/app/urls.js similarity index 100% rename from tulius/gameforum/static/gameforum/app/urls.js rename to tulius/static/gameforum/app/urls.js diff --git a/tulius/gameforum/static/gameforum/app/variation_redirect.js b/tulius/static/gameforum/app/variation_redirect.js similarity index 87% rename from tulius/gameforum/static/gameforum/app/variation_redirect.js rename to tulius/static/gameforum/app/variation_redirect.js index 9a588886..cb4acabd 100644 --- a/tulius/gameforum/static/gameforum/app/variation_redirect.js +++ b/tulius/static/gameforum/app/variation_redirect.js @@ -1,5 +1,8 @@ +import Vue from 'vue' import APILoadMixin from '../../app/components/api_load_mixin.js' import urls from './urls.js' +import axios from '../../common/js/axios.min.js'; + export default Vue.component('variation_redirect', { mixins: [APILoadMixin,], diff --git a/tulius/gameforum/static/gameforum/components/avatar.html b/tulius/static/gameforum/components/avatar.html similarity index 100% rename from tulius/gameforum/static/gameforum/components/avatar.html rename to tulius/static/gameforum/components/avatar.html diff --git a/tulius/gameforum/static/gameforum/components/avatar.js b/tulius/static/gameforum/components/avatar.js similarity index 93% rename from tulius/gameforum/static/gameforum/components/avatar.js rename to tulius/static/gameforum/components/avatar.js index 70757238..80a961b8 100644 --- a/tulius/gameforum/static/gameforum/components/avatar.js +++ b/tulius/static/gameforum/components/avatar.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('game_forum_comment_avatar', { template: '/static/gameforum/components/avatar.html', props: ['variation', 'thread', 'role', 'actions'], diff --git a/tulius/gameforum/static/gameforum/components/favorite_comment.html b/tulius/static/gameforum/components/favorite_comment.html similarity index 100% rename from tulius/gameforum/static/gameforum/components/favorite_comment.html rename to tulius/static/gameforum/components/favorite_comment.html diff --git a/tulius/gameforum/static/gameforum/components/favorite_comment.js b/tulius/static/gameforum/components/favorite_comment.js similarity index 84% rename from tulius/gameforum/static/gameforum/components/favorite_comment.js rename to tulius/static/gameforum/components/favorite_comment.js index 3669a17b..dc86adae 100644 --- a/tulius/gameforum/static/gameforum/components/favorite_comment.js +++ b/tulius/static/gameforum/components/favorite_comment.js @@ -1,4 +1,5 @@ import urls from '../app/urls.js' +import {LazyComponent} from '../../common/js/vue-common.js' export default LazyComponent('game_forum_favorite_comment', { diff --git a/tulius/gameforum/static/gameforum/components/media/illustrations.html b/tulius/static/gameforum/components/media/illustrations.html similarity index 100% rename from tulius/gameforum/static/gameforum/components/media/illustrations.html rename to tulius/static/gameforum/components/media/illustrations.html diff --git a/tulius/gameforum/static/gameforum/components/media/illustrations.js b/tulius/static/gameforum/components/media/illustrations.js similarity index 97% rename from tulius/gameforum/static/gameforum/components/media/illustrations.js rename to tulius/static/gameforum/components/media/illustrations.js index 23717861..7b454a40 100644 --- a/tulius/gameforum/static/gameforum/components/media/illustrations.js +++ b/tulius/static/gameforum/components/media/illustrations.js @@ -1,4 +1,6 @@ import baseMixin from '../../../forum/components/media/base.js' +import {LazyComponent} from '../../../common/js/vue-common.js' + export default LazyComponent('media_illustrations', { template: '/static/gameforum/components/media/illustrations.html', diff --git a/tulius/gameforum/static/gameforum/components/online_status.html b/tulius/static/gameforum/components/online_status.html similarity index 100% rename from tulius/gameforum/static/gameforum/components/online_status.html rename to tulius/static/gameforum/components/online_status.html diff --git a/tulius/gameforum/static/gameforum/components/online_status.js b/tulius/static/gameforum/components/online_status.js similarity index 94% rename from tulius/gameforum/static/gameforum/components/online_status.js rename to tulius/static/gameforum/components/online_status.js index 5b04ab60..31aeeab3 100644 --- a/tulius/gameforum/static/gameforum/components/online_status.js +++ b/tulius/static/gameforum/components/online_status.js @@ -1,3 +1,7 @@ +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; + + export default LazyComponent('game_forum_online_status', { template: '/static/gameforum/components/online_status.html', props: ['variation', 'thread'], diff --git a/tulius/gameforum/static/gameforum/components/role_selector.html b/tulius/static/gameforum/components/role_selector.html similarity index 100% rename from tulius/gameforum/static/gameforum/components/role_selector.html rename to tulius/static/gameforum/components/role_selector.html diff --git a/tulius/gameforum/static/gameforum/components/role_selector.js b/tulius/static/gameforum/components/role_selector.js similarity index 95% rename from tulius/gameforum/static/gameforum/components/role_selector.js rename to tulius/static/gameforum/components/role_selector.js index 7a21f35c..328390a3 100644 --- a/tulius/gameforum/static/gameforum/components/role_selector.js +++ b/tulius/static/gameforum/components/role_selector.js @@ -1,3 +1,6 @@ +import {LazyComponent} from '../../common/js/vue-common.js' + + export default LazyComponent('game_forum_role_selector', { template: '/static/gameforum/components/role_selector.html', props: ['variation', 'thread', 'form', 'editor'], diff --git a/tulius/gameforum/static/gameforum/components/thread_actions.html b/tulius/static/gameforum/components/thread_actions.html similarity index 100% rename from tulius/gameforum/static/gameforum/components/thread_actions.html rename to tulius/static/gameforum/components/thread_actions.html diff --git a/tulius/gameforum/static/gameforum/components/thread_actions.js b/tulius/static/gameforum/components/thread_actions.js similarity index 97% rename from tulius/gameforum/static/gameforum/components/thread_actions.js rename to tulius/static/gameforum/components/thread_actions.js index 9844f6f3..32c9b5e0 100644 --- a/tulius/gameforum/static/gameforum/components/thread_actions.js +++ b/tulius/static/gameforum/components/thread_actions.js @@ -1,5 +1,7 @@ import edit_room from '../../forum/components/edit_room.js' import move_thread from '../../forum/components/move_thread.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('game_forum_thread_actions', { diff --git a/tulius/gameforum/static/gameforum/pages/add_room.html b/tulius/static/gameforum/pages/add_room.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/add_room.html rename to tulius/static/gameforum/pages/add_room.html diff --git a/tulius/gameforum/static/gameforum/pages/add_room.js b/tulius/static/gameforum/pages/add_room.js similarity index 94% rename from tulius/gameforum/static/gameforum/pages/add_room.js rename to tulius/static/gameforum/pages/add_room.js index 8227f143..333665d8 100644 --- a/tulius/gameforum/static/gameforum/pages/add_room.js +++ b/tulius/static/gameforum/pages/add_room.js @@ -1,4 +1,5 @@ import add_room from '../../forum/pages/add_room.js' +import {LazyComponent} from '../../common/js/vue-common.js' export default LazyComponent('game_forum_add_room_page', { diff --git a/tulius/gameforum/static/gameforum/pages/deleted_threads.html b/tulius/static/gameforum/pages/deleted_threads.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/deleted_threads.html rename to tulius/static/gameforum/pages/deleted_threads.html diff --git a/tulius/gameforum/static/gameforum/pages/deleted_threads.js b/tulius/static/gameforum/pages/deleted_threads.js similarity index 95% rename from tulius/gameforum/static/gameforum/pages/deleted_threads.js rename to tulius/static/gameforum/pages/deleted_threads.js index 91963ef1..82d0958a 100644 --- a/tulius/gameforum/static/gameforum/pages/deleted_threads.js +++ b/tulius/static/gameforum/pages/deleted_threads.js @@ -3,6 +3,8 @@ import thread_list from '../../forum/snippets/thread_list.js' import thread_actions from '../components/thread_actions.js' import online_status from '../components/online_status.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('game_room_page_deleted', { diff --git a/tulius/gameforum/static/gameforum/pages/edit_comment.html b/tulius/static/gameforum/pages/edit_comment.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/edit_comment.html rename to tulius/static/gameforum/pages/edit_comment.html diff --git a/tulius/gameforum/static/gameforum/pages/edit_comment.js b/tulius/static/gameforum/pages/edit_comment.js similarity index 92% rename from tulius/gameforum/static/gameforum/pages/edit_comment.js rename to tulius/static/gameforum/pages/edit_comment.js index 91a7e44a..de39cc77 100644 --- a/tulius/gameforum/static/gameforum/pages/edit_comment.js +++ b/tulius/static/gameforum/pages/edit_comment.js @@ -1,5 +1,7 @@ import reply_form_component from '../../forum/components/reply_form.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('game_forum_edit_comment_page', { diff --git a/tulius/gameforum/static/gameforum/pages/edit_thread.html b/tulius/static/gameforum/pages/edit_thread.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/edit_thread.html rename to tulius/static/gameforum/pages/edit_thread.html diff --git a/tulius/gameforum/static/gameforum/pages/edit_thread.js b/tulius/static/gameforum/pages/edit_thread.js similarity index 94% rename from tulius/gameforum/static/gameforum/pages/edit_thread.js rename to tulius/static/gameforum/pages/edit_thread.js index ef7419a6..e6b27b43 100644 --- a/tulius/gameforum/static/gameforum/pages/edit_thread.js +++ b/tulius/static/gameforum/pages/edit_thread.js @@ -1,4 +1,5 @@ import edit_thread from '../../forum/pages/edit_thread.js' +import {LazyComponent} from '../../common/js/vue-common.js' export default LazyComponent('game_forum_edit_thread_page', { diff --git a/tulius/gameforum/static/gameforum/pages/extended_search.html b/tulius/static/gameforum/pages/extended_search.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/extended_search.html rename to tulius/static/gameforum/pages/extended_search.html diff --git a/tulius/gameforum/static/gameforum/pages/extended_search.js b/tulius/static/gameforum/pages/extended_search.js similarity index 91% rename from tulius/gameforum/static/gameforum/pages/extended_search.js rename to tulius/static/gameforum/pages/extended_search.js index 80a0ba8f..b4870931 100644 --- a/tulius/gameforum/static/gameforum/pages/extended_search.js +++ b/tulius/static/gameforum/pages/extended_search.js @@ -1,3 +1,6 @@ +import {LazyComponent} from '../../common/js/vue-common.js' + + export default LazyComponent('game_extended_search', { template: '/static/gameforum/pages/extended_search.html', data: function () { diff --git a/tulius/gameforum/static/gameforum/pages/room.html b/tulius/static/gameforum/pages/room.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/room.html rename to tulius/static/gameforum/pages/room.html diff --git a/tulius/gameforum/static/gameforum/pages/room.js b/tulius/static/gameforum/pages/room.js similarity index 94% rename from tulius/gameforum/static/gameforum/pages/room.js rename to tulius/static/gameforum/pages/room.js index 493348b2..a5c0852c 100644 --- a/tulius/gameforum/static/gameforum/pages/room.js +++ b/tulius/static/gameforum/pages/room.js @@ -3,6 +3,8 @@ import thread_list from '../../forum/snippets/thread_list.js' import thread_actions from '../components/thread_actions.js' import online_status from '../components/online_status.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('game_room_page', { diff --git a/tulius/gameforum/static/gameforum/pages/search_results.html b/tulius/static/gameforum/pages/search_results.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/search_results.html rename to tulius/static/gameforum/pages/search_results.html diff --git a/tulius/gameforum/static/gameforum/pages/search_results.js b/tulius/static/gameforum/pages/search_results.js similarity index 91% rename from tulius/gameforum/static/gameforum/pages/search_results.js rename to tulius/static/gameforum/pages/search_results.js index 8efaf993..4a0fd8cc 100644 --- a/tulius/gameforum/static/gameforum/pages/search_results.js +++ b/tulius/static/gameforum/pages/search_results.js @@ -1,3 +1,6 @@ +import {LazyComponent} from '../../common/js/vue-common.js' + + export default LazyComponent('game_search_results', { template: '/static/gameforum/pages/search_results.html', data: function () { diff --git a/tulius/gameforum/static/gameforum/pages/thread.html b/tulius/static/gameforum/pages/thread.html similarity index 100% rename from tulius/gameforum/static/gameforum/pages/thread.html rename to tulius/static/gameforum/pages/thread.html diff --git a/tulius/gameforum/static/gameforum/pages/thread.js b/tulius/static/gameforum/pages/thread.js similarity index 95% rename from tulius/gameforum/static/gameforum/pages/thread.js rename to tulius/static/gameforum/pages/thread.js index 5a7a09cc..61ad72b8 100644 --- a/tulius/gameforum/static/gameforum/pages/thread.js +++ b/tulius/static/gameforum/pages/thread.js @@ -6,6 +6,8 @@ import comments_component from '../../forum/components/comments.js' import reply_form_component from '../../forum/components/reply_form.js' import APILoadMixin from '../../app/components/api_load_mixin.js' import media_illustrations from '../components/media/illustrations.js' +import {LazyComponent} from '../../common/js/vue-common.js' +import axios from '../../common/js/axios.min.js'; export default LazyComponent('gameforum_thread_page', { diff --git a/tulius/static/package.json b/tulius/static/package.json new file mode 100644 index 00000000..6ab4740c --- /dev/null +++ b/tulius/static/package.json @@ -0,0 +1,28 @@ +{ + "name": "tulius", + "description": "Tulius.com frontend", + "homepage": "Tulius.com", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/kozzztik/tulius" + }, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build" + }, + "dependencies": { + "vue": "^2.6.11", + "vue-router": "^3.2.0" + }, + "devDependencies": { + "@vue/cli-plugin-router": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "vue-template-compiler": "^2.6.11" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/tulius/static/pages/celery_status.js b/tulius/static/pages/celery_status.js index eb7999f7..3de5e83e 100644 --- a/tulius/static/pages/celery_status.js +++ b/tulius/static/pages/celery_status.js @@ -1,4 +1,6 @@ import APILoadMixin from '../app/components/api_load_mixin.js' +import {LazyComponent} from '../common/js/vue-common.js' +import axios from '../common/js/axios.min.js'; export default LazyComponent('celery_status', { diff --git a/tulius/profile/static/profile/app/routes.js b/tulius/static/profile/app/routes.js similarity index 100% rename from tulius/profile/static/profile/app/routes.js rename to tulius/static/profile/app/routes.js diff --git a/tulius/profile/static/profile/pages/favorites.html b/tulius/static/profile/pages/favorites.html similarity index 100% rename from tulius/profile/static/profile/pages/favorites.html rename to tulius/static/profile/pages/favorites.html diff --git a/tulius/profile/static/profile/pages/favorites.js b/tulius/static/profile/pages/favorites.js similarity index 92% rename from tulius/profile/static/profile/pages/favorites.js rename to tulius/static/profile/pages/favorites.js index 353e0141..bfa7f49b 100644 --- a/tulius/profile/static/profile/pages/favorites.js +++ b/tulius/static/profile/pages/favorites.js @@ -1,6 +1,7 @@ import favorites from '../../forum/components/favorites.js' import game_favorites from '../../gameforum/components/favorite_comment.js' import APILoadMixin from '../../app/components/api_load_mixin.js' +import {LazyComponent} from '../../common/js/vue-common.js' export default LazyComponent('profile_favorites', { diff --git a/tulius/static/vue.config.js b/tulius/static/vue.config.js new file mode 100644 index 00000000..3a4083fb --- /dev/null +++ b/tulius/static/vue.config.js @@ -0,0 +1,22 @@ +module.exports = { + publicPath: '/static/', + pages: { + app: { + entry: 'app/app.js', + template: 'app/index.html', + } + }, + runtimeCompiler: true, + filenameHashing: false, + lintOnSave: false, + devServer: { + port: 9000, + headers: {"Access-Control-Allow-Origin": "*"}, + }, + // удаление плагинов webpack связанных с HTML + chainWebpack: config => { + config.plugins.delete('html') + config.plugins.delete('preload') + config.plugins.delete('prefetch') + }, +} \ No newline at end of file diff --git a/tulius/templates/base.haml b/tulius/templates/base.haml index 2738920c..9fab8a43 100755 --- a/tulius/templates/base.haml +++ b/tulius/templates/base.haml @@ -18,7 +18,8 @@ %script{type: 'text/javascript', src: '{{ STATIC_URL }}common/js/autocomplete-select.js'} %script{type: 'text/javascript', src: '{{ STATIC_URL }}websockets/ws4redis.js'} - - - - - - - - - - -
@@ -53,7 +41,9 @@
- + {% for module in index_bundle %} + + {% endfor %} diff --git a/tulius/urls.py b/tulius/urls.py index 8ddc6e08..a8feb690 100755 --- a/tulius/urls.py +++ b/tulius/urls.py @@ -105,6 +105,10 @@ def trigger_error(_): urls.re_path( r'^counters/', urls.include( 'tulius.counters.urls', namespace='counters')), + urls.re_path( + r'^api/ws/', urls.include( + 'tulius.websockets.urls', namespace='websockets')), + ] handler404 = 'tulius.views.error404' diff --git a/tulius/views.py b/tulius/views.py index 6adce32f..efb5d211 100755 --- a/tulius/views.py +++ b/tulius/views.py @@ -12,7 +12,6 @@ from tulius.profile import views as profile_views from tulius.games import models as games -from tulius.websockets import context_processors as websock_context from tulius import celery @@ -57,8 +56,6 @@ class AppSettingsAPI(generic.View): def get(self, request, **kwargs): return http.JsonResponse({ 'debug': settings.DEBUG, - 'websockets_url': websock_context.default( - request, True)['WEBSOCKET_URI'], 'user': profile_views.request_user_json(request), }) @@ -73,6 +70,11 @@ def logic_time(x): class IndexVue(generic.TemplateView): template_name = 'base_vue.html' + def get_context_data(self, **kwargs): + data = super().get_context_data(**kwargs) + data['index_bundle'] = settings.VUE_BUNDLE + return data + class CeleryStatusAPI(generic.View): @staticmethod diff --git a/tulius/websockets/__init__.py b/tulius/websockets/__init__.py index e69de29b..134084d1 100644 --- a/tulius/websockets/__init__.py +++ b/tulius/websockets/__init__.py @@ -0,0 +1,12 @@ +from django.apps import AppConfig + +from tulius.websockets import runserver + + +class WebsocketsConfig(AppConfig): + name = 'tulius.websockets' + label = 'websockets' + verbose_name = 'websockets' + + def ready(self): + runserver.patch() diff --git a/tulius/websockets/app.py b/tulius/websockets/app.py deleted file mode 100644 index 97731500..00000000 --- a/tulius/websockets/app.py +++ /dev/null @@ -1,29 +0,0 @@ -from aiohttp import web -from django.conf import settings - -# from aiohttpdemo_polls.db import close_pg, init_pg -# from aiohttpdemo_polls.middlewares import setup_middlewares - -from tulius.websockets.routes import setup_routes - - -async def init_app(): - app = web.Application() - - # create db connection on startup, shutdown on exit - # app.on_startup.append(init_pg) - # app.on_cleanup.append(close_pg) - - # setup views and routes - setup_routes(app) - - # setup_middlewares(app) - - return app - - -def main(): - app = init_app() - web.run_app(app, - host=settings.ASYNC_SERVER['host'], - port=settings.ASYNC_SERVER['port']) diff --git a/tulius/websockets/asgi/__init__.py b/tulius/websockets/asgi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tulius/websockets/asgi/asgi_handler.py b/tulius/websockets/asgi/asgi_handler.py new file mode 100644 index 00000000..a58887d7 --- /dev/null +++ b/tulius/websockets/asgi/asgi_handler.py @@ -0,0 +1,101 @@ +import django +from django import http +from django.core.handlers import asgi as dj_asgi + + +class HttpResponseUpgrade(http.HttpResponse): + status_code = 101 + + +class ASGITransport: + scope = None + receive = None + send = None + ws = None + + def __init__(self, scope, receive, send): + self.scope = scope + self.receive = receive + self.send = send + + +class ASGIRequest(dj_asgi.ASGIRequest): + asgi = None + scope_type = None + + def __init__(self, transport: ASGITransport, body_file): + self.asgi = transport + # for backward capability. In websocket there is no "method" in scope + if transport.scope['type'] == 'websocket': + transport.scope['method'] = 'GET' + transport.scope.setdefault('method', 'GET') + super().__init__(transport.scope, body_file) + + +class ASGIHandler(dj_asgi.ASGIHandler): + request_class = ASGIRequest + + async def __call__(self, scope, receive, send): + """ + Async entrypoint - parses the request and hands off to get_response. + """ + transport = ASGITransport(scope, receive, send) + if scope['type'] == 'lifespan': + return await self.handle_lifespan(transport) + if scope['type'] not in ['http', 'websocket']: + raise ValueError( + 'Django can only handle ASGI/HTTP connections, not %s.' + % scope['type'] + ) + # Receive the HTTP request body as a stream object. + try: + body_file = await self.read_body(receive) + except dj_asgi.RequestAborted: + return + # Request is complete and can be served. + dj_asgi.set_script_prefix(self.get_script_prefix(scope)) + await dj_asgi.sync_to_async( + dj_asgi.signals.request_started.send, thread_sensitive=True + )(sender=self.__class__, scope=scope) + # Get the request and check for basic issues. + request, error_response = self.create_request(transport, body_file) + if request is None: + await self.send_response(error_response, send) + return + # Get the response, using the async mode of BaseHandler. + response = await self.get_response_async(request) + response._handler_class = self.__class__ + # Increase chunk size on file responses (ASGI servers handles low-level + # chunking). + if isinstance(response, dj_asgi.FileResponse): + response.block_size = self.chunk_size + # Send the response. + await self.send_response(response, send) + + @staticmethod + async def handle_lifespan(transport): + while True: + message = await transport.receive() + if message['type'] == 'lifespan.startup': + # Do some startup here! + await transport.send({'type': 'lifespan.startup.complete'}) + elif message['type'] == 'lifespan.shutdown': + # Do some shutdown here! + await transport.send({'type': 'lifespan.shutdown.complete'}) + + async def send_response(self, response, send): + if isinstance(response, HttpResponseUpgrade): + # websocket view already send reponse, nothing needs to be done. + return + return await super().send_response(response, send) + + +def get_asgi_application(): + """ + The public interface to Django's ASGI support. Return an ASGI 3 callable. + + Avoids making django.core.handlers.ASGIHandler a public API, in case the + internal implementation changes or moves in the future. + """ + django.setup(set_prefix=False) + return ASGIHandler() diff --git a/tulius/websockets/asgi/websocket.py b/tulius/websockets/asgi/websocket.py new file mode 100644 index 00000000..42bf390f --- /dev/null +++ b/tulius/websockets/asgi/websocket.py @@ -0,0 +1,201 @@ +""" +This file is from https://vk.com/@python_django_ru-veb-sokety-v-django-31 + +https://gist.github.com/alex-oleshkevich/ +77a9386cc01c730eccaa45d366bae459#file-connection-py + +""" +import json +import typing as t +import functools + +from django.core import exceptions + +from tulius.websockets.asgi import asgi_handler + + +class State: + CONNECTING = 1 + CONNECTED = 2 + DISCONNECTED = 3 + + +class SendEvent: + """Lists events that application can send. + ACCEPT - Sent by the application when it wishes to accept an incoming + connection. + SEND - Sent by the application to send a data message to the client. + CLOSE - Sent by the application to tell the server to close the connection. + If this is sent before the socket is accepted, the server must close + the connection with a HTTP 403 error code (Forbidden), and not complete + the WebSocket handshake; this may present on some browsers as + a different WebSocket error code (such as 1006, Abnormal Closure). + """ + + ACCEPT = "websocket.accept" + SEND = "websocket.send" + CLOSE = "websocket.close" + + +class ReceiveEvent: + """Enumerates events that application can receive from protocol server. + CONNECT - Sent to the application when the client initially + opens a connection and is about to finish the WebSocket handshake. + This message must be responded to with either an Accept message or a + Close message before the socket will pass websocket.receive messages. + RECEIVE - Sent to the application when a data message is received from the + client. + DISCONNECT - Sent to the application when either connection to the client + is lost, either from the client closing the connection, + the server closing the connection, or loss of the socket. + """ + + CONNECT = "websocket.connect" + RECEIVE = "websocket.receive" + DISCONNECT = "websocket.disconnect" + + +class WebSocket: + def __init__(self, request): + transport = getattr(request, 'asgi', None) + if transport is None: + raise exceptions.ImproperlyConfigured( + 'Recieved websocket request out of ASGI protocol') + if transport.ws: + raise exceptions.ImproperlyConfigured( + 'Websocket connection already created') + if transport.scope['type'] != 'websocket': + raise exceptions.ValidationError( + 'User does not request websocket') + transport.ws = self + self._scope = transport.scope + self._receive = transport.receive + self._send = transport.send + self._state = State.CONNECTING + + async def accept(self, subprotocol: str = None): + """Accept connection. + :param subprotocol: The subprotocol the server wishes to accept. + :type subprotocol: str, optional + """ + await self.send({"type": SendEvent.ACCEPT, "subprotocol": subprotocol}) + + async def close(self, code: int = 1000): + await self.send({"type": SendEvent.CLOSE, "code": code}) + + @property + def closed(self): + return self._state == State.DISCONNECTED + + async def send(self, message: t.Mapping): + if self._state == State.DISCONNECTED: + raise RuntimeError("WebSocket is disconnected.") + + if self._state == State.CONNECTING: + assert message["type"] in {SendEvent.ACCEPT, SendEvent.CLOSE}, ( + 'Could not write event "%s" into socket in connecting state.' + % message["type"] + ) + if message["type"] == SendEvent.CLOSE: + self._state = State.DISCONNECTED + else: + self._state = State.CONNECTED + + elif self._state == State.CONNECTED: + assert message["type"] in {SendEvent.SEND, SendEvent.CLOSE}, ( + 'Connected socket can send "%s" and "%s" events, not "%s"' + % (SendEvent.SEND, SendEvent.CLOSE, message["type"]) + ) + if message["type"] == SendEvent.CLOSE: + self._state = State.DISCONNECTED + + await self._send(message) + + async def receive(self): + if self._state == State.DISCONNECTED: + raise RuntimeError("WebSocket is disconnected.") + + message = await self._receive() + + if self._state == State.CONNECTING: + assert message["type"] == ReceiveEvent.CONNECT, ( + 'WebSocket is in connecting state but received "%s" event' + % message["type"] + ) + self._state = State.CONNECTED + + elif self._state == State.CONNECTED: + assert message["type"] in { + ReceiveEvent.RECEIVE, ReceiveEvent.DISCONNECT}, ( + 'WebSocket is connected but received invalid event "%s".' + % message["type"] + ) + if message["type"] == ReceiveEvent.DISCONNECT: + self._state = State.DISCONNECTED + + return message + + async def receive_json(self) -> t.Any: + message = await self.receive() + if message["type"] == ReceiveEvent.DISCONNECT: + return None + self._test_if_can_receive(message) + return json.loads(message["text"]) + + async def receive_jsonb(self) -> t.Any: + message = await self.receive() + if message["type"] == ReceiveEvent.DISCONNECT: + return None + self._test_if_can_receive(message) + return json.loads(message["bytes"].decode()) + + async def receive_text(self) -> t.Optional[str]: + message = await self.receive() + if message["type"] == ReceiveEvent.DISCONNECT: + return None + self._test_if_can_receive(message) + return message["text"] + + async def receive_bytes(self) -> t.Optional[bytes]: + message = await self.receive() + if message["type"] == ReceiveEvent.DISCONNECT: + return None + self._test_if_can_receive(message) + return message["bytes"] + + async def send_json(self, data: t.Any, **dump_kwargs): + data = json.dumps(data, **dump_kwargs) + await self.send({"type": SendEvent.SEND, "text": data}) + + async def send_jsonb(self, data: t.Any, **dump_kwargs): + data = json.dumps(data, **dump_kwargs) + await self.send({"type": SendEvent.SEND, "bytes": data.encode()}) + + async def send_text(self, text: str): + await self.send({"type": SendEvent.SEND, "text": text}) + + async def send_bytes(self, text: t.Union[str, bytes]): + if isinstance(text, str): + text = text.encode() + await self.send({"type": SendEvent.SEND, "bytes": text}) + + def _test_if_can_receive(self, message: t.Mapping): + assert message["type"] == ReceiveEvent.RECEIVE, ( + 'Invalid message type "%s". Was connection accepted?' % + message["type"] + ) + + +def websocket_view(func): + @functools.wraps(func) + async def wrapper(request, *args, **kwargs): + ws = WebSocket(request) + await ws.accept() + try: + await func(request, ws, *args, **kwargs) + return asgi_handler.HttpResponseUpgrade() + finally: + if not ws.closed: + await ws.close() + wrapper.websocket_wrapper = True + return wrapper diff --git a/tulius/websockets/context_processors.py b/tulius/websockets/context_processors.py deleted file mode 100644 index c581697e..00000000 --- a/tulius/websockets/context_processors.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.conf import settings - - -def default(request, json_format=False): - """ - Adds additional context variables to the default context. - """ - web_url = settings.WEBSOCKET_URL_NEW if json_format \ - else settings.WEBSOCKET_URL - protocol = 'wss://' if request.is_secure() else 'ws://' - if settings.ENV == 'dev': - uri = ''.join([ - protocol, - settings.ASYNC_SERVER['host'], - ':', - str(settings.ASYNC_SERVER['port']), - web_url - ]) - else: - uri = protocol + request.get_host() + web_url - return {'WEBSOCKET_URI': uri} diff --git a/tulius/websockets/routes.py b/tulius/websockets/routes.py index cf71e5fc..9bc83718 100644 --- a/tulius/websockets/routes.py +++ b/tulius/websockets/routes.py @@ -35,11 +35,3 @@ async def handler(self, request, json_format=False): async def json_handler(self, request): return await self.handler(request, json_format=True) - - -def setup_routes(app): - websock_handler = WebsocketHandler() - app.add_routes([ - web.get(settings.WEBSOCKET_URL, websock_handler.handler), - web.get(settings.WEBSOCKET_URL_NEW, websock_handler.json_handler), - ]) diff --git a/tulius/websockets/runserver.py b/tulius/websockets/runserver.py new file mode 100644 index 00000000..ee8aa87a --- /dev/null +++ b/tulius/websockets/runserver.py @@ -0,0 +1,142 @@ +import asyncio +import logging + +from aiohttp import web +from aiohttp.http import WSMsgType +from django.contrib.staticfiles import handlers as static_handlers +from django.core.management.commands import runserver as dj_runserver + +from tulius.websockets.asgi import asgi_handler + +logger = logging.getLogger('django.server') + + +class ASGIRequestHandler: + _response_start = None + _response_body = None + _ws = None + + def __init__(self, request): + self.body_read = False + self.request = request + if request.headers.get('Upgrade') == 'websocket': + connection_type = 'websocket' + else: + connection_type = 'http' + self.scope = { + 'type': connection_type, + 'root_path': '', + 'path': request.path, + 'raw_path': request.raw_path, + 'method': request.method, + 'query_string': request.query_string, + 'client': request._transport_peername, + 'server': ('host', 0), + 'headers': [(n.lower(), v) for n, v in request.raw_headers], + } + + async def receive(self): + if not self.body_read: + self.body_read = True + data = await self.request.read() + if self.scope['type'] == 'websocket': + msg_type = 'websocket.connect' + else: + msg_type = 'body' + return { + 'type': msg_type, + 'body': data, + } + if self._ws is not None: + msg = await self._ws.receive() + if msg.type in ( + WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED): + return {'type': 'websocket.disconnect'} + return { + 'type': 'websocket.receive', + 'text': msg.data, + } + return {'type': 'body end'} + + async def send(self, context): + if context['type'] == 'http.response.start': + self._response_start = context + elif context['type'] == 'http.response.body': + if not self._response_body: + self._response_body = [] + if 'body' in context: + self._response_body.append(context['body']) + elif context['type'] == 'websocket.accept': + self._ws = web.WebSocketResponse() + await self._ws.prepare(self.request) + elif context['type'] == 'websocket.send': + await self._ws.send_str(context['text']) + elif context['type'] == 'websocket.close': + await self._ws.close() + else: + raise NotImplementedError() + + async def handle(self, application): + try: + await application(self.scope, self.receive, self.send) + if self._ws is not None: + return self._ws + return web.Response( + status=self._response_start['status'], + headers=[ + (n.decode('ascii'), v.decode('latin1')) + for n, v in self._response_start['headers']], + body=b''.join(self._response_body) + ) + except Exception as e: + logger.exception(e) + finally: + if self._response_start: + status_code = self._response_start.get('status', 500) + else: + status_code = 500 + if status_code >= 500: + level = logger.error + elif status_code >= 400: + level = logger.warning + else: + level = logger.info + + level('%s %s', self.request.path, status_code) + + +class ASGIServer: + def __init__(self, server_address, handler, ipv6): + self.app = web.Application() + self.asgi_application = asgi_handler.get_asgi_application() + self.server_address = server_address + self.app.add_routes([ + web.get('/{tail:.*}', self.aiohttp_handler), + web.post('/{tail:.*}', self.aiohttp_handler), + web.put('/{tail:.*}', self.aiohttp_handler), + web.options('/{tail:.*}', self.aiohttp_handler), + ]) + + def set_app(self, wsgi_handler): + if isinstance(wsgi_handler, static_handlers.StaticFilesHandler): + self.asgi_application = static_handlers.ASGIStaticFilesHandler( + self.asgi_application + ) + + def serve_forever(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + web.run_app( + self.app, + host=self.server_address[0], + port=self.server_address[1], + print=None, + ) + + async def aiohttp_handler(self, request): + handler = ASGIRequestHandler(request) + return await handler.handle(self.asgi_application) + + +def patch(): + dj_runserver.Command.server_cls = ASGIServer diff --git a/tulius/websockets/urls.py b/tulius/websockets/urls.py new file mode 100644 index 00000000..36714b93 --- /dev/null +++ b/tulius/websockets/urls.py @@ -0,0 +1,13 @@ +from django.conf import urls + +from tulius.websockets import views + + +app_name = 'tulius.websockets' + + +urlpatterns = [ + urls.re_path(r'^$', views.web_socket_view, name='ws'), + urls.re_path( + r'^old/$', views.web_socket_view, {'json_format': False}, name='old'), +] diff --git a/tulius/websockets/user_session.py b/tulius/websockets/user_session.py index f59b1ad5..21b3f7e8 100644 --- a/tulius/websockets/user_session.py +++ b/tulius/websockets/user_session.py @@ -3,11 +3,9 @@ import json import logging -import aiohttp import aioredis from django.conf import settings from django.contrib import auth -from django.contrib.sessions.backends import cached_db from tulius.forum import const as forum_const from tulius.websockets import consts @@ -23,20 +21,16 @@ def __init__(self, request, ws, redis_cache, json_format): self.user_id = None self._redis_cache = redis_cache self.json = json_format + self.user = None def cache_key(self, value): return self._redis_cache.make_key(value) async def auth(self): - session_id = self.request.cookies.get(settings.SESSION_COOKIE_NAME) - if session_id: - session = await self.redis.get( - self.cache_key(cached_db.KEY_PREFIX + session_id)) - if session: - session = self._redis_cache.get_value(session) - if session: - self.user_id = session.get(auth.SESSION_KEY) - # TODO here validation is needed + user = await asyncio.get_event_loop().run_in_executor( + None, functools.partial(auth.get_user, self.request)) + self.user = user + self.user_id = self.user.pk async def _channel_listener_task(self, channel, name, func): async for message in channel.iter(): @@ -108,23 +102,20 @@ async def process(self): await self.subscribe_channel( consts.CHANNEL_USER.format(self.user_id), self.user_channel) - - async for msg in self.ws: - if msg.type == aiohttp.WSMsgType.TEXT: - if msg.data == 'close': - await self.ws.close() - elif msg.data.startswith('{'): - data = json.loads(msg.data) - method = getattr( - self, 'action_' + data.get('action', 'empty'), None) - if method: - await method(data) - else: - await self.ws.send_str(msg.data + '/answer') - elif msg.type == aiohttp.WSMsgType.ERROR: - logger.exception( - 'ws connection closed with exception %s', - self.ws.exception()) + while True: + if self.json: + data = await self.ws.receive_json() + else: + data = await self.ws.receive_text() + if data is None: + break + if self.json: + method = getattr( + self, 'action_' + data.get('action', 'empty'), None) + if method: + await method(data) + else: + await self.ws.send_text(data + '/answer') logger.info('User %s closed', self.user_id) def close(self): diff --git a/tulius/websockets/views.py b/tulius/websockets/views.py new file mode 100644 index 00000000..bebe2c89 --- /dev/null +++ b/tulius/websockets/views.py @@ -0,0 +1,33 @@ +import asyncio +import logging + +import sentry_sdk +from redis_cache import RedisCache +from django.conf import settings +from django.db import transaction + +from tulius.websockets import user_session +from tulius.websockets.asgi import websocket + +params = settings.CACHES['default'].copy() +if params['BACKEND'] != 'redis_cache.RedisCache': + raise NotImplementedError() +redis_location = params.pop('LOCATION') +redis_cache = RedisCache(redis_location, params) + + +@transaction.non_atomic_requests +@websocket.websocket_view +async def web_socket_view(request, ws: websocket.WebSocket, json_format=True): + session = user_session.UserSession( + request, ws, redis_cache, json_format=json_format) + try: + await session.process() + except asyncio.CancelledError: + pass + except Exception as e: + logging.exception(e) + await asyncio.get_event_loop().run_in_executor( + None, sentry_sdk.capture_exception, e) + finally: + session.close() diff --git a/wsgi.py b/wsgi.py deleted file mode 100644 index b6143195..00000000 --- a/wsgi.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -WSGI config for tulius2 project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ -""" - -import os -from django.core.wsgi import get_wsgi_application - -if os.path.exists('settings_production.py'): - settings_file = 'settings_production' -else: - settings_file = 'settings' -os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_file) - -application = get_wsgi_application()