pyazo: restructure to separate Apps

parent 74fdf7a8
......@@ -3,7 +3,7 @@ before_script:
- "python3 -m pip install -U virtualenv"
- "virtualenv env"
- "source env/bin/activate"
- "pip3 install -U -r requirements.txt -r requirements-dev.txt"
- "pip3 install -U -r requirements-dev.txt"
stages:
- test
- build
......
......@@ -9,7 +9,6 @@ RUN apk update && \
apk del openssl-dev libffi-dev libffi-dev build-base py2-pip python2-dev libxml2-dev libxslt-dev libffi-dev gcc musl-dev libgcc openssl-dev curl jpeg-dev zlib-dev freetype-dev lcms2-dev tk-dev tcl-dev && \
adduser -S pyazo
COPY ./allauth_supervisr/ /app/allauth_supervisr/
COPY ./pyazo/ /app/pyazo
COPY ./static/ /app/static
COPY ./manage.py /app/
......
"""supervisr provider"""
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
class SupervisrAccount(ProviderAccount):
"""supervisr account"""
def to_str(self):
dflt = super(SupervisrAccount, self).to_str()
return self.account.extra_data.get('username', dflt)
class SupervisrProvider(OAuth2Provider):
"""supervisr provider"""
id = 'supervisr'
name = 'Supervisr'
account_class = SupervisrAccount
def extract_uid(self, data):
return str(data['sub'])
def extract_common_fields(self, data):
return dict(
email=data.get('email'),
username=data.get('preferred_username'),
name=data.get('name'),
)
def get_default_scope(self):
return ['read']
provider_classes = [SupervisrProvider] # noqa
"""supervisr provider"""
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from allauth_supervisr.provider import SupervisrProvider
urlpatterns = default_urlpatterns(SupervisrProvider)
"""supervisr adapter"""
import requests
from allauth.socialaccount import app_settings
from allauth.socialaccount.providers.oauth2.views import (OAuth2Adapter,
OAuth2CallbackView,
OAuth2LoginView)
from allauth_supervisr.provider import SupervisrProvider
class SupervisrOAuth2Adapter(OAuth2Adapter):
"""supervisr OAuth2 Adapter"""
provider_id = SupervisrProvider.id
settings = app_settings.PROVIDERS.get(provider_id, {}) # noqa
provider_base_url = settings.get("SUPERVISR_URL", 'https://my.beryju.org')
access_token_url = '{0}/app/mod/auth/oauth/provider/token/'.format(provider_base_url)
authorize_url = '{0}/app/mod/auth/oauth/provider/authorize/'.format(provider_base_url)
profile_url = '{0}/api/core/v1/accounts/me/?format=openid'.format(
provider_base_url)
def complete_login(self, request, app, token, **kwargs):
headers = {
'Authorization': 'Bearer {0}'.format(token.token),
'Content-Type': 'application/json',
}
extra_data = requests.get(self.profile_url, headers=headers)
return self.get_provider().sociallogin_from_response(
request,
extra_data.json()
)
oauth2_login = OAuth2LoginView.adapter_view(SupervisrOAuth2Adapter) # noqa
oauth2_callback = OAuth2CallbackView.adapter_view(SupervisrOAuth2Adapter) # noqa
......@@ -25,10 +25,6 @@ external_url: http://image.example.com
# - view_sha512
default_return_view: view_sha256
# Set this to this server's hostname or the external domain if behind a reverse proxy
domains:
- image.example.com
# Set this to true if you only want to use external authentication
external_auth_only: false
......
pyazo /usr/share/pyazo/
allauth_supervisr /usr/share/pyazo/
static /usr/share/pyazo/
manage.py /usr/share/pyazo/
pyazo.sh /usr/share/pyazo/
......
#!/usr/bin/env python
"""
pyazo manage.py
"""
"""pyazo manage.py"""
import os
import sys
......@@ -10,6 +8,6 @@ import pymysql
pymysql.install_as_MySQLdb()
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyazo.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyazo.core.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
"""
pyazo app config
"""
from django.apps import AppConfig
class PyazoConfig(AppConfig):
"""
pyazo main app config
"""
name = 'pyazo'
"""pyazo admin"""
from django.contrib import admin
from pyazo.models import Collection, Upload, UploadView
from pyazo.core.models import Collection, Upload, UploadView
admin.site.register(Upload)
admin.site.register(UploadView)
......
"""pyazo app config"""
from django.apps import AppConfig
class PyazoCoreConfig(AppConfig):
"""pyazo main app config"""
name = 'pyazo.core'
label = 'pyazo_core'
......@@ -12,7 +12,7 @@ from raven.contrib.celery import register_logger_signal, register_signal
pymysql.install_as_MySQLdb()
# set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyazo.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyazo.core.settings")
LOGGER = logging.getLogger(__name__)
......
......@@ -7,7 +7,7 @@ from glob import glob
from django.conf import settings
from django.core.management.base import BaseCommand
from pyazo.models import Upload
from pyazo.core.models import Upload
BUF_SIZE = 65536
LOGGER = logging.getLogger(__name__)
......
......@@ -6,7 +6,7 @@ import cherrypy
from django.conf import settings
from django.core.management.base import BaseCommand
from pyazo.wsgi import application
from pyazo.core.wsgi import application
LOGGER = getLogger(__name__)
......
......@@ -4,7 +4,7 @@ from logging import getLogger
from django.core.management.base import BaseCommand
from pyazo.celery import CELERY_APP
from pyazo.core.celery import CELERY_APP
LOGGER = getLogger(__name__)
......
......@@ -17,6 +17,9 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
options={
'db_table': 'pyazo_upload',
},
name='Upload',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
......@@ -29,6 +32,9 @@ class Migration(migrations.Migration):
],
),
migrations.CreateModel(
options={
'db_table': 'pyazo_uploadview',
},
name='UplodaView',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
......@@ -36,7 +42,7 @@ class Migration(migrations.Migration):
('viewee_dns', models.TextField(blank=True)),
('viewee_date', models.DateTimeField(auto_now_add=True)),
('viewee_user_agent', models.TextField(blank=True)),
('upload', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pyazo.Upload')),
('upload', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pyazo_core.Upload')),
('viewee', models.ForeignKey(blank=True, default=1, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
......
......@@ -8,7 +8,7 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0001_initial'),
('pyazo_core', '0001_initial'),
]
operations = [
......
......@@ -10,7 +10,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0002_auto_20170601_1850'),
('pyazo_core', '0002_auto_20170601_1850'),
]
operations = [
......
......@@ -10,7 +10,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0003_auto_20170928_2121'),
('pyazo_core', '0003_auto_20170928_2121'),
]
operations = [
......
......@@ -10,7 +10,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0004_auto_20171002_1221'),
('pyazo_core', '0004_auto_20171002_1221'),
]
operations = [
......
......@@ -9,11 +9,14 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('pyazo', '0005_auto_20171209_0818'),
('pyazo_core', '0005_auto_20171209_0818'),
]
operations = [
migrations.CreateModel(
options={
'db_table': 'pyazo_collection',
},
name='Collection',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
......@@ -24,7 +27,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='upload',
name='collection',
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pyazo.Collection'),
field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pyazo_core.Collection'),
),
migrations.AlterUniqueTogether(
name='collection',
......
......@@ -6,7 +6,7 @@ from django.db import migrations, models
def update_mime_type(apps, schema_editor):
# set mime_type from file
from pyazo.utils.files import get_mime_type
Upload = apps.get_model('pyazo', 'Upload')
Upload = apps.get_model('pyazo_core', 'Upload')
for upload in Upload.objects.all():
upload.mime_type = get_mime_type(upload.file.name)
upload.save()
......@@ -14,7 +14,7 @@ def update_mime_type(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0006_auto_20181009_1450'),
('pyazo_core', '0006_auto_20181009_1450'),
]
operations = [
......
......@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0007_upload_mime_type'),
('pyazo_core', '0007_upload_mime_type'),
]
operations = [
......
......@@ -6,7 +6,7 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0008_upload_thumbmail'),
('pyazo_core', '0008_upload_thumbmail'),
]
operations = [
......
......@@ -6,7 +6,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0009_remove_upload_type'),
('pyazo_core', '0009_remove_upload_type'),
]
operations = [
......
......@@ -7,13 +7,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0010_auto_20181011_1854'),
('pyazo_core', '0010_auto_20181011_1854'),
]
operations = [
migrations.AlterField(
model_name='upload',
name='collection',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pyazo.Collection'),
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pyazo_core.Collection'),
),
]
......@@ -8,7 +8,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pyazo', '0011_auto_20181011_1900'),
('pyazo_core', '0011_auto_20181011_1900'),
]
operations = [
......
# Generated by Django 2.1.4 on 2018-12-21 18:41
from django.db import migrations
class Migration(migrations.Migration):
atomic = False
dependencies = [
('pyazo_core', '0012_auto_20181117_1158'),
]
operations = [
migrations.AlterModelTable(
name='collection',
table=None,
),
migrations.AlterModelTable(
name='upload',
table=None,
),
migrations.AlterModelTable(
name='uploadview',
table=None,
),
]
......@@ -13,6 +13,7 @@ https://docs.djangoproject.com/en/1.11/ref/settings/
import logging
import os
import sys
from urllib.parse import urlparse
from pyazo import __version__
from pyazo.utils.config import CONFIG
......@@ -21,28 +22,10 @@ LOGGER = logging.getLogger(__name__)
# This is the base url used for image URLs
EXTERNAL_URL = CONFIG.get('external_url')
# This dictates how the Path is generated
# can be either of:
# - view_sha512_short
# - view_md5
# - view_sha256
# - view_sha512
DEFAULT_RETURN_VIEW = CONFIG.get('default_return_view')
# Set this to true if you only want to use external authentication
EXTERNAL_AUTH_ONLY = CONFIG.get('external_auth_only')
# If this is true, images are automatically claimed if the windows user exists
# in django
AUTO_CLAIM_ENABLED = CONFIG.get('auto_claim_enabled')
SECURE_PROXY_SSL_HEADER = tuple(CONFIG.get('secure_proxy_header', {}).items())[0]
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = CONFIG.get('secret_key',
......@@ -51,7 +34,8 @@ SECRET_KEY = CONFIG.get('secret_key',
DEBUG = CONFIG.get('debug')
CORS_ORIGIN_ALLOW_ALL = DEBUG
ALLOWED_HOSTS = CONFIG.get('domains', [])
# config's external_url is a full URL, so we have to parse it to get the host
ALLOWED_HOSTS = [urlparse(CONFIG.get('external_url')).netloc]
LOGIN_REDIRECT_URL = 'index'
# Application definition
......@@ -81,8 +65,20 @@ CELERY_CREATE_MISSING_QUEUES = True
CELERY_TASK_DEFAULT_QUEUE = 'pyazo'
CELERY_BROKER_URL = 'redis://%s' % CONFIG.get('redis')
CELERY_RESULT_BACKEND = 'redis://%s' % CONFIG.get('redis')
CELERY_IMPORTS = ('pyazo.tasks', )
CELERY_IMPORTS = ('pyazo.core.tasks', )
# Influxdb settings
# with CONFIG.cd('influx'):
# INFLUXDB_DISABLED = not CONFIG.get('enabled')
# INFLUXDB_HOST = CONFIG.get('host')
# INFLUXDB_PORT = CONFIG.get('port')
# INFLUXDB_USER = CONFIG.get('user')
# INFLUXDB_PASSWORD = CONFIG.get('password')
# INFLUXDB_DATABASE = CONFIG.get('database')
# INFLUXDB_TIMEOUT = 5
# INFLUXDB_USE_CELERY = True
ACCOUNT_EMAIL_VERIFICATION = 'none'
with CONFIG.cd('web'):
CHERRYPY_SERVER = {
......@@ -105,11 +101,9 @@ INSTALLED_APPS = [
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth_supervisr',
'pyazo',
'allauth_passbook',
'pyazo.core.apps.PyazoCoreConfig',
'raven.contrib.django.raven_compat',
'oauth2_provider',
'corsheaders',
]
AUTHENTICATION_BACKENDS = (
......@@ -129,7 +123,7 @@ MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
]
ROOT_URLCONF = 'pyazo.urls'
ROOT_URLCONF = 'pyazo.core.urls'
TEMPLATES = [
{
......@@ -149,7 +143,7 @@ TEMPLATES = [
VERSION = __version__
WSGI_APPLICATION = 'pyazo.wsgi.application'
WSGI_APPLICATION = 'pyazo.core.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
......@@ -214,7 +208,7 @@ RAVEN_CONFIG = {
'3372ecce5d548a5@sentry.services.beryju.org/4',
'release': VERSION,
'environment': 'production' if DEBUG is False else 'development',
'tags': {'site': EXTERNAL_URL}
'tags': {'site': CONFIG.get('external_url')}
}
ERROR_REPORT_ENABLED = CONFIG.get('error_report_enabled', False)
......
......@@ -6,8 +6,8 @@ from django.conf import settings
from django.shortcuts import get_object_or_404
from PIL import Image
from pyazo.celery import CELERY_APP
from pyazo.models import Upload
from pyazo.core.celery import CELERY_APP
from pyazo.core.models import Upload
from pyazo.utils.files import generate_ext_thumb
LOGGER = getLogger(__name__)
......
......@@ -4,7 +4,7 @@ from urllib.parse import urlparse
from django import template
from pyazo.models import Collection
from pyazo.core.models import Collection
register = template.Library()
......@@ -13,7 +13,9 @@ register = template.Library()
def collections(context):
"""Return User's Collections"""
request = context['request']
return Collection.objects.filter(owner=request.user)
if request.user.is_authenticated:
return Collection.objects.filter(owner=request.user)
return []
@register.filter('fieldtype')
......
......@@ -3,7 +3,7 @@ from django.contrib.auth.models import User
from django.shortcuts import reverse
from django.test import TestCase
from pyazo.tests.utils import test_auth
from pyazo.core.tests.utils import test_auth
class AccountViewTests(TestCase):
......
......@@ -3,8 +3,8 @@ from django.contrib.auth.models import User
from django.shortcuts import reverse
from django.test import TestCase
from pyazo.models import Collection
from pyazo.tests.utils import test_auth
from pyazo.core.models import Collection
from pyazo.core.tests.utils import test_auth
class CoreViewTests(TestCase):
......
......@@ -5,7 +5,7 @@ from django.conf import settings
from django.shortcuts import reverse
from django.test import TestCase
from pyazo.tests.utils import test_auth
from pyazo.core.tests.utils import test_auth
class DownloadViewTests(TestCase):
......
......@@ -4,9 +4,9 @@ import os
from django.conf import settings
from django.test import TestCase
from pyazo.management.commands.reindex import Command as ReindexCommand
from pyazo.models import Upload
from pyazo.tests.utils import call_command_ret
from pyazo.core.management.commands.reindex import Command as ReindexCommand
from pyazo.core.models import Upload
from pyazo.core.tests.utils import call_command_ret
class ManagementTests(TestCase):
......
......@@ -5,8 +5,8 @@ import os
from django.conf import settings
from django.test import TestCase
from pyazo.models import Upload
from pyazo.tasks import make_thumbnail
from pyazo.core.models import Upload
from pyazo.core.tasks import make_thumbnail
class TaskTests(TestCase):
......
......@@ -2,7 +2,7 @@
from django.shortcuts import reverse
from django.test import RequestFactory, TestCase
from pyazo.templatetags.pyazo import back
from pyazo.core.templatetags.pyazo import back