Как вы используете загрузку изображений и браузер FCKEditor с mod-wsgi? - PullRequest
1 голос
/ 29 апреля 2009

Я использую FCKEditor в приложении Django, обслуживаемом Apache / mod-wsgi. Я не хочу устанавливать php только для FCKEditor и вижу, что FCKEditor предлагает загрузку изображений и просмотр изображений через Python. Я просто не нашел хороших инструкций о том, как все это настроить.

Так что в настоящее время Django работает через интерфейс wsgi, используя эту настройку:

import os, sys

DIRNAME = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-3])
sys.path.append(DIRNAME)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

В fckeditor в каталоге editor-> filemanager-> connectors-> py есть файл wsgi.py:

from connector import FCKeditorConnector
from upload import FCKeditorQuickUpload

import cgitb
from cStringIO import StringIO

# Running from WSGI capable server (recomended)
def App(environ, start_response):
    "WSGI entry point. Run the connector"
    if environ['SCRIPT_NAME'].endswith("connector.py"):
        conn = FCKeditorConnector(environ)
    elif environ['SCRIPT_NAME'].endswith("upload.py"):
        conn = FCKeditorQuickUpload(environ)
    else:
        start_response ("200 Ok", [('Content-Type','text/html')])
        yield "Unknown page requested: "
        yield environ['SCRIPT_NAME']
        return
    try:
        # run the connector
        data = conn.doResponse()
        # Start WSGI response:
        start_response ("200 Ok", conn.headers)
        # Send response text
        yield data
    except:
        start_response("500 Internal Server Error",[("Content-type","text/html")])
        file = StringIO()
        cgitb.Hook(file = file).handle()
    yield file.getvalue()

Мне нужно, чтобы эти две вещи работали вместе путем изменения моего файла django wsgi для правильного обслуживания частей fckeditor или для того, чтобы apache правильно обслуживал django и fckeditor в одном домене.

Ответы [ 2 ]

1 голос
/ 04 мая 2009

Здесь описывается, как встроить редактор FCK и включить загрузку изображений.

Сначала вам нужно отредактировать fckconfig.js, чтобы изменить загрузку изображения. URL-адрес, указывающий на какой-либо URL-адрес внутри вашего сервера.

FCKConfig.ImageUploadURL = "/myapp/root/imageUploader";

Это будет указывать на относительный URL-адрес сервера для получения загрузки. FCK отправит загруженный файл этому обработчику, используя переменную CGI имя "NewFile" закодировано с использованием multipart / form-data. К сожалению ты придется реализовать / myapp / root / imageUploader, потому что я не думаю, дистрибутив FCK может быть легко адаптирован к другим средам.

imageUploader должен извлечь NewFile и сохранить его где-то на сервере. Ответ, сгенерированный / myapp / root / imageUploader, должен эмулировать HTML-код, созданный в /editor/.../fckoutput.py. Как то так (формат шаблона whiff)

{{env
    whiff.content_type: "text/html",
    whiff.headers: [
        ["Expires","Mon, 26 Jul 1997 05:00:00 GMT"],
        ["Cache-Control","no-store, no-cache, must-revalidate"],
        ["Cache-Control","post-check=0, pre-check=0"],
        ["Pragma","no-cache"]
        ]
/}}

<script>
//alert("!! RESPONSE RECIEVED");
errorNumber = 0;
fileUrl = "fileurl.png";
fileName = "filename.png";
customMsg = "";
window.parent.OnUploadCompleted(errorNumber, fileUrl, fileName, customMsg);
</script>

Вещи {{env ...}} вверху указывают тип содержимого и рекомендуемые заголовки HTTP для отправки. FileUrl должен быть URL для используйте для поиска изображения на сервере.

Вот основные шаги для получения фрагмента HTML, который генерирует виджет редактора FCK. Единственная сложная часть, вы должны поставить правильная идентификация клиента в os.environ - это некрасиво но сейчас так работает библиотека FCK (я подал ошибку отчет).

import fckeditor # you must have the fck editor python support installed to use this module
import os

inputName = "myInputName" # the name to use for the input element in the form
basePath = "/server/relative/path/to/fck/installation/" # the location of FCK static files
if basePath[-1:]!="/":
        basePath+="/" # basepath must end in slash
