Skip to content

Commit

Permalink
Merge branch 'master' into 256-fix-next-previous-photo
Browse files Browse the repository at this point in the history
  • Loading branch information
damianmoore committed Sep 2, 2021
2 parents fbf4742 + 9a0d631 commit 137987d
Show file tree
Hide file tree
Showing 140 changed files with 5,089 additions and 606 deletions.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [photonixapp]
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ restart:
shell:
$(DOCKER_COMPOSE_DEV) exec photonix bash

shell-prd:
$(DOCKER_COMPOSE_PRD) exec photonix bash

manage:
$(DOCKER_COMPOSE_DEV) exec photonix python photonix/manage.py ${}

Expand Down
12 changes: 11 additions & 1 deletion docker/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ FROM python:3.8.9-slim-buster

# Install system dependencies - note that some of these are only used on non-amd64 where Python packages have to be compiled from source
RUN apt-get update && \
apt-get install -y \
apt-get install -y --no-install-recommends \
build-essential \
cron \
curl \
dcraw \
file \
git \
gnupg \
libatlas-base-dev \
Expand All @@ -14,7 +16,10 @@ RUN apt-get update && \
libblas3 \
libfreetype6 \
libfreetype6-dev \
libgl1 \
libglib2.0-dev \
libhdf5-dev \
libheif-examples \
libimage-exiftool-perl \
libjpeg-dev \
liblapack-dev \
Expand Down Expand Up @@ -66,6 +71,7 @@ RUN cd /srv/ui && yarn install
# Copy over the code
COPY photonix /srv/photonix
COPY test.py /srv/test.py
COPY manage.py /srv/manage.py
COPY tests /srv/tests
COPY ui/public /srv/ui/public
COPY ui/src /srv/ui/src
Expand All @@ -74,6 +80,10 @@ COPY ui/src /srv/ui/src
COPY system /srv/system
COPY system/supervisord.conf /etc/supervisord.conf

