Initial Commit

This project will be to create an image gallery
with support for private 'folders' as well as other
ideas that I have
This commit is contained in:
c0de 2018-03-08 18:55:03 -06:00
commit 88d195c207
13 changed files with 423 additions and 0 deletions

16
.editorconfig Normal file
View File

@ -0,0 +1,16 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
__pycache__
.*~
*.pyc
*.pyo
.*.swp
venv
*.sublime-project
*.sublime-workspace
*.orig
.vscode/*
*.sqlite3

12
Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM python:2.7
WORKDIR /src
ADD . /src
RUN set -ex \
&& curl -L https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh -o /usr/local/bin/wait-for-it.sh \
&& chmod +x /usr/local/bin/wait-for-it.sh \
&& pip install -r requirements.txt \
&& python manage.py collectstatic --noinput
CMD python manage.py runserver 0.0.0.0:8000

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 David Todd (c0de) <c0de@c0defox.es>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

127
README.docker.md Normal file
View File

@ -0,0 +1,127 @@
# local development
You'll need to have installed `docker-compose` and `docker`, and have a running
docker daemon.
# starting services with docker-compose
You should be inside the `django-gallery` directory when running this command.
```sh
docker-compose up
```
You'll see labeled output from each service.
When you make changes on your local copy of django-gallery, they will automatically propagate to the running container.
## accessing the database (cli)
There are cases where you may need access to the database (such as restoring a backup).
These commands will allow you access into the database over the command line.
1. Have docker running. Eg. `docker-compose up -f docker-compose.yaml`
2. Locate your container. `docker ps`, select the CONTAINER ID for postgres
3. Establish a shell in the container. `docker exec -t -i (CONTAINER ID) bash`
4. Connect to the database. `su postgres -c psql`
Now that you are connected to the database CLI, you can perform queries as the root postgres user.
For remote access to this database, you may create a role for yourself with the following query.
`create role your-name with superuser createdb login password 'your-password';`
To restore a database backup from the command line:
1. Find a way to copy the database into the container (or access it externally)
2. Become the postgres root user. `su postgres -c bash`
3. Stop the portal docker container (this can be accomplished with `docker stop (CONTAINER ID)`)
4. Verify that there are no other connections to the DB and enter psql
5. Rename or drop the imagehost_db database so it is out of the way
6. create the database and public schema
7. set permissions for the imagehost user
8. leave psql and run `pg_restore -F -c imagehost_dbDB.custom` on newly created imagehost_db db
Some errors are expected from the above, such as a non-existant usagereports role.
These can safely be ignored for development use (the role requires read-only access in prod)
## accessing the database (GUI)
GUI access to the database can be established with PGAdmin (3 or 4) connected to localhost.
This assumes that you created a user for yourself in the previous section
(if you haven't, you can use the imagehost user at limited permissions)
1. Open PGAdmin and add a new server with an identifying name
2. Under the connection tab
* Hostname/address should be localhost
* Username should be what you added in the previous section
* Password should be what you added in the previous section
3. Save and connect, you should now be able to run queries with administrative privileges.
To restore a database backup inside PGAdmin:
1. Copy the imagehost_dbDB.custom to your desktop (or somewhere easy) and
rename to imagehost_dbDB.backup
2. Connect to the database server
3. Stop the portal docker container (this can be accomplished with `docker stop (CONTIANER ID)`)
4. Verify that there are no other connections to the db and either rename or drop the database
5. Create a new database with the owner set to imagehost
6. Right-click the newly created database and click restore
7. Navigate to your .backup file and select that
8. Let the restore run
Some errors are expected from the above, such as a non-existant usagereports role.
These can safely be ignored for development use (the role requires read-only access in prod)
## applying migrations
After you have made changes to the database or models, migrations need
to be made and then applied. To accomplish that in the docker env:
1. Have docker running. Eg. `docker-compose up -f docker-compose.yaml`
2. Locate your container. `docker ps`, select the CONTAINER ID for the portal
3. Establish a shell in the container. `docker exec -t -i (CONTIANER ID) bash`
4. CD to the portal directory (in docker-compose.yaml, this is defined as /portal)
5. Make your migrations. `python manage.py makemigrations`
6. Apply the migrations. `python manage.py migrate`
7. Optionally exit the shell. It is no longer needed.
You may get errors on your last step if you are restoring from a database
backup. Before making the migrations, first run `python manage.py --fake-initial`
If your database has migrations applied, it should be able to continue from
whichever the last applied migration was.
# staging/testing
You'll need to have `docker-machine` installed. You can create a fully
provisioned VM on ESXi using this command:
```sh
docker-machine create \
--driver vmwarevsphere \
--vmwarevsphere-username root \
--vmwarevsphere-password password \
--vmwarevsphere-vcenter 500.500.500.500 \
my-docker
```
You should replace `my-docker` with whatever you want to uniquely reference this
VM by.
Note: If you get an error similar to "ServerFaultCode: Current license or ESXi version prohibits execution of the requested operation."
you must first put the vmserver in "Evaluation Mode" as the Free tier license does not support remote management of VMs.
This can be accomplished by logging into the esxi interface, navigating to configuration and changing the license config.
## remote environment
First, you'll set up your local docker client to connect to the remote docker host:
```sh
eval $(docker-machine env my-docker)
```
You can see the containers running on the remote host using regular docker
commands like `docker ps`.
## create a production environment
```sh
docker-compose -f docker-compose.yaml -f docker-compose.production.yaml up
```

30
docker-compose.yaml Normal file
View File

@ -0,0 +1,30 @@
version: '3'
services:
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: totallyHacked1337
POSTGRES_USER: imagehost
POSTGRES_DB: imagehost_db
volumes:
- ./backup:/backup
ports:
- '5432:5432'
imagehost_portal:
build: .
environment:
PORTAL_DEBUG: 'true'
volumes:
- .:/portal
ports:
- '8000:8000'
depends_on:
- postgres
working_dir: /portal
command: |
/usr/local/bin/wait-for-it.sh -t 60 postgres:5432 --
sh /portal/run.sh

0
gallery/__init__.py Normal file
View File

120
gallery/settings.py Normal file
View File

@ -0,0 +1,120 @@
"""
Django settings for gallery project.
Generated by 'django-admin startproject' using Django 1.11.4.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/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/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^2)m5jqumpm6-1io$18tjwo@dnukf=r-kl#8&q1#qf!&(&y_6h'
# SECURITY WARNING: don't run with debug turned on in production!
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',
]
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 = 'gallery.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',
],
},
},
]
WSGI_APPLICATION = 'gallery.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/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/1.11/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/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'

21
gallery/urls.py Normal file
View File

@ -0,0 +1,21 @@
"""gallery URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]

16
gallery/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for gallery 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.11/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gallery.settings")
application = get_wsgi_application()

22
manage.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gallery.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
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?"
)
raise
execute_from_command_line(sys.argv)

21
requirements.txt Normal file
View File

@ -0,0 +1,21 @@
asn1crypto==0.22.0
cffi==1.10.0
cryptography==2.0.3
Django==1.11.4
django-debug-panel==0.8.3
django-debug-toolbar==1.8
django-inline-actions==1.1.0
djangorestframework==3.6.3
enum34==1.1.6
idna==2.6
ipaddress==1.0.18
psycopg2==2.7.3
pycparser==2.18
pycrypto==2.6.1
pyOpenSSL==17.2.0
pytz==2017.2
six==1.10.0
sqlparse==0.2.3
uWSGI==2.0.15
zipstream==1.1.4
whitenoise==3.3.1

6
run.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
cd /portal
#cp msmtprc /etc
sleep 1 # Hopefully enough for the database to start accepting connections
python manage.py migrate
python manage.py runserver 0.0.0.0:8000