oFCKeditor = fckeditor.FCKeditor(inputName)
oFCKeditor.BasePath = basePath
oFCKeditor.Height = 300 # the height in pixels of the editor
oFCKeditor.Value = "<h1>initial html to be editted</h1>"
os.environ["HTTP_USER_AGENT"] = "Mozilla/5.0 (Macintosh; U;..." # or whatever
# there must be some way to figure out the user agent in Django right?
htmlOut = oFCKeditor.Create()
# insert htmlOut into your page where you want the editor to appear
return htmlOut

Выше не протестировано, но оно основано на проверке ниже.

Вот как использовать редактор FCK с помощью mod-wsgi: Технически он использует несколько функций WHIFF (см. WHIFF.sourceforge.net ), - на самом деле это часть распространения WHIFF - но функции WHIFF легко удаляются.

Я не знаю, как установить его в Django, но если Django позволяет легко устанавливать приложения wsgi, вы должен быть в состоянии сделать это.

ПРИМЕЧАНИЕ: FCK позволяет клиенту вводить практически все в HTML-страницы - вы хотите фильтровать возвращаемое значение для зла атаки. (например: см. whiff.middleware.TestSafeHTML middleware для пример того, как это сделать).

    
"""
Introduce an FCK editor input element. (requires FCKeditor http://www.fckeditor.net/).

Note: this implementation can generate values containing code injection attacks if you
  don't filter the output generated for evil tags and values.
"""

import fckeditor # you must have the fck editor python support installed to use this module
from whiff.middleware import misc
import os

class FCKInput(misc.utility):
    def __init__(self,
                 inputName, # name for input element
                 basePath, # server relative URL root for FCK HTTP install
                 value = ""):  # initial value for input
        self.inputName = inputName
        self.basePath = basePath
        self.value = value
    def __call__(self, env, start_response):
        inputName = self.param_value(self.inputName, env).strip()
        basePath = self.param_value(self.basePath, env).strip()
        if basePath[-1:]!="/":
            basePath+="/"
        value = self.param_value(self.value, env)
        oFCKeditor = fckeditor.FCKeditor(inputName)
        oFCKeditor.BasePath = basePath
        oFCKeditor.Height = 300 # this should be a require!
        oFCKeditor.Value = value
        # hack around a bug in fck python library: need to put the user agent in os.environ
        # XXX this hack is not safe for multi threaded servers (theoretically)... need to lock on os.env
        os_environ = os.environ
        new_os_env = os_environ.copy()
        new_os_env.update(env)
        try:
            os.environ = new_os_env
            htmlOut = oFCKeditor.Create()
        finally:
            # restore the old os.environ
            os.environ = os_environ
        start_response("200 OK", [('Content-Type', 'text/html')])
        return [htmlOut]

__middleware__ = FCKInput

def test():
    env = {
        "HTTP_USER_AGENT":
        "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
        }
    f = FCKInput("INPUTNAME", "/MY/BASE/PATH", "THE <EM>HTML</EM> VALUE TO START WITH")
    r = f(env, misc.ignore)
    print "test result"
    print "".join(list(r))

if __name__=="__main__":
    test()

Посмотрите, как это работает, например, на http://aaron.oirt.rutgers.edu/myapp/docs/W1500.whyIsWhiffCool.

кстати: спасибо. В любом случае мне нужно было разобраться в этом.

0 голосов
/ 04 июня 2009

Редактировать: В конечном счете, я тоже был недоволен этим решением, поэтому я создал приложение Django , которое заботится о загрузке и просмотре файлов.

Это решение, которое я окончательно взломал после прочтения кода fckeditor:

import os, sys

def fck_handler(environ, start_response):
    path = environ['PATH_INFO']
    if path.endswith(('upload.py', 'connector.py')):
        sys.path.append('/#correct_path_to#/fckeditor/editor/filemanager/connectors/py/')
        if path.endswith('upload.py'):
            from upload import FCKeditorQuickUpload
            conn = FCKeditorQuickUpload(environ)
        else:
            from connector import FCKeditorConnector
            conn = FCKeditorConnector(environ)
        try:
            data = conn.doResponse()
            start_response('200 Ok', conn.headers)
            return data
        except:
            start_response("500 Internal Server Error",[("Content-type","text/html")])
            return "There was an error"
    else:
        sys.path.append('/path_to_your_django_site/')
        os.environ['DJANGO_SETTINGS_MODULE'] = 'your_django_site.settings'
        import django.core.handlers.wsgi
        handler = django.core.handlers.wsgi.WSGIHandler()
        return handler(environ, start_response)

application = fck_handler
...