From 4317b0ba5d614fb6f9f3d3ee333848e9774700ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs?= Date: Thu, 13 Jan 2022 18:08:28 -0500 Subject: Add docker support --- django/Dockerfile | 47 ++++++++ django/core/__init__.py | 0 django/core/admin.py | 3 + django/core/apps.py | 5 + django/core/models.py | 3 + django/core/templates/core/base.djhtml | 52 +++++++++ django/core/tests.py | 3 + django/core/views.py | 3 + django/entrypoint.sh | 161 ++++++++++++++++++++++++++ django/manage.py | 15 +++ django/nginx.conf | 25 ++++ django/personalsite/__init__.py | 0 django/personalsite/settings.py.example | 143 +++++++++++++++++++++++ django/personalsite/urls.py | 36 ++++++ django/personalsite/wsgi.py | 16 +++ django/project/__init__.py | 0 django/project/admin.py | 9 ++ django/project/apps.py | 6 + django/project/forms.py | 30 +++++ django/project/migrations/__init__.py | 0 django/project/models.py | 33 ++++++ django/project/templates/trabajo/index.djhtml | 154 ++++++++++++++++++++++++ django/project/tests.py | 3 + django/project/urls.py | 7 ++ django/project/views.py | 45 +++++++ django/requirements.txt | 5 + django/requirements_prod.txt | 5 + django/social/__init__.py | 0 django/social/admin.py | 17 +++ django/social/apps.py | 6 + django/social/migrations/__init__.py | 0 django/social/models.py | 34 ++++++ django/social/processors.py | 9 ++ django/social/tests.py | 3 + django/social/views.py | 3 + 35 files changed, 881 insertions(+) create mode 100644 django/Dockerfile create mode 100644 django/core/__init__.py create mode 100644 django/core/admin.py create mode 100644 django/core/apps.py create mode 100644 django/core/models.py create mode 100644 django/core/templates/core/base.djhtml create mode 100644 django/core/tests.py create mode 100644 django/core/views.py create mode 100644 django/entrypoint.sh create mode 100644 django/manage.py create mode 100644 django/nginx.conf create mode 100644 django/personalsite/__init__.py create mode 100644 django/personalsite/settings.py.example create mode 100644 django/personalsite/urls.py create mode 100644 django/personalsite/wsgi.py create mode 100644 django/project/__init__.py create mode 100644 django/project/admin.py create mode 100644 django/project/apps.py create mode 100644 django/project/forms.py create mode 100644 django/project/migrations/__init__.py create mode 100644 django/project/models.py create mode 100644 django/project/templates/trabajo/index.djhtml create mode 100644 django/project/tests.py create mode 100644 django/project/urls.py create mode 100644 django/project/views.py create mode 100644 django/requirements.txt create mode 100644 django/requirements_prod.txt create mode 100644 django/social/__init__.py create mode 100644 django/social/admin.py create mode 100644 django/social/apps.py create mode 100644 django/social/migrations/__init__.py create mode 100644 django/social/models.py create mode 100644 django/social/processors.py create mode 100644 django/social/tests.py create mode 100644 django/social/views.py (limited to 'django') diff --git a/django/Dockerfile b/django/Dockerfile new file mode 100644 index 0000000..18b68ed --- /dev/null +++ b/django/Dockerfile @@ -0,0 +1,47 @@ +FROM python:3-alpine AS base +LABEL MAINTAINER="heckyel@riseup.net" + +# Image to Build Dependencies +FROM base AS builder + +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 + +RUN apk add --no-cache musl-dev build-base make gcc g++ \ + libxml2-dev libffi-dev zlib-dev libjpeg lcms2-dev libimagequant-dev \ + libjpeg-turbo-dev libwebp-dev openjpeg-dev tk-dev py3-pillow + +ARG APP_DIR="/srv/app" + +RUN mkdir --parents "$APP_DIR" + +WORKDIR "$APP_DIR" + +COPY requirements_prod.txt . +RUN pip install --no-cache-dir --prefix=/install wheel gunicorn +RUN pip install --no-cache-dir --prefix=/install -r requirements_prod.txt + +# Runtime Environment Image +FROM base + +WORKDIR /srv/app + +# Runtime Dependencies +RUN apk add py3-olefile brotli-libs libpng freetype libxcb \ + libimagequant libjpeg-turbo lcms2 openjpeg libwebp zstd-libs \ + tiff libxau libmd libbsd libxdmcp nginx + +COPY --from=builder /install /usr/local +COPY core/ /srv/app/core +COPY personalsite/ /srv/app/personalsite +COPY project/ /srv/app/project +COPY social/ /srv/app/social +COPY manage.py /srv/app +COPY nginx.conf /etc/nginx/http.d/default.conf + +EXPOSE 80 + +COPY entrypoint.sh / +RUN chmod u+x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/django/core/__init__.py b/django/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/core/admin.py b/django/core/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/django/core/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/django/core/apps.py b/django/core/apps.py new file mode 100644 index 0000000..26f78a8 --- /dev/null +++ b/django/core/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + name = 'core' diff --git a/django/core/models.py b/django/core/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/django/core/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/django/core/templates/core/base.djhtml b/django/core/templates/core/base.djhtml new file mode 100644 index 0000000..ffddace --- /dev/null +++ b/django/core/templates/core/base.djhtml @@ -0,0 +1,52 @@ + + + + + + Sitio personal de Jesús + + + + {% load static %} + + + + + + +
+
+ +
+
+

