Marta Miranda

Primer commit

  1 +*.log
  2 +
  3 +*.py[codt]
  4 +
  5 +# C extensions
  6 +*.so
  7 +
  8 +# Packages
  9 +*.egg
  10 +*.egg-info
  11 +dist
  12 +build
  13 +eggs
  14 +parts
  15 +bin
  16 +var
  17 +sdist
  18 +develop-eggs
  19 +.installed.cfg
  20 +lib
  21 +lib64
  22 +logs
  23 +
  24 +# Installer logs
  25 +pip-log.txt
  26 +
  27 +# Unit test / coverage reports
  28 +.coverage
  29 +.tox
  30 +nosetests.xml
  31 +coverage.xml
  32 +junit.xml
  33 +
  34 +# Translations
  35 +*.mo
  36 +
  37 +# Mr Developer
  38 +.mr.developer.cfg
  39 +.project
  40 +.pydevproject
  41 +
  42 +# Complexity
  43 +output/*.html
  44 +output/*/index.html
  45 +
  46 +# Sphinx
  47 +docs/_build
  48 +
  49 +.webassets-cache
  50 +
  51 +# Virtualenvs
  52 +venv
  53 +
  54 +# intellij
  55 +*.ipr
  56 +*.iml
  57 +*.iws
  58 +
  59 +# vim
  60 +*.sw[o,p]
  61 +
  62 +.DS_Store
  63 +
  64 +# node
  65 +node_modules/
  66 +
  67 +# bower packages
  68 +.sass-cache/
  69 +.idea/.name
  70 +.idea/scopes/scope_settings.xml
  71 +.idea/encodings.xml
  72 +.idea/workspace.xml
  73 +
  74 +# models
  75 +models.png
  76 +
  77 +.idea/*
  78 +
  79 +*.db
  80 +
  81 +secret.key
  82 +
  83 +.bash_history
  84 +.vagrant/*
  85 +
  86 +# Sublime Text 3
  87 +*.sublime-project
  88 +*.sublime-workspace
  89 +
  90 +# ?
  91 +.cache
  92 +src
  93 +
  94 +# Configuration
  95 +.env
  96 +
  97 +# Virtual Environment
  98 +.venv
  99 +tmp
  100 +Procfile.dev
  101 +
  102 +# Cython .C files (precompilation)
  103 +*.c
  104 +
  105 +__pycache__/
  106 +
  107 +# Logs nginx
  108 +deployment/logs/
  109 +
  110 +.pytest_cache/
  111 +
  112 +project/settings/production.py
  113 +project/static/*
  114 +project/media/*
  1 +[socket:PROJECT-NAME]
  2 +host = 127.0.0.1
  3 +port = 8000
  4 +
  5 +[watcher:PROJECT-NAME]
  6 +cmd = /path/virtualenv/bin/chaussette
  7 +args = --fd $(circus.sockets.PROJECT-NAME) PROJECT-NAME.wsgi.application
  8 +use_sockets = True
  9 +numprocesses = 3
  10 +autostart = True
  11 +
  12 +stdout_stream.class = FileStream
  13 +stdout_stream.filename = /PATH/PROJECT/deployment/logs/circus-stdout.log
  14 +
  15 +stderr_stream.class = FileStream
  16 +stderr_stream.filename = /PATH/PROJECT/deployment/logs/circus-stderr.log
  17 +
  18 +
  19 +[env:PROJECT-NAME]
  20 +PYTHONPATH = /PATH/SOURCE/PROJECT-NAME/
  1 +server {
  2 + listen 80;
  3 + charset utf-8;
  4 + server_name URL-PROJECT-NAME;
  5 + return 301 https://$host$request_uri;
  6 +}
  7 +
  8 +server {
  9 + listen 443;
  10 + charset utf-8;
  11 + server_name URL-PROJECT-NAME;
  12 + client_max_body_size 4G;
  13 +
  14 + ssl on;
  15 + ssl_certificate /etc/letsencrypt/live/URL-PROJECT-NAME/fullchain.pem;
  16 + ssl_certificate_key /etc/letsencrypt/live/URL-PROJECT-NAME/privkey.pem;
  17 +
  18 +
  19 + location /static/ {
  20 + # autoindex off;
  21 + alias /PATH/PROJECT/PROJECT-NAME/static/;
  22 + }
  23 +
  24 + location /media/ {
  25 + # autoindex off;
  26 + alias /PATH/PROJECT/PROJECT-NAME/media/;
  27 + }
  28 +
  29 + location / {
  30 + proxy_pass http://localhost:8000;
  31 + proxy_set_header X-Forwarded-Host $server_name;
  32 + proxy_set_header X-Real-IP $remote_addr;
  33 + proxy_set_header Host $host;
  34 + proxy_set_header X-Scheme $scheme;
  35 + proxy_connect_timeout 600;
  36 + proxy_send_timeout 600;
  37 + proxy_read_timeout 600;
  38 + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  39 + add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
  40 + }
  41 +
  42 + ## Logs
  43 + access_log /PATH/PROJECT/deployment/logs/nginx-access.log;
  44 + error_log /PATH/PROJECT/deployment/logs/nginx-errors.log;
  45 +
  46 +}
  1 +# General settings
  2 +DJANGO_DEBUG=true
  3 +DJANGO_SECRET_KEY=CHANGEME!!!
  4 +DJANGO_ALLOWED_HOSTS=*,127.0.0.1
  5 +
  6 +# Database
  7 +DATABASE_URL=postgres://dbuser:dbpass@localhost:port/mydb
  8 +# SQLite
  9 +# DATABASE_URL=sqlite:///mydb.db
  10 +
  11 +# Security! Better to use DNS for this task, but you can use redirect
  12 +DJANGO_SECURE_SSL_REDIRECT=False
  13 +
  14 +
  15 +# Facebook configuration
  16 +SOCIAL_AUTH_FACEBOOK_KEY=<your app id goes here>
  17 +SOCIAL_AUTH_FACEBOOK_SECRET=<your app secret goes here>
  18 +
  19 +PROJECT_NAME_HEADER=Name Project
  20 +PROJECT_NAME_TITLE=Name Project
  21 +
  22 +ACTIVAR_HERRAMIENTAS_DEBBUGING=false
  1 +#!/usr/bin/env python
  2 +import os
  3 +import sys
  4 +
  5 +if __name__ == "__main__":
  6 + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.base")
  7 + try:
  8 + from django.core.management import execute_from_command_line
  9 + except ImportError as exc:
  10 + raise ImportError(
  11 + "Couldn't import Django. Are you sure it's installed and "
  12 + "available on your PYTHONPATH environment variable? Did you "
  13 + "forget to activate a virtual environment?"
  14 + ) from exc
  15 + execute_from_command_line(sys.argv)
  1 +from django.contrib import admin
  2 +from django.utils import timezone
  3 +from django.utils.translation import gettext as _
  4 +
  5 +from . import filters
  6 +
  7 +
  8 +class PublicadoAdmin(admin.ModelAdmin):
  9 + actions = ['publicar', 'no_publicar']
  10 +
  11 + def publicar(self, request, queryset):
  12 + updated_records = queryset.update(publicado=timezone.now())
  13 + message = _('updated records %s' % updated_records)
  14 + self.message_user(request, message)
  15 +
  16 + publicar.short_description = 'Publicar los registros seleccionados'
  17 +
  18 + def no_publicar(self, request, queryset):
  19 + registros_actualizados = queryset.update(publicado=None)
  20 + mensaje = f'Registros actualizados {registros_actualizados}'
  21 + self.message_user(request, mensaje)
  22 +
  23 + no_publicar.short_description = 'No publicar los registros seleccionados'
  24 +
  25 + def get_list_display(self, request):
  26 + return list(super().get_list_display(request)) + ['publicado']
  27 +
  28 + def get_list_filter(self, request):
  29 + list_filter = [filters.PublicadoListFilter] + list(super().get_list_filter(request))
  30 + return list_filter
  1 +from django.apps import AppConfig
  2 +
  3 +
  4 +class CoreConfig(AppConfig):
  5 + name = 'core'
  1 +from django.contrib import admin
  2 +from django.utils.translation import gettext as _
  3 +
  4 +
  5 +# Filters Admin
  6 +
  7 +class PublicadoListFilter(admin.SimpleListFilter):
  8 + title = 'Publicado'
  9 +
  10 + # Parameter for the filter that will be used in the URL query.
  11 + parameter_name = 'publicado'
  12 +
  13 + def lookups(self, request, model_admin):
  14 + return (
  15 + ('true', 'Publicados'),
  16 + ('false', 'No Publicados'),
  17 + )
  18 +
  19 + def queryset(self, request, queryset):
  20 + value = self.value()
  21 + if value:
  22 + return queryset.exclude(publicado__isnull=value == 'true')
  23 +
  24 + return queryset.all()
  25 +
  26 +
  27 +# DRF Filter Common.
  28 +def filter_unaccent_contains(queryset, name, value):
  29 + # TODO: add unaccent within the join list.
  30 + lookup = '__'.join([name, 'icontains'])
  31 + return queryset.filter(**{lookup: value})
  1 +from django.db import models
  2 +from django.utils import timezone
  3 +
  4 +from .querysets import PublicadoQuerySet
  5 +
  6 +
  7 +class Publicado(models.Model):
  8 + class Meta:
  9 + abstract = True
  10 +
  11 + publicado = models.DateTimeField(blank=True, null=True)
  12 +
  13 + objects = PublicadoQuerySet.as_manager()
  14 +
  15 + def publicar(self, estado=True):
  16 + self.publicado = timezone.now() if estado else None
  17 + self.save(update_fields=('publicado',))
  1 +from django.db.models import QuerySet
  2 +
  3 +
  4 +class PublicadoQuerySet(QuerySet):
  5 + def get_queryset(self):
  6 + return self.filter(publicado__isnull=False)
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
  1 +import json
  2 +
  3 +import pytest
  4 +
  5 +from django.contrib.auth import get_user_model
  6 +from oauth2_provider.models import get_application_model
  7 +from rest_framework.test import APIClient
  8 +
  9 +User = get_user_model()
  10 +
  11 +CONTENT_TYPE_JSON = 'application/json'
  12 +
  13 +
  14 +@pytest.fixture
  15 +def create_user(username, first_name='Admin', last_name='Root', email=None):
  16 + user, created = User.objects.get_or_create(
  17 + username=username,
  18 + email='{}@root.com'.format(username) if email is None else email,
  19 + defaults=dict(
  20 + first_name=first_name,
  21 + last_name=last_name,
  22 + password='password'
  23 + )
  24 + )
  25 +
  26 + return user
  27 +
  28 +
  29 +@pytest.fixture
  30 +def get_default_test_user():
  31 + test_user = create_user(username='test_user', first_name='Test', last_name='User', email='test@user')
  32 + return test_user
  33 +
  34 +
  35 +def get_client_application():
  36 + Application = get_application_model()
  37 + application, _ = Application.objects.get_or_create(
  38 + name='TestApp',
  39 + client_type=Application.CLIENT_CONFIDENTIAL,
  40 + authorization_grant_type=Application.GRANT_CLIENT_CREDENTIALS,
  41 + skip_authorization=True
  42 + )
  43 +
  44 + return application
  45 +
  46 +
  47 +def client_authorized():
  48 + app = get_client_application()
  49 + client = APIClient()
  50 + r = client.post('/oauth2/token/', {
  51 + 'grant_type': 'client_credentials',
  52 + 'client_id': app.client_id,
  53 + 'client_secret': app.client_secret
  54 + })
  55 + response = json.loads(r.content)
  56 + client = APIClient()
  57 + client.credentials(HTTP_AUTHORIZATION='Bearer ' + response['access_token'])
  58 + return client
  1 +import json
  2 +
  3 +from django.contrib.auth import get_user_model
  4 +from rest_framework.test import APIClient
  5 +
  6 +from .fixtures import create_user
  7 +
  8 +JSON_CONTENT_TYPE = "application/json"
  9 +JSON_API_CONTENT_TYPE = "application/vnd.api+json"
  10 +JSON_API_ACCEPT_HEADER = "application/vnd.api+json"
  11 +
  12 +
  13 +def get_authenticated_client(user=None):
  14 + client = APIClient()
  15 + if user is not None:
  16 + client.force_authenticate(user=user)
  17 + return client
  18 +
  19 +
  20 +def get(url, params=None, headers=None, user_logged=None):
  21 + url += "?{}".format(params) if params else ''
  22 + client = get_authenticated_client(user_logged)
  23 + if headers is None:
  24 + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER}
  25 +
  26 + response = client.get(url, **headers)
  27 + return response
  28 +
  29 +
  30 +def post(url, data=None, content_type=JSON_API_CONTENT_TYPE, headers=None, user_logged=None):
  31 + url = url + '/' if not url.endswith('/') else url
  32 + client = get_authenticated_client(user_logged)
  33 + if headers is None:
  34 + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER}
  35 +
  36 + response = client.post(url, data=json.dumps(data), content_type=content_type, **headers)
  37 + return response
  38 +
  39 +
  40 +def patch(url, data=None, content_type=JSON_API_CONTENT_TYPE, headers=None, user_logged=None):
  41 + url = url + '/' if not url.endswith('/') else url
  42 + client = get_authenticated_client(user_logged)
  43 + if headers is None:
  44 + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER}
  45 +
  46 + response = client.patch(url, data=json.dumps(data), content_type=content_type, **headers)
  47 + return response
  48 +
  49 +
  50 +def delete(url, data=None, content_type=JSON_API_CONTENT_TYPE, headers=None, user_logged=None):
  51 + url = url + '/' if not url.endswith('/') else url
  52 + client = get_authenticated_client(user_logged)
  53 + if headers is None:
  54 + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER}
  55 +
  56 + response = client.delete(url, data=json.dumps(data), content_type=content_type, **headers)
  57 + return response
  1 +from django.shortcuts import render
  2 +
  3 +# Create your views here.
  1 +from rest_framework import routers
  2 +
  3 +# Define routes
  4 +router = routers.DefaultRouter()
  1 +import sys
  2 +
  3 +import environ
  4 +
  5 +from django.utils.translation import ugettext_lazy as _
  6 +
  7 +
  8 +ROOT_DIR = environ.Path(__file__) - 3
  9 +PROJECT_DIR = ROOT_DIR.path('project')
  10 +APPS_DIR = PROJECT_DIR.path('apps')
  11 +
  12 +sys.path.insert(0, str(APPS_DIR))
  13 +
  14 +# Load operating system environment variables and then prepare to use them
  15 +env = environ.Env()
  16 +# patch for https://github.com/joke2k/django-environ/issues/119
  17 +env_file = str(ROOT_DIR.path('.env'))
  18 +env.read_env(env_file)
  19 +
  20 +# PROJECT
  21 +PROJECT_NAME_HEADER = env('PROJECT_NAME_HEADER', default='Project Name')
  22 +PROJECT_NAME_TITLE = env('PROJECT_NAME_TITLE', default='Project Name')
  23 +
  24 +# DEBUG
  25 +# ------------------------------------------------------------------------------
  26 +# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
  27 +DEBUG = env.bool('DJANGO_DEBUG', False)
  28 +
  29 +SECRET_KEY = env('DJANGO_SECRET_KEY', default='CHANGEME!!!') # noqa
  30 +ALLOWED_HOSTS = env.list('DJANGO_ALLOWED_HOSTS', default='*') # noqa
  31 +
  32 +DATABASES = {
  33 + 'default': env.db('DATABASE_URL')
  34 +}
  35 +
  36 +
  37 +DJANGO_APPS = (
  38 + 'django.contrib.admin',
  39 + 'django.contrib.auth',
  40 + 'django.contrib.contenttypes',
  41 + 'django.contrib.sessions',
  42 + 'django.contrib.messages',
  43 + 'django.contrib.staticfiles',
  44 +)
  45 +
  46 +THIRD_PARTY_APPS = (
  47 + 'rest_framework',
  48 + 'django_filters',
  49 + 'corsheaders',
  50 +)
  51 +
  52 +PROJECT_APPS = (
  53 + 'core',
  54 +)
  55 +
  56 +INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + PROJECT_APPS
  57 +
  58 +MIDDLEWARE = (
  59 + 'corsheaders.middleware.CorsMiddleware',
  60 + 'django.middleware.security.SecurityMiddleware',
  61 + 'django.contrib.sessions.middleware.SessionMiddleware',
  62 + 'django.middleware.common.CommonMiddleware',
  63 + 'django.middleware.csrf.CsrfViewMiddleware',
  64 + 'django.contrib.auth.middleware.AuthenticationMiddleware',
  65 + 'django.contrib.messages.middleware.MessageMiddleware',
  66 + 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  67 +
  68 +)
  69 +
  70 +ROOT_URLCONF = 'project.urls'
  71 +
  72 +# Python dotted path to the WSGI application used by Django's runserver.
  73 +WSGI_APPLICATION = 'project.wsgi.application'
  74 +
  75 +LANGUAGE_CODE = 'es-ar'
  76 +TIME_ZONE = 'UTC'
  77 +USE_I18N = True
  78 +USE_L10N = True
  79 +USE_TZ = True
  80 +
  81 +LANGUAGES = [
  82 + ('es', _('Español')),
  83 + ('en', _('English')),
  84 +]
  85 +
  86 +# Static files (CSS, JavaScript, Images)
  87 +# https://docs.djangoproject.com/en/1.7/howto/static-files/
  88 +
  89 +STATIC_ROOT = str(PROJECT_DIR.path('static'))
  90 +STATIC_URL = '/static/'
  91 +
  92 +MEDIA_ROOT = str(PROJECT_DIR.path('media'))
  93 +MEDIA_URL = env.str('MEDIA_URL', default='/media/')
  94 +
  95 +CORS_ORIGIN_ALLOW_ALL = True
  96 +
  97 +TEMPLATES = [
  98 + {
  99 + 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  100 + 'DIRS': [str(PROJECT_DIR.path('templates'))],
  101 + 'APP_DIRS': True,
  102 + 'OPTIONS': {
  103 + 'debug': DEBUG,
  104 + 'context_processors': [
  105 + 'django.template.context_processors.debug',
  106 + 'django.template.context_processors.request',
  107 + 'django.contrib.auth.context_processors.auth',
  108 + 'django.contrib.messages.context_processors.messages',
  109 + ],
  110 + },
  111 + },
  112 +]
  113 +
  114 +LOGIN_URL = '/admin/login/'
  115 +
  116 +# Password validation
  117 +# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
  118 +
  119 +AUTH_PASSWORD_VALIDATORS = [
  120 + {
  121 + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
  122 + },
  123 + {
  124 + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
  125 + },
  126 + {
  127 + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
  128 + },
  129 + {
  130 + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
  131 + },
  132 +]
  133 +
  134 +
  135 +AUTHENTICATION_BACKENDS = (
  136 + 'django.contrib.auth.backends.ModelBackend',
  137 +)
  138 +
  139 +
  140 +ACTIVAR_HERRAMIENTAS_DEBBUGING = env.bool('ACTIVAR_HERRAMIENTAS_DEBBUGING', default=False)
  141 +
  142 +if ACTIVAR_HERRAMIENTAS_DEBBUGING:
  143 + INSTALLED_APPS += (
  144 + 'debug_toolbar',
  145 + 'django_extensions',
  146 + )
  147 +
  148 + MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
  1 +from .base import *
  2 +
  3 +SECRET_KEY = 'CHANGEME!!!'
  4 +DEBUG = False
  5 +
  6 +DATABASES = {
  7 + 'default': {
  8 + 'ENGINE': 'django.db.backends.sqlite3',
  9 + 'NAME': ':memory:',
  10 + }
  11 +}
  12 +
  13 +MEDIA_ROOT = str(PROJECT_DIR.path('test_media'))
  1 +"""portal URL Configuration
  2 +
  3 +The `urlpatterns` list routes URLs to views. For more information please see:
  4 + https://docs.djangoproject.com/en/2.0/topics/http/urls/
  5 +Examples:
  6 +Function views
  7 + 1. Add an import: from my_app import views
  8 + 2. Add a URL to urlpatterns: path('', views.home, name='home')
  9 +Class-based views
  10 + 1. Add an import: from other_app.views import Home
  11 + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
  12 +Including another URLconf
  13 + 1. Import the include() function: from django.urls import include, path
  14 + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
  15 +"""
  16 +from django.contrib import admin
  17 +from django.urls import path, include
  18 +from django.conf import settings
  19 +
  20 +from .router import router
  21 +
  22 +# I added platform's name.
  23 +admin.site.site_header = getattr(settings, 'PROJECT_NAME_HEADER')
  24 +admin.site.site_title = getattr(settings, 'PROJECT_NAME_TITLE')
  25 +
  26 +urlpatterns = [
  27 + path('admin/', admin.site.urls),
  28 + path('api/v1/', include(router.urls)),
  29 +]
  1 +"""
  2 +WSGI config for portal project.
  3 +
  4 +It exposes the WSGI callable as a module-level variable named ``application``.
  5 +
  6 +For more information on this file, see
  7 +https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
  8 +"""
  9 +
  10 +import os
  11 +from os.path import abspath, dirname
  12 +from sys import path
  13 +
  14 +from django.core.wsgi import get_wsgi_application
  15 +
  16 +SITE_ROOT = dirname(dirname(abspath(__file__)))
  17 +path.append(SITE_ROOT)
  18 +
  19 +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.base")
  20 +
  21 +application = get_wsgi_application()
  1 +[pytest]
  2 +DJANGO_SETTINGS_MODULE=PROJECTproject-NAME.settings.testing
  3 +norecursedirs = requirements deployment
  4 +testpaths = tests
  5 +addopts = --capture=fd --nomigrations
  1 +# Requeriments base.
  2 +
  3 +Django==3.2.8
  4 +django-cors-headers==3.10.0
  5 +django-filter==21.1
  6 +djangorestframework==3.12.4
  7 +django-environ==0.7.0
  8 +
  9 +
  10 +# database
  11 +psycopg2==2.9.1
  12 +psycopg2-binary==2.7.4
  1 +-r testing.txt
  2 +
  3 +django-extensions==3.1.3
  4 +django-debug-toolbar==3.2.2
  1 +-r base.txt
  2 +
  3 +
  4 +chaussette==1.3.0
  1 +-r base.txt
  2 +
  3 +pytest==6.2.5
  4 +pytest-django==4.4.0