Использование stdout shell скриптов в OOo макросах [MEMO]

Автор smaharbA, 26 ноября 2010, 19:37

0 Пользователи и 1 гость просматривают эту тему.

Hubbitus

Ну так он такой и получается. Я же написал...
Или я не понимаю о чем вы.

convas

#16
Таким способом можете вызывать любую функцию из программы на Питоне , а не только для того частного случая, когда эта функция эмулирует SHELL.

У smaharbA она прямо названа shell(x), я назвал ее myfunc(x), если вы внимательно смотрели, и ничего не изменилось, выполняется с тем же результатом.

Т.е., я считаю, что здесь главное - возможность вызывать функцию из программы на Питоне, а не делать акцент на случае частного вида функции.

Hubbitus

convas, спасибо за откровение, но помоему это же все тут и так прекрасно ясно любому человеку не знакомому ни с бэйсиком, ни с Питоном...

Hubbitus

Вы не могли бы лучше кто-нибудь подсказать как правильно не включать (вырезать) в этом примере последнюю пустую строку вывода команды?
Все равно на каком уровне - Бэйсик или Питон.

convas

#19
Использовать Replace():
shellstr = Replace(script.invoke(array("echo ТЕСТИРУЕМ"), array(), array()),chr(10),"")
MsgBox shellstr


и/или Left(), Right(), ...

Hubbitus

Replace не подойдет, так как заменит все символы, а надо только последний.

За Left спасибо, пока именно так и сделал:
ret = script.invoke(array( cmd ), array(), array())
MyShell = Left(ret, len(ret) - 1)

Но это у меня на Линуксе так, на Винде, как я понимаю, два же символа будут (\r\n)? Кто подскажет как получить текущее значение переноса строк системное? Полагаю должна быть какая-то константа или переменная.

Hubbitus

Кажется нашел, вдруг кому понадобится, будет так:
ret = script.invoke(array( cmd ), array(), array())
MyShell = Left(ret, len(ret) - len(com.sun.star.text.ControlCharacter.LINE_BREAK))


На винде не проверял, но вроде должно работать.

convas

На Windows тоже работает.

Но на Windows есть проблема с отображением результата (см.картинку)

Я в своем самом первом ответе пытался обратить внимание smaharbA на эту недоработку, но он это проигнорировал.

Кто захочет, тот может доделать этот макрос для Windows (я не хочу).

[вложение удалено Администратором]

Hubbitus

Ну мне вод винду пока совсем не надо.
А вообще в винде нету ж юникода, попробуйте cp866 и cp1251.

Рыбка Рио

Чтобы файл сохранялся в Юникоде (на любой системе), нужно иначе записывать данные в файл, через сервис om.sun.star.ucb.SimpleFileAccess

Sub Main
    user=createUnoService("com.sun.star.util.PathSubstitution").getSubstituteVariableValue("$(user)")
    mkdir ConvertFromURL(user & "/Scripts/python")
    pscript=""
    sep=getPathSeparator()
    for each c in split(ConvertFromURL(user & "/Scripts/python"),sep)
        pscript=pscript & ".." & getPathSeparator()
    next
    if sep="\" then
        home=environ("USERPROFILE")
    else
        home=environ("HOME")
    end if
    tmp=home & sep & ".tmp" & sep
    mkdir tmp
    script=tmp & "pyshell.py"
   
   
    Dim sf As Object
   sf = createUnoService("com.sun.star.ucb.SimpleFileAccess")
   fileStream = sf.openFileWrite(script)
   fileStream.truncate()
   mytext = createUnoService("com.sun.star.io.TextOutputStream")
   mytext.OutputStream = fileStream
   mytext.WriteString("#!" & chr(10) & "# -*- coding: UTF-8 -*-" & chr(10) & "import os" & chr(10) & "def shell(x):return """".join(os.popen(x.encode('utf-8')).readlines())")
   fileStream.closeOutput
   mytext.closeOutput
   
    drive=split(script,sep)(0)
    if len(drive)=2 and right(drive,1)=":" then script=mid(script,3)
    script=replace(pscript & script,sep,"/")
    script = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory").createScriptProvider("")._
        getScript("vnd.sun.star.script:" & script & "$shell?language=Python&location=user")
    msgbox script.invoke(array("dir """ & replace(home,"/",sep) & """"), array(), array())
End Sub
ubuntu 12.04 + LibO3.6.0

convas

#25
Клио, не то. Не нужно питоновский файл писать в Юникоде, не в этом дело.

Просто, функция shell(x) возвращает строку в UTF-8, которая в Windows отображается кракозябрами.

Ваш макрос выдает те же кракозябры.



[вложение удалено Администратором]

Hubbitus

А что-нибудь вроде:
def myfunc(x):return "".join(os.popen(x.encode('cp866')).readlines())
или
def myfunc(x):return "".join(os.popen(x.encode('cp1251)).readlines())
не спасает?

Впрочем даже если поможет, это только для русского. Так как консоль в винде не юникодная, истинный путь должен быть в этом случае получить у систем текущую кодировку... Как это сделать на винде совершенно не знаю (да и не особо хочу сейчас).

convas

Цитата: Hubbitus от 30 января 2011, 00:24А что-нибудь вроде:
x.encode('cp866')
x.encode('cp1251)
Меняется только вид этих кракозябр, но кракозябры остаются.

convas

Для правильного отображения символов русского языка в Windows файл на Питоне должен быть таким:
import os

def shell(x):

    output = os.popen(x.encode('cp1251')).readlines( )

    ret = "".join( output )

    return unicode(ret,"cp866")

convas

#29
Чтобы окончательно закончить с Питоном, и убрать "странную" строку (Ответ #10)
Цитироватьscript="../../../../../../../../..//Documents and Settings/USERNAME/.tmp/pyshell.py"

можно хранить файлы Питона не в папке USERNAME, а в папке SHARE по тому пути, где обычно и хранятся файлы Питона для OpenOffice.org
ЦитироватьC:\Program Files\OpenOffice.org 3\Basis\share\Scripts\python\

В этом случае макрос для вызова функции myfunc(x) из программы на Питоне очень простой:
Sub MainPyShell
   script="pyshell.py"
   script = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory").createScriptProvider("")._
       getScript("vnd.sun.star.script:" & script & "$myfunc?language=Python&location=share")
   msgbox script.invoke(array("dir C:\GR "), array(), array())
End Sub


"...location=user" заменили на "...location=share"

PS. Это вариант для Windows, но для Linux делается аналогично.