/usr/share/pyshared/elisa/plugins/base/models/image.py is in moovida-plugins-good 1.0.9+bzr1614-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | # -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.
#
# Authors: Benjamin Kampmann <benjamin@fluendo.com>
# Olivier Tilloy <olivier@fluendo.com>
# Philippe Normand <philippe@fluendo.com>
"""
Common models related to image.
"""
from elisa.core import common
from elisa.core.components.model import Model
from elisa.core.utils.i18n import install_translation
from elisa.core.utils import defer, caching
import os.path
from math import pi
ROTATED_0=1
HORIZ_MIRROR=2
ROTATED_180=3
VERT_MIRROR=4
HORIZ_MIRROR_ROTATED_90_CCW=5
ROTATED_90_CW=6
HORIZ_MIRROR_ROTATED_90_CW=7
ROTATED_90_CCW=8
_ = install_translation('base')
# Constants detailing the various possible Image orientations
# These come from the EXIF spec and contain PgmImage rotation settings
# for earch orientation value.
IMAGE_ORIENTATIONS={ROTATED_0: (_('Horizontal (normal)'),
{'rx': 0, 'ry': 0, 'rz': 0}),
HORIZ_MIRROR: (_('Mirrored horizontally'),
{'rx': 0, 'ry': pi, 'rz': 0}),
ROTATED_180: (_('Rotated 180°'), {'rx': 0, 'ry': 0, 'rz': pi}),
VERT_MIRROR: (_('Mirrored vertically'),
{'rx': pi, 'ry': 0, 'rz': 0}),
HORIZ_MIRROR_ROTATED_90_CCW: (_('Mirrored horizontally then rotated 90° counter-clock-wise'),
{'rx': 0, 'ry': pi, 'rz': pi * 1.5}),
ROTATED_90_CW: (_('Rotated 90° clock-wise'),
{'rx': 0, 'ry': 0, 'rz': pi * 0.5}),
HORIZ_MIRROR_ROTATED_90_CW: (_('Mirrored horizontally then rotated 90° clock-wise'),
{'rx': 0, 'ry': pi, 'rz': pi * 0.5}),
ROTATED_90_CCW: (_('Rotated 90° counter-clock-wise'),
{'rx': 0, 'ry': 0, 'rz': pi * 1.5})
}
class ImageModel(Model):
"""
Representation of an image.
An image model contains a list of references to image files that are in
fact one image in various dimensions.
This list is ordered by increasing size of image.
This allows to easily retrieve the largest or the smallest representation
of an image.
'A simple example': the image is used as the cover art of an
L{elisa.plugins.base.models.audio.AlbumModel}. A resource provider fills
this image model with a thumbnail and a huge high contrast image. Now the
UI can decide that it does not want to show such a high quality image
because it is going to be used as an icon in a list. It uses
C{model.cover.references[0]} (the first one, the smallest image) and the
amount of data to load is minimal. Later the user decides to play a track
of the album and the UI wants to show it in fullscreen, it always uses the
last image in the list because it is the largest one (and very probably the
one with the best quality for a huge picture):
C{model.cover.references[-1]}.
@ivar references: images ordered by increasing size of raw data
@type references: C{list} of L{elisa.core.media_uri.MediaUri}
@ivar orientation: orientation of the image, its meaning is the same as
the orienation EXIF field
@type orientation: one of the keys of C{IMAGE_ORIENTATIONS}
@ivar can_rotate: can the image represented by the model be rotated?
@type can_rotate: C{bool}
"""
def __init__(self):
"""
Constructor. Initialize all the fields.
"""
super(ImageModel, self).__init__()
self.references = []
self.orientation = ROTATED_0
self.can_rotate = True
def get_cached_data_path(self, reference_num):
"""
Return the path to the locally cached reference.
If needed, retrieve and cache it first.
@param reference_num: the index of the reference
@type reference_num: C{int}
@return: a deferred fired when done with the path to the cached file
@rtype: L{elisa.core.utils.defer.Deferred} fired with a C{unicode}
"""
uri = self.references[reference_num]
path = caching.get_cached_image_path(uri)
if os.path.exists(path):
# already cached
return defer.succeed(path)
model, dfr = common.application.resource_manager.get(uri)
dfr.addCallback(lambda model: caching.cache_to_file(model.data, path))
return dfr
|