123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- from django.shortcuts import render
- from django.utils.translation import gettext as _
- import geo
- import mimetypes
- from ..models import get_item_type, get_item_by_rel_path, TYPE_AUDIO, TYPE_FOLDER, TYPE_IMAGE, TYPE_OTHER, TYPE_VIDEO
- import os
- import pygal
- from ..queries import search_result_query
- import random
- import stringtools
- import themes
-
- ADDTAG_ENTRY = 'addtag-main'
- INFOVIEW_ENTRY = 'infoview-main'
- DOWNLOAD_ENTRY = 'download-main'
- DOWNLOAD_FLAT_ENTRY = 'download-flat-sub'
- DOWNLOAD_STRUCT_ENTRY = 'download-struct-sub'
- FAVOURITE_ENTRY = 'favourite-main'
- REPEAT_ENTRY = 'repeat-main'
- SHUFFLE_ENTRY = 'shuffle-main'
-
-
- class ItemDoesNotEsistWithinParent(Exception):
- pass
-
-
- def get_wrapper_class(full_path):
- return {
- TYPE_FOLDER: folder_view,
- TYPE_IMAGE: image_view,
- TYPE_VIDEO: video_view,
- TYPE_AUDIO: audio_view,
- TYPE_OTHER: other_view,
- }.get(get_item_type(full_path), base_view)
-
-
- def get_wrapper_instance(full_path, request, is_nxt_prv_item=False):
- return get_wrapper_class(full_path)(request, full_path, is_nxt_prv_item)
-
-
- def random_copy(request, lst):
- shuffle_id = pygal.get_shuffle_id(request)
- #
- rv = lst[:]
- if shuffle_id is not None:
- r = random.Random()
- r.seed(shuffle_id)
- r.shuffle(rv)
- return rv
-
-
- class base_view(object):
- def __init__(self, request, full_path, is_nxt_prv_item):
- self.request = request
- self.full_path = full_path
- self.is_nxt_prv_item = is_nxt_prv_item
- #
- self.item = get_item_by_rel_path(pygal.get_rel_path(full_path))
- if self.item is None:
- raise LookupError("Error while initialising base_view, but item for %s does not exist." % full_path)
- self.is_item = self.item.type != TYPE_FOLDER
- #
- self.mime_type = mimetypes.types_map.get(os.path.splitext(self.full_path)[1])
- self.template = 'pygal/empty.html'
-
- @property
- def tags(self):
- return self.item.tag_set.all()
-
- def may_read(self):
- return self.item.may_read(self.request.user)
-
- def may_modify(self):
- return self.item.may_modify(self.request.user)
-
- def context_adaption(self, context):
- context['item'] = self
- context['thumbnail_size'] = pygal.get_thumbnail_size(self.request)
- context['title'] = self.name or ''
- context[context.ACTIONBAR].extend(self.actionbar)
-
- @property
- def heading(self):
- return '%s' % self.item.name
-
- @property
- def general_information(self):
- rv = []
- full_path = pygal.get_full_path(self.item.rel_path)
- rv.append({'description': _('Name'), 'data': os.path.basename(full_path), 'url': None})
- rv.append({'description': _('Creation Time'), 'data': self.item.item_data.formatted_datetime, 'url': None})
- rv.append({'description': _('Path'), 'data': os.path.dirname(full_path), 'url': None})
- rv.append({'description': _('Size'), 'data': stringtools.physical_value_repr(self.item.item_data.size, 'B'), 'url': None})
- rv.append({'description': _('UID'), 'data': self.item.current_uid(), 'url': None})
- return rv
-
- def __actionbar__(self):
- b = themes.bar()
- if self.is_item:
- if self.is_my_favourite:
- b.append_entry(
- FAVOURITE_ENTRY,
- '',
- themes.color_icon_url(self.request, 'is_favourite.png'),
- pygal.url_favourite_unset(self.request, self.item.rel_path),
- True,
- False
- )
- else:
- b.append_entry(
- FAVOURITE_ENTRY,
- '',
- themes.color_icon_url(self.request, 'favourite.png'),
- pygal.url_favourite_set(self.request, self.item.rel_path),
- True,
- False
- )
- if pygal.is_infoview(self.request):
- b.append_entry(
- INFOVIEW_ENTRY,
- _('Info'),
- themes.color_icon_url(self.request, 'info.png'),
- pygal.url_infoview(self.request, self.item.rel_path),
- True,
- True
- )
- else:
- b.append_entry(
- INFOVIEW_ENTRY,
- _('Info'),
- themes.color_icon_url(self.request, 'info.png'),
- pygal.url_infoview(self.request, self.item.rel_path, search=pygal.SEARCH_KEEP),
- True,
- False
- )
- b.append_entry(
- DOWNLOAD_ENTRY,
- _('Download'),
- themes.color_icon_url(self.request, 'download.png'),
- pygal.url_download(self.request, self.item.rel_path),
- True,
- False
- )
- if type(self) is not folder_view:
- if pygal.is_repeatview(self.request):
- b.append_entry(
- REPEAT_ENTRY,
- _('Repeat'),
- themes.color_icon_url(self.request, 'stop.png'),
- pygal.url_userview(self.request, self.item.rel_path, search=pygal.SEARCH_KEEP),
- True,
- True
- )
- else:
- b.append_entry(
- REPEAT_ENTRY,
- _('Repeat'),
- themes.color_icon_url(self.request, 'play.png'),
- pygal.url_repeatview(self.request, self.item.rel_path),
- True,
- False
- )
- if pygal.get_shuffle_id(self.request) is None:
- b.append_entry(
- SHUFFLE_ENTRY,
- _('Shuffle'),
- themes.color_icon_url(self.request, 'shuffle.png'),
- pygal.url_userview(self.request, self.item.rel_path, shuffle=pygal.SHUFFLE_ENABLE, search=pygal.SEARCH_KEEP),
- True,
- False
- )
- else:
- b.append_entry(
- SHUFFLE_ENTRY,
- _('Shuffle'),
- themes.color_icon_url(self.request, 'shuffle.png'),
- pygal.url_userview(self.request, self.item.rel_path, shuffle=pygal.SHUFFLE_DISABLE, search=pygal.SEARCH_KEEP),
- True,
- True
- )
- if self.is_item and self.may_modify():
- b.append_entry(
- ADDTAG_ENTRY,
- _('Add Tag'),
- themes.color_icon_url(self.request, 'edit2.png'),
- pygal.url_addtag(self.request, self.item.rel_path),
- True,
- False
- )
- return b
-
- @property
- def is_my_favourite(self):
- return self.request.user in self.item.favourite_of.all()
-
- @property
- def actionbar(self):
- return self.__actionbar__()
-
- def __tagbar__(self):
- b = themes.bar(self.request)
- i = 0
- for t in self.item.tag_set.all():
- i += 1
- edit_url = pygal.url_tagedit(self.request, t.id) if self.may_modify() else None
- search_query = 'tag:%s' % t.text
- search_url = pygal.url_userview(self.request, '', search=search_query)
- b.append_entry('tag-%d' % i, t.text, themes.color_icon_url(self.request, '%d.png' % (i % 10)), edit_url, True, False)
- if pygal.get_search_query(self.request) != search_query:
- b.append_entry_to_entry('tag-%d' % i, 'tagedit-%d' % i, _('Edit'), themes.gray_icon_url(self.request, 'edit2.png'), edit_url, True, False)
- b.append_entry_to_entry('tag-%d' % i, 'tagsearch-%d' % i, _('Search'), themes.gray_icon_url(self.request, 'search.png'), search_url, True, False)
- return b
-
- @property
- def tagbar(self):
- return self.__tagbar__()
-
- @property
- def duration(self):
- return self.item.item_data.duration + 1.5
-
- @property
- def url_item(self):
- return pygal.url_item(self.request, self.item.rel_path)
-
- @property
- def url_repeatview(self):
- return pygal.url_repeatview(self.request, self.item.rel_path)
-
- @property
- def is_repeatview(self):
- return pygal.is_repeatview(self.request)
-
- @property
- def url_thumbnail(self):
- return pygal.url_thumbnail(self.request, self.item.rel_path)
-
- @property
- def url_userview(self):
- if self.is_nxt_prv_item:
- return pygal.url_userview(self.request, self.item.rel_path, search=pygal.SEARCH_KEEP, repeat=pygal.REPEAT_KEEP)
- else:
- return pygal.url_userview(self.request, self.item.rel_path, search=pygal.SEARCH_KEEP, repeat=pygal.REPEAT_DISABLE)
-
- @property
- def url_webnail(self):
- return pygal.url_webnail(self.request, self.item.rel_path)
-
- @property
- def name(self):
- return self.item.name
-
- @property
- def date_txt(self):
- return self.item.item_data.formatted_datetime
-
- def __parent__(self):
- if pygal.is_searchview(self.request) or pygal.is_favouriteview(self.request):
- return query_view(self.request, search_result_query(self.request))
- else:
- return get_wrapper_instance(os.path.dirname(self.full_path), self.request)
-
- def __nxt_prv__(self, direction):
- if direction not in [-1, 1]:
- raise ValueError("Parameter direction is incorrect: %s" % repr(direction))
- fp_il = random_copy(self.request, self.__parent__().sorted_fullpathlist())
- try:
- i = fp_il.index(self.full_path)
- except ValueError as e:
- raise ItemDoesNotEsistWithinParent(e)
- lgt = len(fp_il)
- for i in range(i + direction, i + direction * lgt, direction):
- full_path = fp_il[i % lgt]
- if get_item_type(full_path) != TYPE_FOLDER:
- return get_wrapper_instance(full_path, self.request, is_nxt_prv_item=True)
- return self
-
- @property
- def nxt(self):
- return self.__nxt_prv__(1)
-
- @property
- def prv(self):
- return self.__nxt_prv__(-1)
-
- def render(self, context):
- return render(self.request, self.template, context=context)
-
-
- class query_view(object):
- def __init__(self, request, query):
- self.request = request
- self.query = query
- #
- self.template = 'pygal/overview.html'
- #
- self.__item_list__ = None
-
- def context_adaption(self, context):
- context['item'] = self
- context['thumbnail_size'] = pygal.get_thumbnail_size(self.request)
- context['title'] = self.name or ''
- context[context.ACTIONBAR].extend(self.actionbar)
-
- @property
- def name(self):
- if pygal.is_favouriteview(self.request):
- return _('My Favourites')
- elif pygal.is_searchview(self.request):
- return _('Search: "%s"' % pygal.get_search_query(self.request))
- else:
- return '-'
-
- def __actionbar__(self):
- b = themes.bar()
- if pygal.is_infoview(self.request):
- b.append_entry(
- INFOVIEW_ENTRY,
- _('Info'),
- themes.color_icon_url(self.request, 'info.png'),
- pygal.url_infoview(self.request, ''),
- True,
- True
- )
- else:
- b.append_entry(
- INFOVIEW_ENTRY,
- _('Info'),
- themes.color_icon_url(self.request, 'info.png'),
- pygal.url_infoview(self.request, ''),
- True,
- False
- )
- b.append_entry(
- DOWNLOAD_ENTRY,
- _('Download'),
- themes.color_icon_url(self.request, 'download.png'),
- None,
- True,
- False
- )
- b.append_entry_to_entry(
- DOWNLOAD_ENTRY,
- DOWNLOAD_STRUCT_ENTRY,
- _('Download (Structured)'),
- themes.gray_icon_url(self.request, 'download.png'),
- pygal.url_download(self.request, ''),
- True,
- False
- )
- b.append_entry_to_entry(
- DOWNLOAD_ENTRY,
- DOWNLOAD_FLAT_ENTRY,
- _('Download (Flat)'),
- themes.gray_icon_url(self.request, 'download.png'),
- pygal.url_download(self.request, '', flat=True),
- True,
- False
- )
- if pygal.get_shuffle_id(self.request) is None:
- b.append_entry(
- SHUFFLE_ENTRY,
- _('Shuffle'),
- themes.color_icon_url(self.request, 'shuffle.png'),
- pygal.url_userview(self.request, '', shuffle=pygal.SHUFFLE_ENABLE, search=pygal.SEARCH_KEEP),
- True,
- False
- )
- else:
- b.append_entry(
- SHUFFLE_ENTRY,
- _('Shuffle'),
- themes.color_icon_url(self.request, 'shuffle.png'),
- pygal.url_userview(self.request, '', shuffle=pygal.SHUFFLE_DISABLE, search=pygal.SEARCH_KEEP),
- True,
- True
- )
- return b
-
- @property
- def actionbar(self):
- return self.__actionbar__()
-
- def sorted_fullpathlist(self):
- il = []
- for item_model in self.query:
- if item_model.may_read(self.request.user):
- il.append(item_model)
- il.sort(key=lambda entry: entry.sort_string(), reverse=True)
- return [pygal.get_full_path(i.rel_path) for i in il]
-
- def __init_itemlist__(self):
- if self.__item_list__ is None:
- self.__item_list__ = []
- for full_path in self.sorted_fullpathlist():
- w = get_wrapper_instance(full_path, self.request)
- self.__item_list__.append(w)
-
- @property
- def item_list(self):
- self.__init_itemlist__()
- return random_copy(self.request, self.__item_list__)
-
- def render(self, context):
- return render(self.request, self.template, context=context)
-
-
- class folder_view(base_view):
- def __init__(self, *args, **kwargs):
- base_view.__init__(self, *args, **kwargs)
- #
- self.template = 'pygal/overview.html'
- #
- self.__item_list__ = None
-
- def __actionbar__(self):
- b = base_view.__actionbar__(self)
- b.append_entry_to_entry(
- DOWNLOAD_ENTRY,
- DOWNLOAD_STRUCT_ENTRY,
- _('Download (Structured)'),
- themes.gray_icon_url(self.request, 'download.png'),
- pygal.url_download(self.request, self.item.rel_path),
- True,
- False
- )
- b.append_entry_to_entry(
- DOWNLOAD_ENTRY,
- DOWNLOAD_FLAT_ENTRY,
- _('Download (Flat)'),
- themes.gray_icon_url(self.request, 'download.png'),
- pygal.url_download(self.request, self.item.rel_path, flat=True),
- True,
- False
- )
- return b
-
- def sorted_fullpathlist(self):
- return [pygal.get_full_path(i.rel_path) for i in self.item.sorted_itemlist()]
-
- def __init_fullpathlist__(self):
- if self.__item_list__ is None:
- self.__item_list__ = []
- for full_path in self.sorted_fullpathlist():
- w = get_wrapper_instance(full_path, self.request)
- self.__item_list__.append(w)
-
- @property
- def item_list(self):
- self.__init_fullpathlist__()
- return random_copy(self.request, self.__item_list__)
-
- @property
- def url_thumbnail(self):
- return pygal.url_thumbnail(self. request, self.item.thumbnail_item().rel_path)
-
-
- class image_view(base_view):
- def __init__(self, *args, **kwargs):
- base_view.__init__(self, *args, **kwargs)
- #
- self.template = 'pygal/image.html'
-
- def __actionbar__(self):
- b = base_view.__actionbar__(self)
- gps_data = self.item.item_data.gps
- if gps_data is not None:
- b.append_entry(
- 'actionbar-gpslink',
- _('GPS'),
- themes.color_icon_url(self.request, 'gps.png'),
- geo.osm.landmark_link(geo.gps.coordinate(**gps_data)),
- True,
- False
- )
- return b
-
- @property
- def width(self):
- if self.item.item_data.orientation in [5, 6, 7, 8]:
- return self.item.item_data.height
- else:
- return self.item.item_data.width
-
- @property
- def height(self):
- if self.item.item_data.orientation in [5, 6, 7, 8]:
- return self.item.item_data.width
- else:
- return self.item.item_data.height
-
-
- class video_view(base_view):
- def __init__(self, *args, **kwargs):
- base_view.__init__(self, *args, **kwargs)
- #
- self.template = 'pygal/video.html'
-
- @property
- def use_internal_player(self):
- return self.mime_type in [mimetypes.types_map.get(ext) for ext in ['.mp4', '.webm', '.ogv', '.flv', '.3gp', ]]
-
- @property
- def webnail_width(self):
- w, h = self.item.item_data.width, self.item.item_data.height
- return int(pygal.get_webnail_size(self.request) * w / max(w, h))
-
- @property
- def webnail_height(self):
- w, h = self.item.item_data.width, self.item.item_data.height
- return int(pygal.get_webnail_size(self.request) * h / max(w, h))
-
-
- class audio_view(base_view):
- def __init__(self, *args, **kwargs):
- base_view.__init__(self, *args, **kwargs)
- #
- self.template = 'pygal/audio.html'
-
- @property
- def heading(self):
- return '%02d - %s' % (self.item.item_data.track, self.item.item_data.title)
-
- @property
- def audio_information(self):
- rv = []
- entries = (
- (_('Artist'), self.item.artist_c),
- (_('Album'), self.item.album_c),
- (_('Year'), self.item.year_c),
- (_('Title'), self.item.title_c),
- (_('Duration'), stringtools.time_repr(self.item.duration_c)),
- )
- for description, data in entries:
- if data is not None:
- rv.append({'description': description, 'data': data, 'url': None})
- return rv
-
-
- class other_view(base_view):
- def __init__(self, *args, **kwargs):
- base_view.__init__(self, *args, **kwargs)
- #
- self.template = 'pygal/other.html'
|