Skip to content

Commit

Permalink
Merge branch 'master' into 6-Faceted-search-remaining-filters
Browse files Browse the repository at this point in the history
  • Loading branch information
damianmoore committed Mar 22, 2021
2 parents c94239c + ea0c290 commit f30b3ee
Show file tree
Hide file tree
Showing 69 changed files with 1,843 additions and 1,226 deletions.
4 changes: 4 additions & 0 deletions photonix/accounts/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def resolve_profile(self, info):
return user

def resolve_environment(self, info):
return {
'demo': os.environ.get('DEMO', False),
'first_run': False,
}
user = User.objects.first()
if user and user.has_config_persional_info and \
user.has_created_library and user.has_configured_importing and \
Expand Down
32 changes: 32 additions & 0 deletions photonix/photos/management/commands/housekeeping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import os
from pathlib import Path
from shutil import rmtree
from time import sleep

from django.conf import settings
from django.core.management.base import BaseCommand

from photonix.photos.models import Photo, Task
from photonix.photos.utils.thumbnails import THUMBNAILER_VERSION


class Command(BaseCommand):
help = 'Makes sure that if there have been upgrades to thumbnailing or image analysis code then jobs get rescheduled.'

def housekeeping(self):
# Remove old cache directories
for directory in os.listdir(settings.THUMBNAIL_ROOT):
if directory not in ['photofile']:
path = Path(settings.THUMBNAIL_ROOT) / directory
print(f'Removing old cache directory {path}')
rmtree(path)

# Regenerate any outdated thumbnails
photos = Photo.objects.filter(thumbnailed_version__lt=THUMBNAILER_VERSION)
if photos.count():
print(f'Rescheduling {photos.count()} photos to have their thumbnails regenerated')
for photo in photos:
Task(type='generate_thumbnails', subject_id=photo.id).save()

def handle(self, *args, **options):
self.housekeeping()
9 changes: 6 additions & 3 deletions photonix/photos/management/commands/watch_photos.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import asyncio
import imghdr
import subprocess
from pathlib import Path
from time import sleep

Expand Down Expand Up @@ -50,17 +52,18 @@ async def handle_inotify_events():
async for event in inotify:
if event.mask in [Mask.CLOSE_WRITE, Mask.MOVED_TO, Mask.DELETE, Mask.MOVED_FROM]:
photo_path = event.path

library_id = None
for potential_library_path, (potential_library_id, _) in watching_libraries.items():
if str(photo_path).startswith(potential_library_path):
library_id = potential_library_id

if event.mask in [Mask.DELETE, Mask.MOVED_FROM]:
print(f'Removing photo "{photo_path}" from library "{library_id}"')
await record_photo_async(photo_path, library_id, str(event.mask).split('.')[1])
else:
print(f'Adding photo "{photo_path}" to library "{library_id}"')
await record_photo_async(photo_path, library_id, str(event.mask).split('.')[1])
if imghdr.what(photo_path) or not subprocess.run(['dcraw', '-i', photo_path]).returncode:
print(f'Adding photo "{photo_path}" to library "{library_id}"')
await record_photo_async(photo_path, library_id, str(event.mask).split('.')[1])

loop = asyncio.get_event_loop()
loop.create_task(check_libraries())
Expand Down
38 changes: 38 additions & 0 deletions photonix/photos/migrations/0006_auto_20210321_1625.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 3.0.7 on 2021-03-21 16:25

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('photos', '0005_auto_20210206_1032'),
]

operations = [
migrations.RemoveField(
model_name='photofile',
name='preferred',
),
migrations.AddField(
model_name='photo',
name='preferred_photo_file',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='photos.PhotoFile'),
),
migrations.AddField(
model_name='photo',
name='thumbnailed_version',
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name='photofile',
name='thumbnailed_version',
field=models.PositiveIntegerField(default=0),
),
migrations.AlterField(
model_name='phototag',
name='model_version',
field=models.PositiveIntegerField(default=0),
),
]
14 changes: 9 additions & 5 deletions photonix/photos/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ class Photo(UUIDModel, VersionedModel):
longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True)
altitude = models.DecimalField(max_digits=6, decimal_places=1, null=True)
star_rating = models.PositiveIntegerField(
help_text='assign rating to photo', verbose_name="Rating", null=True, blank=True)
help_text='assign rating to photo', verbose_name="Rating", null=True, blank=True)
preferred_photo_file = models.ForeignKey('PhotoFile', related_name='+', null=True, on_delete=models.SET_NULL) # File selected by the user that is the best version to be used
thumbnailed_version = models.PositiveIntegerField(default=0) # Version from photos.utils.thumbnails.THUMBNAILER_VERSION at time of generating the required thumbnails declared in settings.THUMBNAIL_SIZES