Jesús

+

Desarrollador

+
+
+
+
+ + +
+ {% block content %}{% endblock %} +
+ + {% block footer %} + + {% block contacto %}{% endblock %} + + {% endblock %} + + + + diff --git a/django/core/tests.py b/django/core/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/django/core/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django/core/views.py b/django/core/views.py new file mode 100644 index 0000000..ad8747b --- /dev/null +++ b/django/core/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render, HttpResponse + +# Create your views here. diff --git a/django/entrypoint.sh b/django/entrypoint.sh new file mode 100644 index 0000000..12edeca --- /dev/null +++ b/django/entrypoint.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env sh + +## Config +if [ ! -f "/srv/app/personalsite/settings.py" ]; then + # generate config + cat > /srv/app/personalsite/settings.py <<- EOF +""" +Django settings for personalsite project. + +Generated by 'django-admin startproject' using Django 2.1.2. + +For more information on this file, see +https://docs.djangoproject.com/en/2.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.1/ref/settings/ +""" + +import os + +# 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/2.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '${SECRET_KEY:-8$oylik7o2-dbx+5a77=2a532w8lx&=ofiyv!1bs9a9)0t%6r2}' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = ${APP_DEBUG:-False} + +ALLOWED_HOSTS = ["${WEB_SITE_URL:-example.com}", "localhost", "127.0.0.1", "0.0.0.0", "django"] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'core', + 'project.apps.ProjectConfig', + 'social.apps.SocialConfig', + 'django_cleanup.apps.CleanupConfig', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'personalsite.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'social.processors.ctx_dict', + ], + }, + }, +] + +WSGI_APPLICATION = 'personalsite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': '${NAME_DB:-site}', + 'USER': '${USER_DB:-site}', + 'PASSWORD': '${PASS_DB:-site}', + 'HOST': '${HOST_DB:-127.0.0.1}', + 'PORT': '${PORT_DB:-5432}', + } +} + +# Password validation +# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.1/topics/i18n/ + +LANGUAGE_CODE = 'es' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.1/howto/static-files/ + +STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') + +# Media files +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +# Incoming Email +EMAIL_FROM = '${EMAIL_FROM:-noreply@example.com}' +EMAIL_TO = '${EMAIL_TO:-user@example.com}' + +# Email config +EMAIL_HOST = '${EMAIL_HOST:-smtp.example.com}' +EMAIL_HOST_USER = '${EMAIL_HOST_USER:-username}' +EMAIL_HOST_PASSWORD = '${EMAIL_HOST_PASSWORD:-password}' +EMAIL_PORT = '${EMAIL_HOST_PORT:-587}' +EMAIL_USE_TLS = ${EMAIL_USE_TLS:-True} +EOF +fi + +cd /srv/app || exit +/usr/local/bin/python3 manage.py makemigrations --no-input +/usr/local/bin/python3 manage.py migrate --no-input +/usr/local/bin/python3 manage.py collectstatic --no-input + +gunicorn -b "0.0.0.0:${GUNICORN_PORT_NUMBER:-8080}" --timeout "${GUNICORN_TIMEOUT:-30}" --workers "${GUNICORN_NUM_WORKERS:-4}" personalsite.wsgi & +exec nginx -g "daemon off;" diff --git a/django/manage.py b/django/manage.py new file mode 100644 index 0000000..fe7cda5 --- /dev/null +++ b/django/manage.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == '__main__': + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'personalsite.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) diff --git a/django/nginx.conf b/django/nginx.conf new file mode 100644 index 0000000..2bf6930 --- /dev/null +++ b/django/nginx.conf @@ -0,0 +1,25 @@ +upstream django { + server 127.0.0.1:8080; +} + +server { + listen 80; + + access_log /dev/null; + error_log /dev/null; + + location / { + proxy_pass http://django; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + } + location /static/ { + autoindex on; + alias /srv/app/static/; + } + location /media/ { + autoindex on; + alias /srv/app/media/; + } +} diff --git a/django/personalsite/__init__.py b/django/personalsite/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/personalsite/settings.py.example b/django/personalsite/settings.py.example new file mode 100644 index 0000000..12f22f8 --- /dev/null +++ b/django/personalsite/settings.py.example @@ -0,0 +1,143 @@ +""" +Django settings for personalsite project. + +Generated by 'django-admin startproject' using Django 2.1.2. + +For more information on this file, see +https://docs.djangoproject.com/en/2.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.1/ref/settings/ +""" + +import os + +# 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/2.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '8$oylik7o2-dbx+5a77=2a532w8lx&=ofiyv!1bs9a9)0t%6r)' + +# SECURITY WARNING: don't run with debug turned on in production! +# DEBUG = False +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'core', + 'project.apps.ProjectConfig', + 'social.apps.SocialConfig', + 'django_cleanup.apps.CleanupConfig', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'personalsite.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'social.processors.ctx_dict', + ], + }, + }, +] + +WSGI_APPLICATION = 'personalsite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.1/topics/i18n/ + +LANGUAGE_CODE = 'es' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.1/howto/static-files/ + +STATIC_URL = '/static/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'static') + +# Media files +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +# Incoming Email +EMAIL_FROM = 'noreply@example.com' +EMAIL_TO = 'user@example.com' + +# Email config +EMAIL_HOST = 'smtp.example.com' +EMAIL_HOST_USER = 'username' +EMAIL_HOST_PASSWORD = 'pass' +EMAIL_PORT = '587' +EMAIL_USE_TLS = True diff --git a/django/personalsite/urls.py b/django/personalsite/urls.py new file mode 100644 index 0000000..f964f4b --- /dev/null +++ b/django/personalsite/urls.py @@ -0,0 +1,36 @@ +"""personalsite URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +from django.conf import settings + +urlpatterns = [ + path('', include('project.urls')), + path('admin/', admin.site.urls), +] + +if settings.DEBUG: + from django.conf.urls.static import static + urlpatterns += static( + settings.MEDIA_URL, + document_root=settings.MEDIA_ROOT + ) + +# Custom titles for admin +admin.site.site_header = 'Personal Site' +admin.site.site_title = 'Personal Site' +admin.site.index_title = 'Panel de administrador' diff --git a/django/personalsite/wsgi.py b/django/personalsite/wsgi.py new file mode 100644 index 0000000..c239385 --- /dev/null +++ b/django/personalsite/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for personalsite 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/2.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'personalsite.settings') + +application = get_wsgi_application() diff --git a/django/project/__init__.py b/django/project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/project/admin.py b/django/project/admin.py new file mode 100644 index 0000000..661a9e6 --- /dev/null +++ b/django/project/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin +from .models import Project + + +class ProjectAdmin(admin.ModelAdmin): + readonly_fields = ('created', 'updated',) + + +admin.site.register(Project, ProjectAdmin) diff --git a/django/project/apps.py b/django/project/apps.py new file mode 100644 index 0000000..cd51a76 --- /dev/null +++ b/django/project/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ProjectConfig(AppConfig): + name = 'project' + verbose_name = 'Proyectos' diff --git a/django/project/forms.py b/django/project/forms.py new file mode 100644 index 0000000..54cc5a5 --- /dev/null +++ b/django/project/forms.py @@ -0,0 +1,30 @@ +from django import forms + + +class ContactForm(forms.Form): + name = forms.CharField( + label="Nombre", + required=True, + widget=forms.TextInput( + attrs={'placeholder': 'Nombre'} + ), + min_length=3, + max_length=100) + + email = forms.EmailField( + label="Email", + required=True, + widget=forms.EmailInput( + attrs={'placeholder': 'user@page.domain'} + ), + min_length=3, + max_length=100) + + content = forms.CharField( + label="Mensaje", + required=True, + widget=forms.Textarea( + attrs={'placeholder': 'Mensaje'} + ), + min_length=10, + max_length=1000) diff --git a/django/project/migrations/__init__.py b/django/project/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/project/models.py b/django/project/models.py new file mode 100644 index 0000000..1125957 --- /dev/null +++ b/django/project/models.py @@ -0,0 +1,33 @@ +from django.db import models + + +class Project(models.Model): + title = models.CharField( + max_length=200, verbose_name='Titulo') + + decription = models.TextField( + verbose_name='Descripción') + + image = models.ImageField( + verbose_name='Imagen', + upload_to='projects/uploads/%Y/%m/%d/') + + link = models.URLField( + null=True, blank=True, + verbose_name='Sitio web') + + created = models.DateTimeField( + auto_now_add=True, + verbose_name='Fecha de creación') + + updated = models.DateTimeField( + auto_now=True, + verbose_name='Fecha de modificación') + + class Meta: + verbose_name = 'proyecto' + verbose_name_plural = 'proyectos' + ordering = ["-created"] + + def __str__(self): + return self.title diff --git a/django/project/templates/trabajo/index.djhtml b/django/project/templates/trabajo/index.djhtml new file mode 100644 index 0000000..eb7ddd4 --- /dev/null +++ b/django/project/templates/trabajo/index.djhtml @@ -0,0 +1,154 @@ +{% extends 'core/base.djhtml' %} + +{% load static %} + +{% block content %} +
+
+
+ Jesús Eduardo +
+
+

