This commit is contained in:
2017-12-12 13:15:45 +03:00
parent 90e9a158cd
commit 596d9e0358
19 changed files with 573 additions and 557 deletions

1
Procfile Normal file
View File

@ -0,0 +1 @@
web: gunicorn mysite.wsgi --log-file -

View File

@ -1,33 +1,33 @@
import os import os
# Return file string and filename # Return file string and filename
def get_file_from_request(request, fieldname): def get_file_from_request(request, fieldname):
file_l = '' file_l = ''
for i in request.FILES[fieldname]: for i in request.FILES[fieldname]:
file_l = file_l + i file_l = file_l + i
return file_l, str(request.FILES[fieldname]) return file_l, str(request.FILES[fieldname])
# Write file to /dev/shm and return ar handler # Write file to /dev/shm and return ar handler
def write_to_shm(file, name): def write_to_shm(file, name):
f = open('/dev/shm/' + name, 'w') f = open('/dev/shm/' + name, 'w')
f.write(file) f.write(file)
f.close() f.close()
return '/dev/shm/' + name return '/dev/shm/' + name
# Remove file from /dev/shm # Remove file from /dev/shm
def rm_from_shm(name): def rm_from_shm(name):
try: try:
os.remove('/dev/shm/' + name) os.remove('/dev/shm/' + name)
return True return True
except Exception as e: except Exception as e:
return str(e) return str(e)
# Split filename # Split filename
def split_file(filename): def split_file(filename):
pass pass

View File

@ -1,12 +1,12 @@
from PIL import Image from PIL import Image
def resize_image(fh, img_prop): def resize_image(fh, img_prop):
im = Image.open(fh) im = Image.open(fh)
# size = 100, 100 # size = 100, 100
im.thumbnail(img_prop['size']) im.thumbnail(img_prop['size'])
print(img_prop['size']) #print(img_prop['size'])
# im.thumbnail(size) # im.thumbnail(size)
thumb_name = img_prop['dest'] + '/thumb_' + img_prop['name'] thumb_name = img_prop['dest'] + '/thumb_' + img_prop['name']
im.save(thumb_name) im.save(thumb_name)
return thumb_name return thumb_name

View File

