From 9d5e789012402f4e006577085a424baf0a2761b8 Mon Sep 17 00:00:00 2001 From: Greg Thole Date: Wed, 10 Jan 2018 16:39:10 -0500 Subject: [PATCH] Update/fix research views --- .dockerignore | 5 + .gitignore | 1 + Dockerfile | 8 +- docker-compose.yml | 115 ++++++++------- gedgo/gedcom_update.py | 16 +- gedgo/static/styles/style-default.css | 3 + gedgo/storages.py | 56 ++++--- gedgo/templates/default/research.html | 23 +-- gedgo/templates/default/research_preview.html | 50 +++++++ gedgo/views/research.py | 137 ++++++++++++------ manage.py | 0 reqs.pip | 1 + settings.py | 18 ++- 13 files changed, 292 insertions(+), 141 deletions(-) create mode 100644 .dockerignore create mode 100644 gedgo/templates/default/research_preview.html mode change 100644 => 100755 manage.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2a6b170 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +*.py[co] +settings_local.py +*.ged +/tmp +/files diff --git a/.gitignore b/.gitignore index 5290cc7..e584585 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ pip-log.txt /files/ *.ged settings_local.py +/tmp diff --git a/Dockerfile b/Dockerfile index d94821c..8b07583 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,6 @@ FROM python:2.7 -COPY ./ /src/ +COPY ./ /app/ -WORKDIR /src/ +WORKDIR /app/ RUN pip install -r reqs.pip - -RUN adduser --disabled-password --gecos '' gedgo -RUN chown -R gedgo:gedgo /src -USER gedgo diff --git a/docker-compose.yml b/docker-compose.yml index c5794cf..ea76fdb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,55 +1,60 @@ -# Dev services -avahi: - container_name: 'avahi' - image: 'enernoclabs/avahi:latest' - net: 'host' - log_driver: 'none' -db: - container_name: 'db' - image: 'mysql' - ports: - - '3306:3306' - environment: - MYSQL_ROOT_PASSWORD: 'docker' - MYSQL_DATABASE: 'gedgo' - MYSQL_USER: 'gedgo' - MYSQL_PASSWORD: 'gedgo' - log_driver: 'none' -redis: - container_name: 'redis' - image: 'redis' - ports: - - '6379' - log_driver: 'none' -# Application -app: - build: '.' - container_name: 'gedgo_app' - command: ['python', 'manage.py', 'runserver', '0.0.0.0:8000'] - volumes: - - './:/src' - ports: - - '8000:8000' - links: - - 'db' - - 'redis' -web: - image: 'nginx' - command: 'nginx -g "daemon off;"' - volumes: - - './gedgo-web.conf:/etc/nginx/conf.d/gedgo-web.conf:ro' - - './files:/src/files:ro' - ports: - - '80:80' - links: - - 'app' -worker: - container_name: 'gedgo_worker' - image: 'gedgo_app' - command: ['python', 'manage.py', 'celeryd', '-c', '1', '--loglevel=info'] - volumes: - - './:/src' - links: - - 'app' - - 'db' - - 'redis' +version: '2.2' +services: + # Dev services + avahi: + container_name: 'avahi' + image: 'enernoclabs/avahi:latest' + network_mode: 'host' + logging: + driver: 'none' + db: + container_name: 'db' + image: 'mysql' + ports: + - '3306:3306' + environment: + MYSQL_ROOT_PASSWORD: 'docker' + MYSQL_DATABASE: 'gedgo' + MYSQL_USER: 'gedgo' + MYSQL_PASSWORD: 'gedgo' + logging: + driver: 'none' + redis: + container_name: 'redis' + image: 'redis' + ports: + - '6379' + logging: + driver: 'none' + # Application + app: + build: '.' + container_name: 'gedgo_app' + command: ['python', 'manage.py', 'runserver', '0.0.0.0:8000'] + volumes: + - './:/app' + links: + - 'db' + - 'redis' + web: + image: 'nginx' + command: 'nginx -g "daemon off;"' + volumes: + - './gedgo-web.conf:/etc/nginx/conf.d/gedgo-web.conf:ro' + - './files:/src/files:ro' + ports: + - '80:80' + links: + - 'app' + worker: + container_name: 'gedgo_worker' + image: 'gedgo_app' + command: ['python', 'manage.py', 'celeryd', '-c', '1', '--loglevel=info'] + volumes: + - './:/app' + links: + - 'app' + - 'db' + - 'redis' + depends_on: + - 'app' diff --git a/gedgo/gedcom_update.py b/gedgo/gedcom_update.py index 5f78c1c..1f4a017 100644 --- a/gedgo/gedcom_update.py +++ b/gedgo/gedcom_update.py @@ -27,11 +27,13 @@ def update(g, file_name, verbose=True): title=__child_value_by_tags(parsed.header, 'TITL', default=''), last_updated=datetime(1920, 1, 1) # TODO: Fix. ) + print g.id if verbose: print 'Importing entries to models' person_counter = family_counter = note_counter = 0 - for entry in parsed.entries.values(): + entries = parsed.entries.values() + for index, entry in enumerate(entries): tag = entry['tag'] if tag == 'INDI': @@ -44,6 +46,9 @@ def update(g, file_name, verbose=True): __process_Note(entry, g) note_counter += 1 + if (index + 1) % 100 == 0: + print ' ... %d / %d' % (index + 1, len(entries)) + if verbose: print 'Found %d people, %d families, %d notes, and %d documents' % ( person_counter, family_counter, note_counter, @@ -64,8 +69,9 @@ def __process_all_relations(gedcom, parsed, verbose=True): print ' Starting Person objects.' # Process Person objects - for person in gedcom.person_set.iterator(): + for index, person in enumerate(gedcom.person_set.iterator()): entry = parsed.entries.get(person.pointer) + print index if entry is not None: __process_person_relations(gedcom, person, entry) else: @@ -256,7 +262,7 @@ def __process_Document(entry, obj, g): m.docfile.name = file_name if kind == 'PHOTO': try: - make_thumbnail(name) + make_thumbnail(name, __child_value_by_tags(entry, 'CROP')) thumb = path.join('default/thumbs', name) except: print ' Warning: failed to make or find thumbnail: %s' % name @@ -362,7 +368,7 @@ def __valid_document_entry(e): return name -def make_thumbnail(name): +def make_thumbnail(name, crop): """ Copies an image from gedcom_storage, converts it to a thumbnail, and saves it to default_storage for fast access @@ -375,7 +381,7 @@ def make_thumbnail(name): im = Image.open(gedcom_storage.open(name)) width, height = im.size - # TODO: Use gedcom _CROP attribute to set the box + # TODO: Use crop argument if width > height: offset = (width - height) / 2 box = (offset, 0, offset + height, height) diff --git a/gedgo/static/styles/style-default.css b/gedgo/static/styles/style-default.css index ef765e9..aaca3d5 100644 --- a/gedgo/static/styles/style-default.css +++ b/gedgo/static/styles/style-default.css @@ -44,6 +44,9 @@ body { margin-left: auto; margin-right: auto; max-width: 100%; + min-width: 100%; + min-height: 100%; + max-height: 100%; margin-bottom: 10px; } .subsection-thumb { diff --git a/gedgo/storages.py b/gedgo/storages.py index 4fff6a7..3f63df3 100644 --- a/gedgo/storages.py +++ b/gedgo/storages.py @@ -3,13 +3,16 @@ from django.conf import settings from django.utils.module_loading import import_string +from cStringIO import StringIO import os -from dropbox.client import DropboxClient +from dropbox.dropbox import Dropbox +from dropbox.files import FileMetadata, FolderMetadata, ThumbnailFormat, \ + ThumbnailSize class DropboxStorage(Storage): def __init__(self, *args, **kwargs): - self.client = DropboxClient(settings.DROPBOX_ACCESS_TOKEN) + self.client = Dropbox(settings.DROPBOX_ACCESS_TOKEN) self.location = kwargs.get('location', settings.MEDIA_ROOT) def path(self, name): @@ -17,39 +20,53 @@ def path(self, name): def exists(self, name): try: - return isinstance(self.client.metadata(self.path(name)), dict) + return isinstance( + self.client.files_get_metadata(self.path(name)), + (FileMetadata, FolderMetadata) + ) except: return False def listdir(self, name): - meta = self.client.metadata(self.path(name)) - return self._list_from_contents(self.path(name), meta['contents']) + result = self.client.files_list_folder(self.path(name)) + return self._list_from_contents(self.path(name), result.entries) def _list_from_contents(self, path, contents): directories, files = [], [] for entry in contents: - name = entry['path'][len(path) + 1:] - if entry['is_dir']: - directories.append(name) - else: - files.append(name) + if isinstance(entry, FileMetadata): + files.append(entry.name) + if isinstance(entry, FolderMetadata): + directories.append(entry.name) return (directories, files) def open(self, name, mode='rb'): - return self.client.get_file(self.path(name)) + meta, resp= self.client.files_download(self.path(name)) + return resp.raw def size(self, name): - return self.client.metadata(self.path(name)).bytes + return self.client.files_get_metadata(self.path(name)).size def url(self, name): - return self.client.media(self.path(name))['url'] + url = self.client.files_get_temporary_link(self.path(name)).link + return url - def search(self, query, name=''): - contents = self.client.search(self.path(name), query) - return self._list_from_contents(self.path(name), contents) + def search(self, query, name='', start=0): + result = self.client.files_search(self.path(name), query, start) + directories, files = [], [] + for entry in result.matches: + if isinstance(entry.metadata, FileMetadata): + p = entry.metadata.path_display[len(self.location):] + files.append(p) + # Ignore directories for now + return (directories, files) - def preview(self, name): - return self.client.thumbnail(self.path(name), 's') + def preview(self, name, size='w64h64'): + return StringIO(self.client.files_get_thumbnail( + self.path(name), + format=ThumbnailFormat('jpeg', None), + size=ThumbnailSize(size, None) + )[1].content) class ResearchFileSystemStorage(FileSystemStorage): @@ -63,9 +80,6 @@ def search(self, query): files.append(os.path.join(r, f)) return directories, files - def preview(self, path): - raise NotImplementedError - research_storage = import_string(settings.GEDGO_RESEARCH_FILE_STORAGE)( location=settings.GEDGO_RESEARCH_FILE_ROOT) diff --git a/gedgo/templates/default/research.html b/gedgo/templates/default/research.html index 05b2a56..4644d92 100644 --- a/gedgo/templates/default/research.html +++ b/gedgo/templates/default/research.html @@ -9,7 +9,7 @@ @@ -18,9 +18,9 @@
- +
- {% if rquery %} clear{% endif %} + {% if rq %} clear{% endif %} {% endif %} @@ -28,15 +28,16 @@ {% endblock %} {% block content %} -{% if levels|length > 1 %} - Up a level + +{% if not directories and not files %} + No files here. {% endif %} -

{{ current_level }}

+ {% if directories %} {% endif %} + {% if directories and files %}
{% endif %} + {% if files %}