Acerca de

+

Consultor y desarrollador de Software Libre. Hacker de Hyperbola GNU/Linux-Libre.

+
+
+
+ + +
+
+

Proyectos

+
+ + {% for project in projects %} +
+
+ {{project.title}} +
+
+

+ {% if project.link %} + {{project.title}} + {% endif %} +

+

{{project.decription}}

+
+
+ {% endfor %} + +
+
+
+{% endblock %} + + +{% block footer %} + +{% endblock %} diff --git a/django/project/tests.py b/django/project/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/django/project/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django/project/urls.py b/django/project/urls.py new file mode 100644 index 0000000..52e75fe --- /dev/null +++ b/django/project/urls.py @@ -0,0 +1,7 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.home, name="home"), + # path('filename', views.i2pfile, name='i2pfile'), +] diff --git a/django/project/views.py b/django/project/views.py new file mode 100644 index 0000000..d4d7f93 --- /dev/null +++ b/django/project/views.py @@ -0,0 +1,45 @@ +from django.shortcuts import render, redirect +from django.urls import reverse +from django.core.mail import EmailMessage +from .models import Project +from .forms import ContactForm +from personalsite.settings import ( + EMAIL_FROM, + EMAIL_TO +) + + +def home(request): + projects = Project.objects.all() + + # Form + contact_form = ContactForm() + if request.method == "POST": + contact_form = ContactForm(data=request.POST) + if contact_form.is_valid(): + name = request.POST.get('name', '') + email = request.POST.get('email', '') + content = request.POST.get('content', '') + # Send Email + msg = EmailMessage( + "Personal-Site: Nuevo mensaje", + "De {} <{}>\n\nEscribió:\n\n{}".format(name, email, content), + EMAIL_FROM, + [EMAIL_TO], + reply_to=[email], + ) + try: + msg.send(fail_silently=False) + # ok + return redirect(reverse('home')+"?ok") + except: + # Fail + return redirect(reverse('home')+"?fail") + # EndForm + + return render(request, 'trabajo/index.djhtml', + {'projects': projects, 'form': contact_form}) + + +# def i2pfile(request): +# return render(request, 'trabajo/filename') diff --git a/django/requirements.txt b/django/requirements.txt new file mode 100644 index 0000000..7200434 --- /dev/null +++ b/django/requirements.txt @@ -0,0 +1,5 @@ +Django==2.2.16 +django-cleanup==5.0.0 +Pillow==9.0.0 +pytz==2018.9 +sqlparse==0.3.1 diff --git a/django/requirements_prod.txt b/django/requirements_prod.txt new file mode 100644 index 0000000..7072840 --- /dev/null +++ b/django/requirements_prod.txt @@ -0,0 +1,5 @@ +Django==2.2.16 +django-cleanup==5.0.0 +Pillow==8.4.0 +psycopg2-binary +pytz diff --git a/django/social/__init__.py b/django/social/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/social/admin.py b/django/social/admin.py new file mode 100644 index 0000000..3084240 --- /dev/null +++ b/django/social/admin.py @@ -0,0 +1,17 @@ +from django.contrib import admin +from .models import Link + + +# Register your models here. + +class LinkAdmin(admin.ModelAdmin): + readonly_fields = ('created', 'updated') + + def get_readonly_fields(self, request, obj=None): + if request.user.groups.filter(name='Personal').exists(): + return ('key', 'name') + else: + return ('created', 'updated') + + +admin.site.register(Link, LinkAdmin) diff --git a/django/social/apps.py b/django/social/apps.py new file mode 100644 index 0000000..77d553d --- /dev/null +++ b/django/social/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class SocialConfig(AppConfig): + name = 'social' + verbose_name = "Redes Sociales" diff --git a/django/social/migrations/__init__.py b/django/social/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/social/models.py b/django/social/models.py new file mode 100644 index 0000000..c693015 --- /dev/null +++ b/django/social/models.py @@ -0,0 +1,34 @@ +from django.db import models + + +class Link(models.Model): + key = models.SlugField( + verbose_name="Nombre clave", + max_length=100, + unique=True) + + name = models.CharField( + verbose_name="Red social", + max_length=200) + + url = models.URLField( + verbose_name="Enlace", + max_length=200, + null=True, + blank=True) + + created = models.DateTimeField( + auto_now_add=True, + verbose_name='Fecha de creación') + + updated = models.DateTimeField( + auto_now=True, + verbose_name='Fecha de modificación') + + class Meta: + verbose_name = 'enlace' + verbose_name_plural = 'enlaces' + ordering = ["name"] + + def __str__(self): + return self.name diff --git a/django/social/processors.py b/django/social/processors.py new file mode 100644 index 0000000..0c3eb68 --- /dev/null +++ b/django/social/processors.py @@ -0,0 +1,9 @@ +from .models import Link + + +def ctx_dict(request): + ctx = {} + links = Link.objects.all() + for link in links: + ctx[link.key] = link.url + return ctx diff --git a/django/social/tests.py b/django/social/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/django/social/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django/social/views.py b/django/social/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/django/social/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. -- cgit v1.2.3