@ -1,139 +1,150 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Django settings for mysite project. Django settings for mysite project.
Generated by 'django-admin startproject' using Django 1.9.7. Generated by 'django-admin startproject' using Django 1.9.7.
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/1.9/topics/settings/ https://docs.djangoproject.com/en/1.9/topics/settings/
For the full list of settings and their values, see For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.9/ref/settings/ https://docs.djangoproject.com/en/1.9/ref/settings/
""" """
import os import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '1a+3jmf#g!q_gj66$^v9_&8uoev=%k49=j(%lp%!kvv$6x3bn^' SECRET_KEY = '1a+3jmf#g!q_gj66$^v9_&8uoev=%k49=j(%lp%!kvv$6x3bn^'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ["imgcollection.herokuapp.com",]
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'imagehosting', 'imagehosting',
'taggit' #'taggit'
] ]
MIDDLEWARE_CLASSES = [ MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
ROOT_URLCONF = 'imagehosting.urls' ROOT_URLCONF = 'imagehosting.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [], 'DIRS': [],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
'django.template.context_processors.debug', 'django.template.context_processors.debug',
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
], ],
}, },
}, },
] ]
WSGI_APPLICATION = 'imagehost.wsgi.application' WSGI_APPLICATION = 'imagehost.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases # https://docs.djangoproject.com/en/1.9/ref/settings/#databases
'''
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, '../db.sqlite3'), 'NAME': os.path.join(BASE_DIR, '../db.sqlite3'),
} }
} }
'''
# Password validation DATABASES = {
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
AUTH_PASSWORD_VALIDATORS = [ 'NAME': 'ddg4djbee66kal',
{ 'USER': 'jrowflkieuofex',
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 'PASSWORD': 'ec999abac6adefb9876d38458e3aad38c009ebeb78be01783c5a48268e10f04a',
}, 'HOST': 'ec2-54-247-82-87.eu-west-1.compute.amazonaws.com',
{ 'PORT': '5432',
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }
}, }
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', # Password validation
}, # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', AUTH_PASSWORD_VALIDATORS = [
}, {
] 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
# Internationalization 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
# https://docs.djangoproject.com/en/1.9/topics/i18n/ },
{
LANGUAGE_CODE = 'ru-RU' 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
USE_I18N = True },
{
TIME_ZONE = 'Europe/Moscow' 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
USE_I18N = True
USE_L10N = True # Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
USE_TZ = True
LANGUAGE_CODE = 'ru-RU'
USE_I18N = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/ TIME_ZONE = 'Europe/Moscow'
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_URL = '/static/' USE_I18N = True
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
USE_L10N = True
ADMIN_TOOLS_MENU = 'myproject.menu.CustomMenu'
ADMIN_TOOLS_INDEX_DASHBOARD = 'myproject.dashboard.CustomIndexDashboard' USE_TZ = True
ADMIN_TOOLS_APP_INDEX_DASHBOARD = 'myproject.dashboard.CustomAppIndexDashboard'
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media') # Static files (CSS, JavaScript, Images)
MEDIA_URL = '/media/' # https://docs.djangoproject.com/en/1.9/howto/static-files/
LOGIN_REDIRECT_URL = '/' PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
LOGOUT_REDIRECT_URL = '/' STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
ADMIN_TOOLS_MENU = 'myproject.menu.CustomMenu'
ADMIN_TOOLS_INDEX_DASHBOARD = 'myproject.dashboard.CustomIndexDashboard'
ADMIN_TOOLS_APP_INDEX_DASHBOARD = 'myproject.dashboard.CustomAppIndexDashboard'
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')
MEDIA_URL = '/media/'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

View File

@ -1,28 +1,28 @@
"""mysite URL Configuration """mysite URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see: The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.9/topics/http/urls/ https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples: Examples:
Function views Function views
1. Add an import: from my_app import views 1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views Class-based views
1. Add an import: from other_app.views import Home 1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf Including another URLconf
1. Import the include() function: from django.conf.urls import url, include 1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
""" """
from django.conf.urls import url, include, patterns from django.conf.urls import url, include
from django.contrib import admin from django.contrib import admin
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
urlpatterns = patterns('', urlpatterns = [
url(r'^admin/', admin.site.urls), url(r'^admin/', admin.site.urls),
url(r'^$', TemplateView.as_view(template_name='main.html')), url(r'^$', TemplateView.as_view(template_name='main.html')),
url(r'^blog/', include('blog.urls')), url(r'^blog/', include('blog.urls')),
url(r'^polls/', include('polls.urls', namespace="polls")), url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^imagehost/', include('imagehost.urls')), url(r'^imagehost/', include('imagehost.urls')),
url(r'^pfm/', include('pfm.urls')), url(r'^pfm/', include('pfm.urls')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -1,17 +1,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
WSGI config for mysite project. WSGI config for mysite project.
It exposes the WSGI callable as a module-level variable named ``application``. It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/
""" """
import os import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "imagehost.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "imagehost.settings")
application = get_wsgi_application() application = get_wsgi_application()

View File

@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from .models import Post from .models import Post
admin.site.register(Post) admin.site.register(Post)
# Register your models here. # Register your models here.

View File

@ -1,7 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.apps import AppConfig from django.apps import AppConfig
class ImagehostConfig(AppConfig): class ImagehostConfig(AppConfig):
name = 'imagehost' name = 'imagehost'

View File

@ -1,18 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django import forms from django import forms
from .models import Post from .models import Post
class PostForm(forms.ModelForm): class PostForm(forms.ModelForm):
class Meta: class Meta:
model = Post model = Post
fields = ('name', 'file') fields = ('name', 'file')
class DeleteForm(forms.ModelForm): class DeleteForm(forms.ModelForm):
class Meta: class Meta:
model = Post model = Post
fields = [] fields = []

View File

@ -1,28 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
import os import os
class Post(models.Model): class Post(models.Model):
name = models.CharField(max_length=30, blank=True) name = models.CharField(max_length=30, blank=True)
file = models.FileField(upload_to='images') file = models.FileField(upload_to='images')
thumb_name = property(thumb_name) thumb_name = property(thumb_name)
orig_name = property(orig_name) orig_name = property(orig_name)
def publish(self): def publish(self):
self.published_date = timezone.now() self.published_date = timezone.now()
self.save() self.save()
def __unicode__(self): def __unicode__(self):
return self.name return self.name
def thumb_name(self): def thumb_name(self):
x = os.path.split(self.file.name)[-1] x = os.path.split(self.file.name)[-1]
return '/thumb_' + x return '/thumb_' + x
def orig_name(self): def orig_name(self):
x = os.path.split(self.file.name)[-1] x = os.path.split(self.file.name)[-1]
return x return x

View File

@ -1,35 +1,35 @@
{% extends 'imagehosting/base.html' %} {% extends 'imagehosting/base.html' %}
{% load static %} {% load static %}
{% block content%} {% block content%}
<div class="images"> <div class="images">
{% for image in all %}<a href="{% url 'image_detail' pk=image.pk %}" ><img src= "/media/images{{image.thumb_name }}"></a>{% endfor %} {% for image in all %}<a href="{% url 'image_detail' pk=image.pk %}" ><img src= "/media/images{{image.thumb_name }}"></a>{% endfor %}
</div> </div>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script> <script>
$(function() {resizer(); }) $(function() {resizer(); })
$(window).resize(function() { resizer(); }) $(window).resize(function() { resizer(); })
function resizer() { function resizer() {
var imgs = $('img'); var imgs = $('img');
var row_width = $(window).width() - 50; var row_width = $(window).width() - 50;
var prev = []; var prev = [];
var total_w = 0; var total_w = 0;
imgs.each(function (i, e) { imgs.each(function (i, e) {
$(this).height(200); $(this).height(200);
prev[prev.length] = $(e); prev[prev.length] = $(e);
total_w += $(e).width(); total_w += $(e).width();
if (total_w > row_width) { if (total_w > row_width) {
prev = $(prev); prev = $(prev);
prev.each(function (indx, element) {$(element).height(row_width*200/total_w)}); prev.each(function (indx, element) {$(element).height(row_width*200/total_w)});
prev = []; prev = [];
total_w = 0; total_w = 0;
} }
}) })
} }
</script> </script>
{% endblock content %} {% endblock content %}

View File

@ -1,114 +1,114 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Josefin+Sans:600" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Josefin+Sans:600" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<style> <style>
body { body {
margin: 0; margin: 0;
} }
.images { .images {
margin-top: 10px; margin-top: 10px;
margin-left: 25px; margin-left: 25px;
} }
.header { .header {
dispaly: block; dispaly: block;
color: black; color: black;
background: linear-gradient(#f3f3f3, #e0e0e0); background: linear-gradient(#f3f3f3, #e0e0e0);
padding: 10px 25px; padding: 10px 25px;
font-size: 30px font-size: 30px
} }
ul.menu-icon { ul.menu-icon {
display: none; display: none;
float: right; float: right;
color: black; color: black;
padding: 7px 0 20px; padding: 7px 0 20px;
margin: 0; margin: 0;
} }
.logo { .logo {
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
color: #696969; color: #696969;
width: 50px; width: 50px;
text-decoration: none; text-decoration: none;
} }
li { li {
list-style-type: none list-style-type: none
} }
.menu { .menu {
position: absolute; position: absolute;
font-size: 20px; font-size: 20px;
right: 10px; right: 10px;
top: 60px; top: 60px;
display: none; display: none;
} }
.menu a { .menu a {
text-align: right; text-align: right;
display: inline-block; display: inline-block;
padding: 10px; padding: 10px;
background: #e0e0e0; background: #e0e0e0;
width: 90%; width: 90%;
text-decoration: none; text-decoration: none;
} }
.menu a:hover { .menu a:hover {
color:#181D2B; color:#181D2B;
} }
i { i {
float: right; float: right;
} }
.right-menu { .right-menu {
float: right; float: right;
padding: 12px; padding: 12px;
font-family: 'Open Sans', sans-serif; font-family: 'Open Sans', sans-serif;
font-size: 20px; font-size: 20px;
display: inline; display: inline;
} }
a.right-menu { a.right-menu {
text-decoration: none; text-decoration: none;
color: #4368AD; color: #4368AD;
padding: 9px; padding: 9px;
} }
@media screen and (max-width: 450px) { @media screen and (max-width: 450px) {
ul.menu-icon {display: block} ul.menu-icon {display: block}
a.right-menu {display: none} a.right-menu {display: none}
} }
</style> </style>
</head> </head>
<body> <body>
<div class='header'> <a href="{% url 'all_posts' %}" class='logo'>LOGO </a> <div class='header'> <a href="{% url 'all_posts' %}" class='logo'>LOGO </a>
<a href="{% url 'image_new' %}" class='right-menu'>new image</a> <a href="{% url 'image_new' %}" class='right-menu'>new image</a>
<a href="{% url 'all_posts' %}" class='right-menu'>all images</a> <a href="{% url 'all_posts' %}" class='right-menu'>all images</a>
<ul class='menu-icon'> <ul class='menu-icon'>
<li><i class="fa fa-bars"></i></li> <li><i class="fa fa-bars"></i></li>
<ul class="menu"> <ul class="menu">
<li class="long"><a href="{% url 'image_new' %}">new image</a></li> <li class="long"><a href="{% url 'image_new' %}">new image</a></li>
<li class="long"><a href="{% url 'all_posts' %}">all images</a></li> <li class="long"><a href="{% url 'all_posts' %}">all images</a></li>
</ul> </ul>
</ul> </ul>
</div> </div>
{% block content %} {% block content %}
{% endblock%} {% endblock%}
</body> </body>
<script> <script>
$('.menu-icon').click(function() {if ($('.menu').css('display') == 'block') { $('.menu-icon').click(function() {if ($('.menu').css('display') == 'block') {
$('.menu').css('display', 'none') } else { $('.menu').css('display', 'none') } else {
$('.menu').css('display', 'block') $('.menu').css('display', 'block')
}}) }})
</script> </script>
</html> </html>

View File

@ -1,15 +1,15 @@
{% extends 'imagehosting/base.html' %} {% extends 'imagehosting/base.html' %}
{% block content %} {% block content %}
<div class="block" style="position: relative; width: 400px; width: padding: 50px; border: 1px solid #e0e0e0; margin: 100px auto;"> <div class="block" style="position: relative; width: 400px; width: padding: 50px; border: 1px solid #e0e0e0; margin: 100px auto;">
<a href="/media/{{post.file}}"><img src="/media/images{{ post.thumb_name }}" style="margin: auto; display: block; padding: 10px"></a> <a href="/media/{{post.file}}"><img src="/media/images{{ post.thumb_name }}" style="margin: auto; display: block; padding: 10px"></a>
<div style="margin: auto; display: block; padding: 10px 0 20px; width: 140px; text-align: center;"> <div style="margin: auto; display: block; padding: 10px 0 20px; width: 140px; text-align: center;">
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a href="{% url 'delete_post' pk=post.pk %}" onclick = "return confirm('Удалить?')" style="padding-right: 30px; color: #888787">удалить</a> <a href="{% url 'delete_post' pk=post.pk %}" onclick = "return confirm('Удалить?')" style="padding-right: 30px; color: #888787">удалить</a>
{% endif %} {% endif %}
<a href="/media/{{post.file}}" download style=" color: #888787; margin: auto; text-align: right"> {{ post.name }} скачать</a> <a href="/media/{{post.file}}" download style=" color: #888787; margin: auto; text-align: right"> {{ post.name }} скачать</a>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,10 +1,10 @@
{% extends 'imagehosting/base.html' %} {% extends 'imagehosting/base.html' %}
{% block content %} {% block content %}
<div class="block" style="width: 500px; padding: 50px; margin: 100px auto; border: 1px solid #e0e0e0"> <div class="block" style="width: 500px; padding: 50px; margin: 100px auto; border: 1px solid #e0e0e0">
<form method="POST" class="post-form" enctype="multipart/form-data" action="" >{% csrf_token %} <form method="POST" class="post-form" enctype="multipart/form-data" action="" >{% csrf_token %}
{{ form.as_p }} {{ form.as_p }}
<input type="submit" value="send" class="save btn btn-default"></button> <input type="submit" value="send" class="save btn btn-default"></button>
</form> </form>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,12 +1,12 @@
{% extends 'imagehosting/base.html' %} {% extends 'imagehosting/base.html' %}
{% block content %} {% block content %}
<form method="post" action="{% url 'login' %}" class="w3-container" style="padding: 20px"> <form method="post" action="{% url 'login' %}" class="w3-container" style="padding: 20px">
<table> <table>
{% csrf_token %} {% csrf_token %}
{{form.as_table}} {{form.as_table}}
<tr><td></td><td><input id="login" type="submit" class="w3-btn w3-right"value="login" /></td></tr> <tr><td></td><td><input id="login" type="submit" class="w3-btn w3-right"value="login" /></td></tr>
</table> </table>
<input type="hidden" name="next" value="{{ next }}" /> <input type="hidden" name="next" value="{{ next }}" />
</form> </form>
{% endblock %} {% endblock %}

View File

@ -1,3 +1,3 @@
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

View File

@ -1,22 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import url from django.conf.urls import url
from . import views from . import views
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.views import login, logout from django.contrib.auth.views import login, logout
urlpatterns = [ urlpatterns = [
url(r'^$', views.image_new, name='image_new'), url(r'^$', views.image_new, name='image_new'),
url(r'^post/(?P<pk>[0-9]+)/$', views.image_detail, name='image_detail'), url(r'^post/(?P<pk>[0-9]+)/$', views.image_detail, name='image_detail'),
url(r'^all/$', views.all_posts, name='all_posts'), url(r'^all/$', views.all_posts, name='all_posts'),
url(r'^delete/(?P<pk>[0-9]+)/$', views.delete_post, name='delete_post'), url(r'^delete/(?P<pk>[0-9]+)/$', views.delete_post, name='delete_post'),
url(r'^admin/', admin.site.urls), url(r'^admin/', admin.site.urls),
url(r'^login$', login, {'template_name':'imagehosting/login.html'}, name='login'), url(r'^login$', login, {'template_name':'imagehosting/login.html'}, name='login'),
url(r'^logout/$', logout) url(r'^logout/$', logout)
] ]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns() urlpatterns += staticfiles_urlpatterns()

View File

@ -1,59 +1,59 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render, get_object_or_404, HttpResponseRedirect from django.shortcuts import render, get_object_or_404, HttpResponseRedirect
from .models import Post from .models import Post
from .forms import PostForm, DeleteForm from .forms import PostForm, DeleteForm
from django.shortcuts import redirect from django.shortcuts import redirect
from ih import files, images from ih import files, images
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from ih import images from ih import images
from django.views.decorators.csrf import requires_csrf_token from django.views.decorators.csrf import requires_csrf_token
def create_thumb_from_file(filename): def create_thumb_from_file(filename):
orig_file = 'imagehost/media/images/' + filename orig_file = 'imagehost/media/images/' + filename
# Create thumbnail # Create thumbnail
thumb_name = images.resize_image(orig_file, { thumb_name = images.resize_image(orig_file, {
'name': filename, 'name': filename,
'size': [300, 300], 'size': [300, 300],
'dest': 'imagehost/media/images' 'dest': 'imagehost/media/images'
} }
) )
return thumb_name return thumb_name
@login_required(login_url="/login") @login_required(login_url="/login")
def image_new(request): def image_new(request):
if request.method == "POST": if request.method == "POST":
form = PostForm(request.POST, request.FILES) form = PostForm(request.POST, request.FILES)
if form.is_valid(): if form.is_valid():
post = form.save(commit=False) post = form.save(commit=False)
post.save() post.save()
create_thumb_from_file(post.orig_name) create_thumb_from_file(post.orig_name)
return redirect('imagehosting.views.image_detail', pk=post.id) return redirect('imagehosting.views.image_detail', pk=post.id)
else: else:
form = PostForm() form = PostForm()
return render(request, 'imagehosting/index.html', {'form': form}) return render(request, 'imagehosting/index.html', {'form': form})
def image_detail(request, pk): def image_detail(request, pk):
post = get_object_or_404(Post, pk=pk) post = get_object_or_404(Post, pk=pk)
return render(request, 'imagehosting/image.html', {'post': post}) return render(request, 'imagehosting/image.html', {'post': post})
def all_posts(request): def all_posts(request):
all = Post.objects.order_by('-pk') all_posts = Post.objects.order_by('-pk')
return render(request, 'imagehosting/all.html', {'all': all}) return render(request, 'imagehosting/all.html', {'all': all_posts})
@login_required(login_url="/login") @login_required(login_url="/login")
def delete_post(request, pk): def delete_post(request, pk):
post_to_delete = get_object_or_404(Post, pk=pk) post_to_delete = get_object_or_404(Post, pk=pk)
if request.method == 'GET': if request.method == 'GET':
form = DeleteForm(request.POST, instance=post_to_delete) form = DeleteForm(request.POST, instance=post_to_delete)
if form.is_valid(): # checks CSRF if form.is_valid(): # checks CSRF
if not request.user.is_authenticated(): if not request.user.is_authenticated():
return HttpResponseRedirect('/admin') return HttpResponseRedirect('/admin')
post_to_delete.delete() post_to_delete.delete()
return redirect('imagehosting.views.all_posts') return redirect('imagehosting.views.all_posts')
return render(request, 'imagehosting/delete.html', {'form': form}) return render(request, 'imagehosting/delete.html', {'form': form})

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
Django==1.11.1
psycopg2
gunicorn==19.6.0