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

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

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

smaharbA


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"
   f=FreeFile
   open script for output as #f
   print #f, "import os" & chr(10) & "def shell(x):return """".join(os.popen(x).readlines())"
   close #f
   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
Я конечно далек от мысли... (с)

convas

Не очень информативно.

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

Hubbitus

О, именно то что я искал!

Только у меня не работает. На вызов .getScript("vnd.sun.star.script:" & script & "$shell?language=Python&location=user") возбуждается следующее исключение com.sun.star.script.provider.XScriptProvider. Ну и так как оно здесь не ловится, появляется окошко сообщение с текстом:
ЦитироватьОшибка времени выполнения BASIC.
Вызвано исключение
Type: com.sun.star.script.provider.ScriptFrameworkErrorException
Message: unsatisfied query for instance of type com.sun.star.script.provider.XScriptProvider

Может кто-нибудь помочь с этим?

raptor

Может не работать на LO 3.3.0, потому что там не работает модуль Python.

Рыбка Рио

Цитата: raptor от 27 января 2011, 15:04
Может не работать на LO 3.3.0, потому что там не работает модуль Python.
Да, там на Windows (в остальных системах всё должно работать) не работают скрипты на Питоне (исправление уже появилось в день выхода LibO, и должно появиться в 3.3.1). (Но, кстати, не весь модуль Питон не работает на Windows - некоторые расширения на Питоне, которые не используют скрипты там работают и в 3.3.0).
ubuntu 12.04 + LibO3.6.0

Hubbitus

#5
Ну во-первых у меня еще OpenOffice, во-вторых на Linux.
Но версия какраз 3.3.0.
OOO330m19 Build 9561.
Подскажете ссылочку на багрепорт об этом? И как точно протестировать что не работают Питон скрипты?
Есть способ обойти проблему?

Рыбка Рио

Bug 33355 – Python scripting not available

Кстати, у вас OOo3.3.0rc9 - может быть там тоже есть эта проблема? Ведь  LibO 3.3.0 основан на OOO330m19, а OOo 3.3.0 - на OOO330m20.
(Короче, обновитесь до финального OOo, в любом случае.)
ubuntu 12.04 + LibO3.6.0

Рыбка Рио

Нет, в OOO330m19 проблемы со скриптами на Питоне нет (OOo_3.3.0rc9_20110110_Win_x86_install_en-US.exe+WinXP SP2 ru).
ubuntu 12.04 + LibO3.6.0

Hubbitus

О, заработало!
Оказывается нужно было поставить дополнительный пакет openoffice.org-pyuno чтобы работало. Ну и перезапустить офис.
Прошу прощения за напрасные волнения. И всем спасибо за ответы.

Hubbitus

Тааак, проблема номер 2 - юникод.
При попытке выполнить скажем "echo Тест" (c русскими символами команду), получаем очень длинное сообщение об ошибке:
Ошибка времени испольнения BASIC.
Вызвано исключение
Type: com.sun.star.uno.RuntimeException
Message: Error during invoking function shell in module file:///home/pasha/.openoffice.org/3/user/Scripts/python/../../../../../../../..//home/pasha/.tmp/pyshell.py (<type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode characters in position 5-8: ordinal not in rang(128)

/home/pasha/.openoffice.org/3/user/Scripts/python/../../../../../../../..//home/pasha/.tmp/pyshell.py:2 in function shell() [def shell(x):return "".join(os.popen(x).readlines())] /usr/lib/openoffice.org/extensions/script-provider-for-python/pythonscript.py:790 in function invoke() [ret = self.func( *args )]
).


Кто знает как подружить его с юникодом?

convas

#10
Немного пояснения.
Макрос от smaharbA из 1 поста:
1.
Создает на Python вот такую программу pyshell.py:
import os
def myfunc(x):return "".join(os.popen(x).readlines())


И ее не нужно создавать каждый раз при запуске макроса, достаточно создать только один раз (можно вручную), а потом только выполнять.

2.
Выполняет эту программу на Python.

Если вы уже создали когда-то ранее этот файл pyshell.py, то для его исполнения достаточно выполнить макрос (пример для Windows):
Sub MainPyShell
   script="../../../../../../../../..//Documents and Settings/USERNAME/.tmp/pyshell.py"
   script = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory").createScriptProvider("")._
       getScript("vnd.sun.star.script:" & script & "$myfunc?language=Python&location=user")
   msgbox script.invoke(array("dir C:\GR "), array(), array())
End Sub


где C:\GR - папка, список файлов которой нужно получить (для примера).


Мораль: при проблемах нужно ковырять Python.

Hubbitus

convas, я понял что там делается и без Вас, спасибо. Кстати автосоздание скрипта есть универсальность этой функции, хотя конечно каждый раз создавать не обязательно. Это уже можно немного допилисть по желанию. Другое дело что я не являюсь Питон программистом. Если Вы знаете как решить проблему с юникодом, был бы очень благодарен за подсказку.

convas

Я, к сожалению, тоже не являюсь программистом на Питоне.
Может быть, попробовать выполнить эту программу на чистом Питоне (не из OOoBasic) и посмотреть, что получится.
А лучше обратиться к специалисту по Питону, а еще лучше к самому автору (smaharbA).

Hubbitus

Нашел!!!
Если вдруг кому-то еще будет надо, то делается так:
Строка
print #f, "import os" & chr(10) & "def shell(x):return """".join(os.popen(x).readlines())"
заменяется на:
print #f, "import os" & chr(10) & "def shell(x):return """".join(os.popen(x.encode('utf-8')).readlines())"
Вычитал тут - http://ru.wikibooks.org/wiki/%D0%A3%D1%87%D0%B5%D0%B1%D0%BD%D0%B8%D0%BA_Python_2.6

convas

#14
Замечательно.
Значит, файл pyshell.py должен быть таким:
import os
def myfunc(x):return "".join(os.popen(x.encode('utf-8')).readlines())