# Copy crontab
COPY system/cron.d /etc/cron.d/
RUN chmod 0644 /etc/cron.d/*

ENV PYTHONPATH /srv

CMD ./system/run.sh
Expand Down
21 changes: 17 additions & 4 deletions docker/Dockerfile.prd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FROM ${ARCH}python:3.8.9-slim-buster as builder
RUN apt-get update && \
apt-get install -y \
build-essential \
cmake \
curl \
gfortran \
gnupg \
Expand All @@ -13,11 +14,11 @@ RUN apt-get update && \
libblas3 \
libfreetype6 \
libfreetype6-dev \
libhdf5-dev \
libjpeg-dev \
liblapack-dev \
liblapack3 \
libpq-dev \
libssl-dev \
libtiff5-dev \
&& \
apt-get clean && \
Expand Down Expand Up @@ -86,25 +87,31 @@ RUN rm -rf \
/usr/local/lib/python3.8/site-packages/matplotlib/mpl-data/sample_data \
/usr/local/lib/python3.8/site-packages/matplotlib/mpl-data/images \
/usr/local/lib/python3.8/site-packages/matplotlib/mpl-data/stylelib \
/usr/local/lib/python3.8/site-packages/h5py \
/usr/local/lib/python3.8/site-packages/tensorboard \
/usr/local/lib/python3.8/site-packages/tensorboard_plugin_wit


FROM ${ARCH}python:3.8.9-slim-buster

RUN apt-get update && \
apt-get install -y \
apt-get install -y --no-install-recommends \
cron \
dcraw \
file \
libatlas3-base \
libfreetype6 \
libfreetype6-dev \
libgl1 \
libglib2.0-dev \
libhdf5-dev \
libheif-examples \
libimage-exiftool-perl \
libpq-dev \
libtiff5-dev \
netcat \
nginx-light \
supervisor \
xz-utils \
&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/* \
Expand All @@ -120,6 +127,7 @@ WORKDIR /srv

# Copy over the code
COPY photonix /srv/photonix
COPY manage.py /srv/manage.py
COPY test.py /srv/test.py
COPY tests /srv/tests
COPY ui/public /srv/ui/public
Expand All @@ -128,9 +136,14 @@ COPY ui/public /srv/ui/public
COPY system /srv/system
COPY system/supervisord.conf /etc/supervisord.conf

# Copy crontab
COPY system/cron.d /etc/cron.d/
RUN chmod 0644 /etc/cron.d/*

ENV PYTHONPATH /srv
ENV TF_CPP_MIN_LOG_LEVEL 3

RUN python photonix/manage.py collectstatic --noinput --link
RUN DJANGO_SECRET_KEY=test python photonix/manage.py collectstatic --noinput --link

CMD ./system/run.sh

Expand Down
3 changes: 2 additions & 1 deletion docker/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ services:
- '8880:8001'
environment:
ENV: dev
DEMO: 1
SAMPLE_DATA: 1
POSTGRES_HOST: postgres
POSTGRES_DB: photonix
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
REDIS_HOST: redis
ALLOWED_HOSTS: '*'
LOG_LEVEL: DEBUG
volumes:
- ../photonix:/srv/photonix
- ../system:/srv/system
Expand Down
1 change: 1 addition & 0 deletions docker/docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ services:
POSTGRES_PASSWORD: password
REDIS_HOST: redis
ALLOWED_HOSTS: '*'
# More configuration options here: https://photonix.org/docs/configuration/
volumes:
- ./data/photos:/data/photos
- ./data/raw-photos-processed:/data/raw-photos-processed
Expand Down
1 change: 1 addition & 0 deletions manage.py
18 changes: 18 additions & 0 deletions photonix/accounts/migrations/0004_alter_user_first_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.3 on 2021-06-17 22:18

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('accounts', '0003_add_user_signup_flds'),
]

operations = [
migrations.AlterField(
model_name='user',
name='first_name',
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
),
]
59 changes: 29 additions & 30 deletions photonix/accounts/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.contrib.auth import get_user_model, authenticate, update_session_auth_hash
import graphene
from graphene_django.types import DjangoObjectType
from graphql import GraphQLError
from graphql_jwt.shortcuts import create_refresh_token, get_token
import graphql_jwt
from photonix.photos.models import Library, LibraryPath, LibraryUser
Expand All @@ -12,18 +13,12 @@


class UserType(DjangoObjectType):
"""Docstring for UserType."""

class Meta:
model = User


class CreateUser(graphene.Mutation):
"""Docstring for CreateUser."""

class Arguments:
"""Docstring for Arguments."""

username = graphene.String(required=True)
password = graphene.String(required=True)
password1 = graphene.String(required=True)
Expand All @@ -34,13 +29,12 @@ class Arguments:

@staticmethod
def mutate(self, info, username, password, password1):
"""Mutate method."""
if User.objects.filter(username=username).exists():
raise Exception("Username already exists!")
raise GraphQLError('Username already exists!')
elif len(password) < 8 and len(password1) < 8:
raise Exception("Password must be at least 8 characters long!")
raise GraphQLError('Password must be at least 8 characters long!')
elif password != password1:
raise Exception("Password fields do not match!")
raise GraphQLError('Password fields do not match!')
else:
user = User(username=username)
user.set_password(password1)
Expand All @@ -53,6 +47,7 @@ def mutate(self, info, username, password, password1):

class Environment(graphene.ObjectType):
demo = graphene.Boolean()
sample_data = graphene.Boolean()
first_run = graphene.Boolean()
form = graphene.String()
user_id = graphene.ID()
Expand All @@ -61,11 +56,11 @@ class Environment(graphene.ObjectType):


class AfterSignup(graphene.ObjectType):
"""Pass token for login, after signup."""

'''Pass token for login, after signup.'''
token = graphene.String()
refresh_token = graphene.String()


class Query(graphene.ObjectType):
profile = graphene.Field(UserType)
environment = graphene.Field(Environment)
Expand All @@ -74,66 +69,72 @@ class Query(graphene.ObjectType):
def resolve_profile(self, info):
user = info.context.user
if user.is_anonymous:
raise Exception('Not logged in')
raise GraphQLError('Not logged in')
return user

def resolve_environment(self, info):
user = User.objects.first()
demo = os.environ.get('DEMO', False)
sample_data = os.environ.get('DEMO', False) or os.environ.get('SAMPLE_DATA', False)

if user and user.has_config_persional_info and \
user.has_created_library and user.has_configured_importing and \
user.has_configured_image_analysis:
# raise Exception(info.context.user.is_anonymous)
return {
'demo': os.environ.get('DEMO', False),
'demo': demo,
'sample_data': sample_data,
'first_run': False,
}
else:
if not user:
if not user or not user.is_authenticated:
return {
'demo': os.environ.get('DEMO', False), 'first_run': True,
'demo': demo,
'sample_data': sample_data,
'first_run': True,
'form': 'has_config_persional_info'}
if not user.has_created_library:
return {
'demo': os.environ.get('DEMO', False), 'first_run': True,
'demo': demo,
'sample_data': sample_data,
'first_run': True,
'form': 'has_created_library', 'user_id': user.id}
if not user.has_configured_importing:
return {
'demo': os.environ.get('DEMO', False), 'first_run': True,
'demo': demo,
'sample_data': sample_data,
'first_run': True,
'form': 'has_configured_importing', 'user_id': user.id,
'library_id': Library.objects.filter(users__user=user)[0].id,
'library_path_id': LibraryPath.objects.filter(library__users__user=user)[0].id
}
if not user.has_configured_image_analysis:
return {
'demo': os.environ.get('DEMO', False), 'first_run': True,
'demo': demo,
'sample_data': sample_data,
'first_run': True,
'form': 'has_configured_image_analysis', 'user_id': user.id,
'library_id': Library.objects.filter(users__user=user)[0].id,
}

def resolve_after_signup(self, info):
"""To login user from frontend after finish sigunp process."""
'''To login user from frontend after finish sigunp process.'''
user = info.context.user
if user.has_configured_image_analysis:
if user.is_authenticated and user.has_configured_image_analysis:
return {'token': get_token(user), 'refresh_token': create_refresh_token(user)}
return {'token': None, 'refresh_token': None}


class ChangePassword(graphene.Mutation):
"""docstring for ChangePassword."""

class Arguments:
"""docstring for Arguments."""

old_password = graphene.String(required=True)
new_password = graphene.String(required=True)

ok = graphene.Boolean()

@staticmethod
def mutate(self, info, old_password, new_password):
"""Mutate method for change password."""
if os.environ.get('DEMO', False) and os.environ.get('ENV') != 'test':
raise Exception("Password cannot be changed in demo mode!")
raise GraphQLError('Password cannot be changed in demo mode!')
if authenticate(username=info.context.user.username, password=old_password):
info.context.user.set_password(new_password)
info.context.user.save()
Expand All @@ -143,8 +144,6 @@ def mutate(self, info, old_password, new_password):


class Mutation(graphene.ObjectType):
"""To create objects for all mutaions."""

token_auth = graphql_jwt.ObtainJSONWebToken.Field()
verify_token = graphql_jwt.Verify.Field()
refresh_token = graphql_jwt.Refresh.Field()
Expand Down
9 changes: 5 additions & 4 deletions photonix/classifiers/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
import logging

import requests

import redis
from redis_lock import Lock

from photonix.photos.utils.redis import redis_connection


graph_cache = {}

logger = logging.getLogger(__name__)


class BaseModel:
def __init__(self, model_dir=None):
global graph_cache
Expand Down Expand Up @@ -50,8 +52,7 @@ def ensure_downloaded(self, lock_name=None):
if not lock_name:
lock_name = 'classifier_{}_download'.format(self.name)

r = redis.Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'))
with Lock(r, lock_name):
with Lock(redis_connection, lock_name):
try:
with open(version_file) as f:
if f.read().strip() == str(self.version):
Expand Down
6 changes: 1 addition & 5 deletions photonix/classifiers/color/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def __init__(self):
self.colors = {
# Name: ((red, green, blue), ordering)

'Red': ((120, 4, 20), 1),
'Red': ((120, 4, 20), 1),
'Orange': ((245, 133, 0), 2),
'Amber': ((234, 166, 30), 3),
'Yellow': ((240, 240, 39), 4),
Expand Down Expand Up @@ -82,15 +82,11 @@ def run_on_photo(photo_id):
photo, results = results_for_model_on_photo(model, photo_id)

if photo:
from django.utils import timezone
from photonix.photos.models import PhotoTag
photo.clear_tags(source='C', type='C')
for name, score in results:
tag = get_or_create_tag(library=photo.library, name=name, type='C', source='C', ordering=model.colors[name][1])
PhotoTag(photo=photo, tag=tag, source='C', confidence=score, significance=score).save()
photo.classifier_color_completed_at = timezone.now()
photo.classifier_color_version = getattr(model, 'version', 0)
photo.save()

return photo, results

Expand Down
Loading

0 comments on commit 137987d

Please sign in to comment.