diff --git a/gedgo/storages.py b/gedgo/storages.py index d5a2c58..d9b2124 100644 --- a/gedgo/storages.py +++ b/gedgo/storages.py @@ -1,4 +1,4 @@ -from django.core.files.storage import Storage +from django.core.files.storage import Storage, FileSystemStorage from django.utils._os import safe_join from django.conf import settings from django.utils.module_loading import import_string @@ -15,25 +15,19 @@ def __init__(self, *args, **kwargs): def path(self, name): return safe_join(self.location, name) - def created_time(self, name): - raise NotImplementedError - def exists(self, name): try: return isinstance(self.client.metadata(self.path(name)), dict) except: return False - def get_available_name(self, name): - raise NotImplementedError - - def get_valid_name(self, name): - raise NotImplementedError - def listdir(self, path): meta = self.client.metadata(self.path(path)) + return self._list_from_contents(meta['contents']) + + def _list_from_contents(self, contents): directories, files = [], [] - for entry in meta['contents']: + for entry in contents: name = os.path.basename(entry['path']) if entry['is_dir']: directories.append(name) @@ -41,21 +35,37 @@ def listdir(self, path): files.append(name) return (directories, files) - def modified_time(self, name): - raise NotImplementedError - def open(self, name, mode='rb'): return self.client.get_file(self.path(name)) - def save(self, name, content, max_length=None): - raise NotImplementedError - def size(self, name): return self.client.metadata(self.path(name)).bytes def url(self, name): return self.client.media(self.path(name))['url'] + def search(self, query): + contents = self.client.search(self.path(''), query) + return self._list_from_contents(contents) + + def preview(self, name): + return self.client.preview(self.path(name)) + + +class ResearchFileSystemStorage(FileSystemStorage): + def search(self, query): + terms = [term for term in query.lower().split()] + directories, files = [], [] + for root, ds, fs in os.walk(self.location): + r = root[len(self.location) + 1:] + for f in fs: + if all([(t in f.lower()) for t in terms]): + 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/views/research.py b/gedgo/views/research.py index c4610c5..4d63e96 100644 --- a/gedgo/views/research.py +++ b/gedgo/views/research.py @@ -21,8 +21,8 @@ def research(request, pathname): return serve_content(storage, name) else: directories, files = storage.listdir(name) - directories = [__process(name, d, True) for d in directories] - files = [__process(name, f, False) for f in files] + directories = [process_file(name, d, True) for d in directories] + files = [process_file(name, f, False) for f in files] # Build a depth tree of the directories above this one for # navigation @@ -47,7 +47,7 @@ def research(request, pathname): raise Http404 -def __process(name, p, is_dir=False): +def process_file(name, p, is_dir=False): type_ = 'folder_open' if is_dir else _get_type(p) return { 'type': type_, diff --git a/gedgo/views/search.py b/gedgo/views/search.py index 02f8a73..554cca2 100644 --- a/gedgo/views/search.py +++ b/gedgo/views/search.py @@ -1,10 +1,14 @@ from django.contrib.auth.decorators import login_required from django.shortcuts import redirect from django.db.models import Q +from django.http import Http404 +from gedgo.storages import research_storage from gedgo.models import Gedcom, Person, BlogPost +from gedgo.views.research import process_file from gedgo.views.util import render +import os import re TERMS_RE = re.compile('\w+') @@ -12,6 +16,37 @@ @login_required def search(request): + kind = request.GET.get('kind') + if kind == 'blog': + return _blog(request) + if kind == 'files': + return _files(request) + return _people(request) + + +def _files(request): + _, files = research_storage.search(request.GET.get('q', '')) + files = [ + process_file(os.path.dirname(f), os.path.basename(f), False) + for f in files + ] + levels = [('Search: ' + request.GET.get('q', '') + ' ', '')] + return render( + request, + 'research.html', + { + 'directories': [], + 'files': files, + 'levels': levels + } + ) + + +def _blog(request): + raise Http404 + + +def _people(request): g = Gedcom.objects.first() context = { 'people': Person.objects.none(), @@ -26,28 +61,22 @@ def search(request): terms = TERMS_RE.findall(q) people = Person.objects.all() - posts = BlogPost.objects.all() for term in terms: people &= Person.objects.filter( Q(last_name__icontains=term) | Q(first_name__icontains=term) | Q(suffix__icontains=term) ) - posts &= BlogPost.objects.filter( - Q(title__icontains=term) | - Q(body__icontains=term) - ) - people = people.order_by('-pointer') + people = people.order_by('-pointer') # If there's only a single person, just go directly to the details view - if people.count() == 1 and not posts.exists(): + if people.count() == 1: person = people.first() return redirect( '/gedgo/%d/%s' % (person.gedcom.id, person.pointer) ) context['people'] = people - context['posts'] = posts context['query'] = q return render( request,