2

ユーザーに代わっていくつかのサーバーファイルシステム(たとえば、/ fs01、/ fs02など)にアクセスして操作するDjangoWebアプリケーションがあります。これらのファイルシステム上の画像のサムネイルをユーザーに提示したいのですが、それを行うにはsorl-thumbnailが最適だと思いました。

sorl-thumbnailがサムネイルを作成するには、画像がMEDIA_ROOTの下にある必要があるようです。私MEDIA_ROOT/Users/me/Dev/MyProject/myproj/mediaですので、これは機能します:

path = "/Users/me/Dev/MyProject/myproj/media/pipe-img/magritte-pipe-large.jpg"
try:
  im = get_thumbnail(path, '100x100', crop='center', quality=99)
except Exception, e:
  exc_type, exc_obj, exc_tb = sys.exc_info()
  print "Failed getting thumbnail: (%s) %s" % (exc_type, e)
print "im.url = %s" % im.url

予想どおり、サムネイルを作成し、im.urlを印刷します。しかし、私がに変更pathすると:

path = "/fs02/dir/ep340102/foo/2048x1024/magritte-pipe-large.jpg"

それは失敗します:

Failed getting thumbnail: (<class 'django.core.exceptions.SuspiciousOperation'>)
Attempted access to '/fs02/dir/ep340102/foo/2048x1024/magritte-pipe-large.jpg' denied.

これを解決する方法はありますか?これらの他のファイルシステム(/ fs01、/ fs02、/ fs03など)で必要に応じて、sorl-thumbnailを使用してサムネイルを作成できますか?より良いアプローチはありますか?

アップデート。 完全なスタックトレースは次のとおりです。

Environment:


Request Method: GET
Request URL: http://localhost:8000/pipe/file_selection/

Django Version: 1.4.1
Python Version: 2.7.2
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.admin',
 'django.contrib.admindocs',
 'django.contrib.humanize',
 'django.contrib.messages',
 'pipeproj.pipe',
 'south',
 'guardian',
 'sorl.thumbnail')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  20.                 return view_func(request, *args, **kwargs)
File "/Users/dylan/Dev/Pipe/pipeproj/../pipeproj/pipe/views/data.py" in file_selection
  184.  im = get_thumbnail(path, '100x100', crop='center', quality=99)
File "/Library/Python/2.7/site-packages/sorl_thumbnail-11.12-py2.7.egg/sorl/thumbnail/shortcuts.py" in get_thumbnail
  8.     return default.backend.get_thumbnail(file_, geometry_string, **options)
File "/Library/Python/2.7/site-packages/sorl_thumbnail-11.12-py2.7.egg/sorl/thumbnail/base.py" in get_thumbnail
  56.             source_image = default.engine.get_image(source)
File "/Library/Python/2.7/site-packages/sorl_thumbnail-11.12-py2.7.egg/sorl/thumbnail/engines/pil_engine.py" in get_image
  12.         buf = StringIO(source.read())
File "/Library/Python/2.7/site-packages/sorl_thumbnail-11.12-py2.7.egg/sorl/thumbnail/images.py" in read
  121.         return self.storage.open(self.name).read()
File "/Library/Python/2.7/site-packages/django/core/files/storage.py" in open
  33.         return self._open(name, mode)
File "/Library/Python/2.7/site-packages/django/core/files/storage.py" in _open
  156.         return File(open(self.path(name), mode))
File "/Library/Python/2.7/site-packages/django/core/files/storage.py" in path
  246.             raise SuspiciousOperation("Attempted access to '%s' denied." % name)

Exception Type: SuspiciousOperation at /pipe/file_selection/
Exception Value: Attempted access to '/fs02/dir/ep340102/foo/2048x1024/bettina.jpg' denied.
4

3 に答える 3

4

SuspiciousOperationは、FileSystemStorage.path()からのものです。

def path(self, name):
try:
    path = safe_join(self.location, name)
except ValueError:
    raise SuspiciousFileOperation("Attempted access to '%s' denied." % name)
return os.path.normpath(path)

これは、次のテストを行うsafe_join()で発生します。

if (not normcase(final_path).startswith(normcase(base_path + sep)) and
...

これは、計算されたファイル名が構成されたサムネイルストレージ内に存在する必要があることを意味します。デフォルトでは、settings.THUMBNAIL_STORAGEはsettings.DEFAULT_FILE_STORAGEであり、これはファイルをsettings.MEDIA_ROOTに格納するFileSystemStorageです。

ストレージクラスを定義することで、サムネイルに別のストレージパスを使用できるようになります。

from django.core.files.storage import FileSystemStorage

class ThumbnailStorage(FileSystemStorage):
    def __init__(self, **kwargs):
        super(ThumbnailStorage, self).__init__(
            location='/fs02', base_url='/fs02')

次にsettings.pyで

THUMBNAIL_STORAGE = 'myproj.storage.ThumbnailStorage'

また、そのURLで何かが/fs02を提供していることを確認する必要があります。

if settings.DEBUG:
    patterns += patterns('',
        url(r'^fs02/(?P<path>.*)$', 'django.views.static.serve',
            {'document_root': '/fs02'}))

サムネイルは、デフォルトのTHUMBNAIL_PREFIXに従って/ fs02 / cache/...として作成されることに注意してください。

于 2013-08-29T11:28:53.663 に答える
0

次のコマンドで何が得られますか?

ls -la /fs02/dir/ep340102/foo/2048x1024/

アクセス拒否は通常、ファイル所有者が適切でない場合(および/またはファイル権限が間違っている場合)に発生します...

于 2013-02-12T00:53:57.003 に答える
0

代わりに、次のように絶対URLを指定して実行しました。

from sorl.thumbnail import get_thumbnail
from django.contrib.staticfiles.storage import staticfiles_storage

image_url = staticfiles_storage.url('image.jpg')
thumbnail = get_thumbnail(image_url, '100x100')
于 2014-09-10T09:47:14.170 に答える