class Meta:
ordering = ['-taken_at']
Expand All @@ -144,11 +146,13 @@ def thumbnail_url(self, thumbnail):
return '/thumbnails/{}x{}_{}_q{}/{}.jpg'.format(thumbnail[0], thumbnail[1], thumbnail[2], thumbnail[3], self.id)

def thumbnail_path(self, thumbnail):
return str(Path(settings.THUMBNAIL_ROOT) / '{}x{}_{}_q{}/{}.jpg'.format(thumbnail[0], thumbnail[1], thumbnail[2], thumbnail[3], self.id))
return str(Path(settings.THUMBNAIL_ROOT) / 'photofile' / '{}x{}_{}_q{}/{}.jpg'.format(thumbnail[0], thumbnail[1], thumbnail[2], thumbnail[3], self.base_file.id))

@property
def base_file(self):
preferred_files = self.files.filter(preferred=True)
preferred_files = []
if self.preferred_photo_file:
preferred_files = [self.preferred_photo_file]
if not preferred_files:
preferred_files = self.files.filter(raw_processed=True)
if not preferred_files:
Expand Down Expand Up @@ -183,7 +187,7 @@ class PhotoFile(UUIDModel, VersionedModel):
mimetype = models.CharField(max_length=32, blank=True, null=True)
file_modified_at = models.DateTimeField()
bytes = models.PositiveIntegerField()
preferred = models.BooleanField(default=False)
thumbnailed_version = models.PositiveIntegerField(default=0) # Version from photos.utils.thumbnails.THUMBNAILER_VERSION at time of generating the required thumbnails declared in settings.THUMBNAIL_SIZES
raw_processed = models.BooleanField(default=False)
raw_version = models.PositiveIntegerField(null=True)
raw_external_params = models.CharField(max_length=16, blank=True, null=True)
Expand Down Expand Up @@ -237,7 +241,7 @@ class PhotoTag(UUIDModel, VersionedModel):
photo = models.ForeignKey(Photo, related_name='photo_tags', on_delete=models.CASCADE, null=True)
tag = models.ForeignKey(Tag, related_name='photo_tags', on_delete=models.CASCADE)
source = models.CharField(max_length=1, choices=SOURCE_CHOICES)
model_version = models.PositiveIntegerField(null=True)
model_version = models.PositiveIntegerField(default=0)
confidence = models.FloatField()
significance = models.FloatField(null=True)
verified = models.BooleanField(default=False)
Expand Down
6 changes: 6 additions & 0 deletions photonix/photos/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class Query(graphene.ObjectType):

photo = graphene.Field(PhotoNode, id=graphene.UUID())
all_photos = DjangoFilterConnectionField(PhotoNode, filterset_class=PhotoFilter)
map_photos = DjangoFilterConnectionField(PhotoNode, filterset_class=PhotoFilter)

all_location_tags = graphene.List(LocationTagType, library_id=graphene.UUID(), multi_filter=graphene.String())
all_object_tags = graphene.List(ObjectTagType, library_id=graphene.UUID(), multi_filter=graphene.String())
Expand Down Expand Up @@ -263,6 +264,11 @@ def resolve_all_photos(self, info, **kwargs):
user = info.context.user
return Photo.objects.filter(library__users__user=user)

@login_required
def resolve_map_photos(self, info, **kwargs):
user = info.context.user
return Photo.objects.filter(library__users__user=user).exclude(latitude__isnull=True, longitude__isnull=True)

def resolve_all_location_tags(self, info, **kwargs):
user = info.context.user
if kwargs.get('multi_filter'):
Expand Down
8 changes: 6 additions & 2 deletions photonix/photos/utils/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ def record_photo(path, library, inotify_event_type=None):
except PhotoFile.DoesNotExist:
photo_file = PhotoFile()

if inotify_event_type in ['DELETE', 'MOVED_FROM']:
return delete_photo_record(photo_file)
if inotify_event_type in ['DELETE', 'MOVED_FROM']:
if PhotoFile.objects.filter(path=path).exists():
return delete_photo_record(photo_file)
else:
return False

file_modified_at = datetime.fromtimestamp(os.stat(path).st_mtime, tz=utc)

Expand Down Expand Up @@ -160,4 +163,5 @@ def delete_photo_record(photo_file_obj):
photo_obj.delete()
Tag.objects.filter(photo_tags=None).delete()
Camera.objects.filter(photos=None).delete()
Lens.objects.filter(photos=None).delete()
return False

0 comments on commit f30b3ee

Please sign in to comment.