Skip to content
This repository was archived by the owner on Aug 1, 2022. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions browsepy/plugin/gallery/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os.path

from flask import Blueprint, render_template, jsonify, url_for
from werkzeug.exceptions import NotFound

from browsepy import stream_template, get_cookie_browse_sorting, \
browse_sortkey_reverse
from browsepy.file import OutsideDirectoryBase

from .images import ImageFile, ImageDirectory, \
detect_image_mimetype
from ... import open_file

__basedir__ = os.path.dirname(os.path.abspath(__file__))

gallery = Blueprint(
'gallery',
__name__,
url_prefix='/gallery',
template_folder=os.path.join(__basedir__, 'templates'),
static_folder=os.path.join(__basedir__, 'static'),
)


@gallery.route('/image/<path:path>')
def image(path):
try:
file = ImageFile.from_urlpath(path)
if file.is_file:
curdir = ImageDirectory.from_urlpath(os.path.dirname(path))
return stream_template(
'gallery.html',
file=file,
curdir=curdir
)

except OutsideDirectoryBase:
pass
return NotFound()


@gallery.route("/dirlist", defaults={"path": ""})
@gallery.route('/dirlist/<path:path>')
def directory_json(path):
sort_property = get_cookie_browse_sorting(path, 'text')
sort_fnc, sort_reverse = browse_sortkey_reverse(sort_property)
try:
file = ImageDirectory.from_urlpath(path)
return jsonify([dict(url=url_for("open", path=e.urlpath),
caption=e.title,
thumbnail=url_for("open", path=e.urlpath)) for e in sorted(file.entries(), key=lambda x: x.title) if isinstance(e, ImageFile)])

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're ignoring the user-configured sorting here, which could be okish, but then why are you getting it from browsepy?

except OutsideDirectoryBase:
pass
return NotFound()

@gallery.route("/directory", defaults={"path": ""})
@gallery.route('/directory/<path:path>')
def directory(path):
sort_property = get_cookie_browse_sorting(path, 'text')
sort_fnc, sort_reverse = browse_sortkey_reverse(sort_property)
try:
file = ImageDirectory.from_urlpath(path)
if file.is_directory:
return stream_template(
'gallery.html',
file=file,
sort_property=sort_property,
sort_fnc=sort_fnc,
sort_reverse=sort_reverse,
)
except OutsideDirectoryBase:
pass
return NotFound()


def register_arguments(manager):

@ergoithz ergoithz Dec 3, 2019

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can be removed if not used.

'''
Register arguments using given plugin manager.

This method is called before `register_plugin`.

:param manager: plugin manager
:type manager: browsepy.manager.PluginManager
'''

# Arguments are forwarded to argparse:ArgumentParser.add_argument,
# https://docs.python.org/3.7/library/argparse.html#the-add-argument-method
# manager.register_argument(
# '--player-directory-play', action='store_false',
# help='enable directories as playlist'
# )


def register_plugin(manager):
'''
Register blueprints and actions using given plugin manager.

:param manager: plugin manager
:type manager: browsepy.manager.PluginManager
'''
manager.register_blueprint(gallery)
manager.register_mimetype_function(detect_image_mimetype)

# add style tag
manager.register_widget(
place='styles',
type='stylesheet',
endpoint='gallery.static',
filename='css/browse.css'
)

# register link actions
manager.register_widget(
place='entry-link',
type='link',
endpoint='gallery.image',
filter=ImageFile.detect
)


# register action buttons
manager.register_widget(
place='entry-actions',
css='showimage',
type='button',
endpoint='gallery.image',
filter=ImageFile.detect
)

manager.register_widget(
place='header',
type='button',
endpoint='gallery.directory',
text='Show image gallery',
filter=ImageDirectory.detect
)
102 changes: 102 additions & 0 deletions browsepy/plugin/gallery/images.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@

import sys
import codecs
import os.path
import warnings

from werkzeug.utils import cached_property

from browsepy.compat import range, PY_LEGACY # noqa
from browsepy.file import Node, File, Directory, \
underscore_replace, check_under_base


if PY_LEGACY:
import ConfigParser as configparser
else:
import configparser

ConfigParserBase = (
configparser.SafeConfigParser
if hasattr(configparser, 'SafeConfigParser') else
configparser.ConfigParser
)


class ImageBase(File):
extensions = {
'png': 'image/png',
'jpg': 'image/jpg',
'gif': 'image/gif'
}

@classmethod
def extensions_from_mimetypes(cls, mimetypes):
mimetypes = frozenset(mimetypes)
return {
ext: mimetype
for ext, mimetype in cls.extensions.items()
if mimetype in mimetypes
}

@classmethod
def detect(cls, node, os_sep=os.sep):
basename = node.path.rsplit(os_sep)[-1]
if '.' in basename:
ext = basename.rsplit('.')[-1].lower().strip()
return cls.extensions.get(ext, None)
return None


class ImageFile(ImageBase):
mimetypes = ['image/png', 'image/jpg', 'image/gif']
extensions = ImageBase.extensions_from_mimetypes(mimetypes)
media_map = {mime: ext for ext, mime in extensions.items()}

def __init__(self, path, **kwargs):
super(ImageFile, self).__init__(path=path, **kwargs)
#TODO: read exif
self.title = os.path.basename(path)

@property
def title(self):
return self._title or self.name

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property self._title can be, potentially, undefined on this class, even if this class usage avoids it right now.


@title.setter
def title(self, title):
self._title = title

@property
def media_format(self):
return self.media_map[self.type]


class ImageDirectory(Directory):
file_class = ImageFile
name = ''

@cached_property
def parent(self):
return Directory(self.path)

@classmethod
def detect(cls, node):
if node.is_directory:
for file in node._listdir():
if ImageFile.detect(file):
return cls.mimetype
return None

def entries(self, sortkey=None, reverse=None):
listdir_fnc = super(ImageDirectory, self).listdir
for file in listdir_fnc(sortkey=sortkey, reverse=reverse):
if ImageFile.detect(file):
yield file


def detect_image_mimetype(path, os_sep=os.sep):
basename = path.rsplit(os_sep)[-1]
if '.' in basename:
ext = basename.rsplit('.')[-1]
return ImageBase.extensions.get(ext, None)
return None
3 changes: 3 additions & 0 deletions browsepy/plugin/gallery/static/css/browse.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a.button.showimage:after {
content: "\1f5bc";
}
Loading