PrEditor 0.0.0.dev1__py2.py3-none-any.whl → 0.1.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PrEditor might be problematic. Click here for more details.
- PrEditor-0.1.0.dist-info/LICENSE +165 -0
- PrEditor-0.1.0.dist-info/METADATA +212 -0
- PrEditor-0.1.0.dist-info/RECORD +149 -0
- {PrEditor-0.0.0.dev1.dist-info → PrEditor-0.1.0.dist-info}/WHEEL +1 -1
- PrEditor-0.1.0.dist-info/entry_points.txt +18 -0
- PrEditor-0.1.0.dist-info/top_level.txt +1 -0
- preditor/__init__.py +301 -0
- {blurdev → preditor}/__main__.py +13 -13
- preditor/about_module.py +166 -0
- preditor/cli.py +192 -0
- {blurdev → preditor}/contexts.py +119 -119
- preditor/cores/core.py +65 -0
- preditor/dccs/maya/PrEditor_maya.mod +2 -0
- preditor/dccs/maya/plug-ins/PrEditor_maya.py +108 -0
- preditor/debug.py +294 -0
- blurdev/scintilla/delayable_engine.py → preditor/delayable_engine/__init__.py +310 -299
- blurdev/scintilla/delayables/base.py → preditor/delayable_engine/delayables.py +85 -85
- {blurdev → preditor}/enum.py +728 -1003
- {blurdev → preditor}/gui/__init__.py +84 -125
- preditor/gui/app.py +159 -0
- {blurdev → preditor}/gui/codehighlighter.py +209 -219
- {blurdev → preditor}/gui/completer.py +226 -236
- {blurdev → preditor}/gui/console.py +801 -858
- {blurdev → preditor}/gui/dialog.py +200 -216
- preditor/gui/drag_tab_bar.py +190 -0
- preditor/gui/editor_chooser.py +57 -0
- {blurdev → preditor}/gui/errordialog.py +100 -97
- preditor/gui/fuzzy_search/fuzzy_search.py +93 -0
- preditor/gui/group_tab_widget/__init__.py +319 -0
- preditor/gui/group_tab_widget/grouped_tab_menu.py +35 -0
- preditor/gui/group_tab_widget/grouped_tab_models.py +108 -0
- preditor/gui/group_tab_widget/grouped_tab_widget.py +75 -0
- preditor/gui/group_tab_widget/one_tab_widget.py +54 -0
- preditor/gui/level_buttons.py +349 -0
- {blurdev → preditor}/gui/logger_window_handler.py +46 -45
- {blurdev → preditor}/gui/loggerwindow.py +1205 -1417
- {blurdev → preditor}/gui/newtabwidget.py +69 -68
- {blurdev → preditor}/gui/redmine_login_dialog.py +63 -61
- {blurdev → preditor}/gui/set_text_editor_path_dialog.py +59 -57
- preditor/gui/ui/editor_chooser.ui +93 -0
- {blurdev → preditor}/gui/ui/errordialog.ui +81 -81
- {blurdev → preditor}/gui/ui/loggerwindow.ui +1030 -864
- {blurdev → preditor}/gui/ui/redmine_login_dialog.ui +124 -124
- {blurdev → preditor}/gui/ui/set_text_editor_path_dialog.ui +149 -149
- {blurdev → preditor}/gui/window.py +183 -199
- preditor/gui/workbox_mixin.py +357 -0
- preditor/gui/workbox_text_edit.py +117 -0
- preditor/gui/workboxwidget.py +276 -0
- preditor/logging_config.py +52 -0
- preditor/osystem.py +401 -0
- preditor/plugins.py +65 -0
- preditor/prefs.py +74 -0
- {blurdev → preditor}/resource/environment_variables.html +26 -38
- {blurdev → preditor}/resource/error_mail.html +85 -85
- {blurdev → preditor}/resource/error_mail_inline.html +41 -41
- preditor/resource/img/README.md +7 -0
- preditor/resource/img/arrow_forward.png +0 -0
- preditor/resource/img/check-bold.png +0 -0
- preditor/resource/img/chevron-down.png +0 -0
- preditor/resource/img/chevron-up.png +0 -0
- preditor/resource/img/close-thick.png +0 -0
- preditor/resource/img/comment-edit.png +0 -0
- preditor/resource/img/content-copy.png +0 -0
- preditor/resource/img/content-cut.png +0 -0
- preditor/resource/img/content-duplicate.png +0 -0
- preditor/resource/img/content-paste.png +0 -0
- preditor/resource/img/content-save.png +0 -0
- preditor/resource/img/debug_disabled.png +0 -0
- preditor/resource/img/eye-check.png +0 -0
- preditor/resource/img/file-plus.png +0 -0
- preditor/resource/img/file-remove.png +0 -0
- preditor/resource/img/format-align-left.png +0 -0
- preditor/resource/img/format-letter-case-lower.png +0 -0
- preditor/resource/img/format-letter-case-upper.png +0 -0
- preditor/resource/img/information.png +0 -0
- preditor/resource/img/logging_critical.png +0 -0
- preditor/resource/img/logging_custom.png +0 -0
- preditor/resource/img/logging_debug.png +0 -0
- preditor/resource/img/logging_error.png +0 -0
- preditor/resource/img/logging_info.png +0 -0
- preditor/resource/img/logging_not_set.png +0 -0
- preditor/resource/img/logging_warning.png +0 -0
- preditor/resource/img/marker.png +0 -0
- preditor/resource/img/play.png +0 -0
- preditor/resource/img/playlist-play.png +0 -0
- preditor/resource/img/plus-minus-variant.png +0 -0
- preditor/resource/img/preditor.ico +0 -0
- preditor/resource/img/preditor.png +0 -0
- preditor/resource/img/preditor.psd +0 -0
- preditor/resource/img/preditor.svg +44 -0
- preditor/resource/img/restart.svg +1 -0
- preditor/resource/img/skip-forward-outline.png +0 -0
- preditor/resource/img/skip-next-outline.png +0 -0
- preditor/resource/img/skip-next.png +0 -0
- preditor/resource/img/skip-previous.png +0 -0
- preditor/resource/img/subdirectory-arrow-right.png +0 -0
- preditor/resource/img/text-search-variant.png +0 -0
- {blurdev → preditor}/resource/lang/python.json +30 -30
- preditor/resource/settings.ini +25 -0
- {blurdev/resource/stylesheet/logger → preditor/resource/stylesheet}/Bright.css +56 -61
- {blurdev → preditor}/resource/stylesheet/Dark.css +190 -132
- {blurdev → preditor}/scintilla/__init__.py +22 -28
- preditor/scintilla/delayables/__init__.py +11 -0
- {blurdev → preditor}/scintilla/delayables/smart_highlight.py +94 -93
- {blurdev → preditor}/scintilla/delayables/spell_check.py +173 -172
- {blurdev → preditor}/scintilla/documenteditor.py +2039 -2115
- {blurdev → preditor}/scintilla/finddialog.py +68 -81
- {blurdev → preditor}/scintilla/lang/__init__.py +80 -93
- {blurdev → preditor}/scintilla/lang/config/bash.ini +15 -15
- {blurdev → preditor}/scintilla/lang/config/batch.ini +14 -14
- {blurdev → preditor}/scintilla/lang/config/cpp.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/css.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/eyeonscript.ini +17 -17
- {blurdev → preditor}/scintilla/lang/config/html.ini +21 -21
- {blurdev → preditor}/scintilla/lang/config/javascript.ini +24 -24
- {blurdev → preditor}/scintilla/lang/config/lua.ini +16 -16
- {blurdev → preditor}/scintilla/lang/config/maxscript.ini +20 -20
- {blurdev → preditor}/scintilla/lang/config/mel.ini +18 -18
- {blurdev → preditor}/scintilla/lang/config/mu.ini +22 -22
- {blurdev → preditor}/scintilla/lang/config/nsi.ini +5 -5
- {blurdev → preditor}/scintilla/lang/config/perl.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/puppet.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/python.ini +28 -28
- {blurdev → preditor}/scintilla/lang/config/ruby.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/sql.ini +7 -7
- {blurdev → preditor}/scintilla/lang/config/xml.ini +21 -21
- {blurdev → preditor}/scintilla/lang/config/yaml.ini +18 -18
- {blurdev → preditor}/scintilla/lang/language.py +240 -250
- preditor/scintilla/lexers/__init__.py +0 -0
- {blurdev → preditor}/scintilla/lexers/cpplexer.py +21 -30
- {blurdev → preditor}/scintilla/lexers/javascriptlexer.py +25 -34
- {blurdev → preditor}/scintilla/lexers/maxscriptlexer.py +234 -253
- {blurdev → preditor}/scintilla/lexers/mellexer.py +368 -376
- {blurdev → preditor}/scintilla/lexers/mulexer.py +32 -41
- {blurdev → preditor}/scintilla/lexers/pythonlexer.py +41 -50
- {blurdev → preditor}/scintilla/ui/finddialog.ui +160 -160
- preditor/settings.py +71 -0
- preditor/stream/__init__.py +80 -0
- preditor/stream/director.py +56 -0
- preditor/stream/manager.py +74 -0
- preditor/streamhandler_helper.py +46 -0
- preditor/utils/__init__.py +0 -0
- preditor/utils/cute.py +30 -0
- preditor/utils/stylesheets.py +54 -0
- {blurdev → preditor}/version.py +5 -5
- preditor/weakref.py +363 -0
- PrEditor-0.0.0.dev1.dist-info/METADATA +0 -51
- PrEditor-0.0.0.dev1.dist-info/RECORD +0 -279
- PrEditor-0.0.0.dev1.dist-info/top_level.txt +0 -1
- blurdev/__init__.py +0 -356
- blurdev/cores/__init__.py +0 -98
- blurdev/cores/application.py +0 -26
- blurdev/cores/core.py +0 -634
- blurdev/debug.py +0 -593
- blurdev/external.py +0 -391
- blurdev/gui/level_buttons.py +0 -585
- blurdev/gui/workboxwidget.py +0 -205
- blurdev/logger.py +0 -238
- blurdev/osystem.py +0 -813
- blurdev/prefs.py +0 -33
- blurdev/protocols/__init__.py +0 -71
- blurdev/protocols/write_std_output_handler.py +0 -83
- blurdev/resource/designer_plugins.xml +0 -9
- blurdev/resource/error_email_old.html +0 -41
- blurdev/resource/img/add.png +0 -0
- blurdev/resource/img/ajax-loader.gif +0 -0
- blurdev/resource/img/application.png +0 -0
- blurdev/resource/img/applications.png +0 -0
- blurdev/resource/img/assburner.png +0 -0
- blurdev/resource/img/assfreezer.png +0 -0
- blurdev/resource/img/bar.gif +0 -0
- blurdev/resource/img/blank.png +0 -0
- blurdev/resource/img/blurdev.png +0 -0
- blurdev/resource/img/calendar_disabled.png +0 -0
- blurdev/resource/img/calendar_enabled.png +0 -0
- blurdev/resource/img/cancel.png +0 -0
- blurdev/resource/img/custom.png +0 -0
- blurdev/resource/img/debug_high.png +0 -0
- blurdev/resource/img/debug_low.png +0 -0
- blurdev/resource/img/debug_mid.png +0 -0
- blurdev/resource/img/debug_off.png +0 -0
- blurdev/resource/img/django.png +0 -0
- blurdev/resource/img/doc.png +0 -0
- blurdev/resource/img/edit.png +0 -0
- blurdev/resource/img/elemental.png +0 -0
- blurdev/resource/img/explore.png +0 -0
- blurdev/resource/img/favorite.png +0 -0
- blurdev/resource/img/file.png +0 -0
- blurdev/resource/img/folder.png +0 -0
- blurdev/resource/img/ide/add.png +0 -0
- blurdev/resource/img/ide/add_note.png +0 -0
- blurdev/resource/img/ide/arrow_down.png +0 -0
- blurdev/resource/img/ide/arrow_up.png +0 -0
- blurdev/resource/img/ide/check.png +0 -0
- blurdev/resource/img/ide/class.png +0 -0
- blurdev/resource/img/ide/clean.png +0 -0
- blurdev/resource/img/ide/clearlog.png +0 -0
- blurdev/resource/img/ide/close.png +0 -0
- blurdev/resource/img/ide/comment_add.png +0 -0
- blurdev/resource/img/ide/comment_remove.png +0 -0
- blurdev/resource/img/ide/comment_toggle.png +0 -0
- blurdev/resource/img/ide/console.png +0 -0
- blurdev/resource/img/ide/copy.png +0 -0
- blurdev/resource/img/ide/copylstrip.png +0 -0
- blurdev/resource/img/ide/cut.png +0 -0
- blurdev/resource/img/ide/edit.png +0 -0
- blurdev/resource/img/ide/find.png +0 -0
- blurdev/resource/img/ide/find_replace.png +0 -0
- blurdev/resource/img/ide/findnext.png +0 -0
- blurdev/resource/img/ide/findprev.png +0 -0
- blurdev/resource/img/ide/folder_find.png +0 -0
- blurdev/resource/img/ide/function.png +0 -0
- blurdev/resource/img/ide/git-bash.png +0 -0
- blurdev/resource/img/ide/git-gui.png +0 -0
- blurdev/resource/img/ide/gitk.png +0 -0
- blurdev/resource/img/ide/goto.png +0 -0
- blurdev/resource/img/ide/goto_def.png +0 -0
- blurdev/resource/img/ide/help.png +0 -0
- blurdev/resource/img/ide/highlighter.png +0 -0
- blurdev/resource/img/ide/lowercase.png +0 -0
- blurdev/resource/img/ide/newfile.png +0 -0
- blurdev/resource/img/ide/newfolder.png +0 -0
- blurdev/resource/img/ide/newproject.png +0 -0
- blurdev/resource/img/ide/newwizard.png +0 -0
- blurdev/resource/img/ide/open.png +0 -0
- blurdev/resource/img/ide/paste.png +0 -0
- blurdev/resource/img/ide/pdb_continue.png +0 -0
- blurdev/resource/img/ide/pdb_down.png +0 -0
- blurdev/resource/img/ide/pdb_next.png +0 -0
- blurdev/resource/img/ide/pdb_step.png +0 -0
- blurdev/resource/img/ide/pdb_up.png +0 -0
- blurdev/resource/img/ide/plus_minus.png +0 -0
- blurdev/resource/img/ide/preferences.png +0 -0
- blurdev/resource/img/ide/project_find.png +0 -0
- blurdev/resource/img/ide/python.png +0 -0
- blurdev/resource/img/ide/pyular.png +0 -0
- blurdev/resource/img/ide/qt.png +0 -0
- blurdev/resource/img/ide/quit.png +0 -0
- blurdev/resource/img/ide/redo.png +0 -0
- blurdev/resource/img/ide/refresh.png +0 -0
- blurdev/resource/img/ide/remove.png +0 -0
- blurdev/resource/img/ide/ruler.png +0 -0
- blurdev/resource/img/ide/run.png +0 -0
- blurdev/resource/img/ide/runall.png +0 -0
- blurdev/resource/img/ide/runallclear.png +0 -0
- blurdev/resource/img/ide/runselected.png +0 -0
- blurdev/resource/img/ide/runselectedclear.png +0 -0
- blurdev/resource/img/ide/save.png +0 -0
- blurdev/resource/img/ide/saveas.png +0 -0
- blurdev/resource/img/ide/sdk.png +0 -0
- blurdev/resource/img/ide/separator.png +0 -0
- blurdev/resource/img/ide/tabbed.png +0 -0
- blurdev/resource/img/ide/tile.png +0 -0
- blurdev/resource/img/ide/toolbar.png +0 -0
- blurdev/resource/img/ide/undo.png +0 -0
- blurdev/resource/img/ide/uppercase.png +0 -0
- blurdev/resource/img/ide/view_as.png +0 -0
- blurdev/resource/img/ide/windowed.png +0 -0
- blurdev/resource/img/ide.ico +0 -0
- blurdev/resource/img/ide.png +0 -0
- blurdev/resource/img/ide48.png +0 -0
- blurdev/resource/img/info.png +0 -0
- blurdev/resource/img/legacy tool.png +0 -0
- blurdev/resource/img/library.png +0 -0
- blurdev/resource/img/logger/about.png +0 -0
- blurdev/resource/img/logger/arrow_forward.png +0 -0
- blurdev/resource/img/logger/clear.png +0 -0
- blurdev/resource/img/logger/close.png +0 -0
- blurdev/resource/img/logger/debug_disabled.png +0 -0
- blurdev/resource/img/logger/debug_high.png +0 -0
- blurdev/resource/img/logger/debug_low.png +0 -0
- blurdev/resource/img/logger/debug_mid.png +0 -0
- blurdev/resource/img/logger/down.png +0 -0
- blurdev/resource/img/logger/find.png +0 -0
- blurdev/resource/img/logger/logging_critical.png +0 -0
- blurdev/resource/img/logger/logging_debug.png +0 -0
- blurdev/resource/img/logger/logging_error.png +0 -0
- blurdev/resource/img/logger/logging_info.png +0 -0
- blurdev/resource/img/logger/logging_not_set.png +0 -0
- blurdev/resource/img/logger/logging_warning.png +0 -0
- blurdev/resource/img/logger/next.png +0 -0
- blurdev/resource/img/logger/play.png +0 -0
- blurdev/resource/img/logger/playlist_play.png +0 -0
- blurdev/resource/img/logger/previous.png +0 -0
- blurdev/resource/img/logger/return.png +0 -0
- blurdev/resource/img/logger/save.png +0 -0
- blurdev/resource/img/logger/subdirectory_arrow_right.png +0 -0
- blurdev/resource/img/logger/up.png +0 -0
- blurdev/resource/img/lovebar.png +0 -0
- blurdev/resource/img/new.png +0 -0
- blurdev/resource/img/new_selected.png +0 -0
- blurdev/resource/img/node.png +0 -0
- blurdev/resource/img/ok.png +0 -0
- blurdev/resource/img/options.png +0 -0
- blurdev/resource/img/packages.png +0 -0
- blurdev/resource/img/preview/add.png +0 -0
- blurdev/resource/img/preview/brush.png +0 -0
- blurdev/resource/img/preview/delete.png +0 -0
- blurdev/resource/img/preview/delte.png +0 -0
- blurdev/resource/img/preview/fill.png +0 -0
- blurdev/resource/img/preview/layers.png +0 -0
- blurdev/resource/img/preview/media.png +0 -0
- blurdev/resource/img/preview/navigate.png +0 -0
- blurdev/resource/img/preview/pencil.png +0 -0
- blurdev/resource/img/preview/select.png +0 -0
- blurdev/resource/img/preview/type.png +0 -0
- blurdev/resource/img/preview/visible.png +0 -0
- blurdev/resource/img/project.png +0 -0
- blurdev/resource/img/python_logger.ico +0 -0
- blurdev/resource/img/python_logger.png +0 -0
- blurdev/resource/img/refresh.png +0 -0
- blurdev/resource/img/remove.png +0 -0
- blurdev/resource/img/reset.png +0 -0
- blurdev/resource/img/richtext/font_bold.png +0 -0
- blurdev/resource/img/richtext/font_italic.png +0 -0
- blurdev/resource/img/richtext/link_image.png +0 -0
- blurdev/resource/img/richtext/spell_check.png +0 -0
- blurdev/resource/img/richtext/unordered_list.png +0 -0
- blurdev/resource/img/save.png +0 -0
- blurdev/resource/img/savesettings.png +0 -0
- blurdev/resource/img/settings.png +0 -0
- blurdev/resource/img/tool.png +0 -0
- blurdev/resource/img/toolbarHandleHorizontal.png +0 -0
- blurdev/resource/img/toolbarHandleVertical.png +0 -0
- blurdev/resource/img/trash.png +0 -0
- blurdev/resource/img/trax.png +0 -0
- blurdev/resource/img/tree.png +0 -0
- blurdev/resource/img/treegrunt.ico +0 -0
- blurdev/resource/img/treegrunt.png +0 -0
- blurdev/resource/img/treegruntedit.png +0 -0
- blurdev/resource/img/user interface.png +0 -0
- blurdev/resource/img/warning.png +0 -0
- blurdev/resource/img/watermark.png +0 -0
- blurdev/resource/sdk/blurdev.sdk +0 -3
- blurdev/resource/settings.ini +0 -82
- blurdev/resource/softimage/BlurApplication.dll +0 -0
- blurdev/resource/softimage/BlurApplication64.dll +0 -0
- blurdev/resource/stylesheet/Carbon.css +0 -35
- blurdev/resource/stylesheet/logger/Dark.css +0 -62
- blurdev/resource/templ/py_comment.templ +0 -1
- blurdev/resource/templ/py_debug_raise_error.templ +0 -7
- blurdev/resource/templ/py_doc_string.templ +0 -10
- blurdev/resource/templ/py_header.templ +0 -9
- blurdev/resource/templ/py_line_comment.templ +0 -1
- blurdev/resource/templ/py_log_to_file.templ +0 -22
- blurdev/resource/templ/py_module_path.templ +0 -1
- blurdev/resource/templ/py_pyqt_core.templ +0 -1
- blurdev/resource/templ/py_pyqt_gui.templ +0 -1
- blurdev/resource/templ/py_splashscreen.templ +0 -6
- blurdev/resource/templ/py_testing_note.templ +0 -1
- blurdev/resource/templ/py_testing_note_end.templ +0 -1
- blurdev/resource/tools_environments.json +0 -72
- blurdev/resource/tools_environments.xml +0 -11
- blurdev/resource/tools_environments_linux.xml +0 -11
- blurdev/resource/tools_environments_offline.xml +0 -7
- blurdev/runtimes/__init__.py +0 -2
- blurdev/runtimes/logger.py +0 -44
- blurdev/scintilla/delayables/__init__.py +0 -9
- blurdev/settings.py +0 -312
- blurdev/utils/error.py +0 -389
- {blurdev/scintilla/lexers → preditor/cores}/__init__.py +0 -0
- {blurdev/utils → preditor/gui/fuzzy_search}/__init__.py +0 -0
- {blurdev → preditor}/resource/img/warning-big.png +0 -0
blurdev/external.py
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
from __future__ import print_function
|
|
2
|
-
from __future__ import absolute_import
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
import time
|
|
6
|
-
import multiprocessing
|
|
7
|
-
from multiprocessing import Process, Pipe
|
|
8
|
-
import blurdev
|
|
9
|
-
from Qt.QtCore import QTimer
|
|
10
|
-
from blurdev.protocols import BaseProtocolHandler, InvalidHandlerError
|
|
11
|
-
import six
|
|
12
|
-
|
|
13
|
-
try:
|
|
14
|
-
# Optional: In case blur.Stone is not installed,
|
|
15
|
-
# though this will mean it can't automatically close python.
|
|
16
|
-
import blur.Stone as Stone
|
|
17
|
-
except ImportError:
|
|
18
|
-
Stone = None
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class External(object):
|
|
22
|
-
"""Singleton class used for multiProcess communication.
|
|
23
|
-
|
|
24
|
-
This class provides a easy way to spawn a secondary instance of python and run
|
|
25
|
-
Qt/blurdev. It also provides for two way communication between the two processes.
|
|
26
|
-
Currently, the parent process does not check its pipe for data automatically, you
|
|
27
|
-
will need to periodicly poll that data using checkPipe if you would like to receive
|
|
28
|
-
that info.
|
|
29
|
-
|
|
30
|
-
Note: This uses blur.Stone to monitor the parent process though it is optional, if
|
|
31
|
-
blur.Stone is not installed, it may not properly close the subprocesses.
|
|
32
|
-
|
|
33
|
-
Args:
|
|
34
|
-
send: If provided, call multiProcess, and send the data. Defaults to None. See
|
|
35
|
-
parsePipe for valid values.
|
|
36
|
-
|
|
37
|
-
Attributes:
|
|
38
|
-
|
|
39
|
-
checkIfOrphaned (bool): If true, exit blurdev if the parent process terminates
|
|
40
|
-
|
|
41
|
-
childProcess (multiprocessing.Process): Pointer to the child process
|
|
42
|
-
|
|
43
|
-
exitMonitorPid (int): Parent process id used to check if the parent process has
|
|
44
|
-
terminated.
|
|
45
|
-
|
|
46
|
-
exitMonitorProcessName (str): Parent process name used to check if the parent
|
|
47
|
-
process has terminated. Because of how multiprocessing works this becomes
|
|
48
|
-
invalid before the pid. In most cases the pid will not become invalid until
|
|
49
|
-
the child python closes.
|
|
50
|
-
|
|
51
|
-
isChildProcess (bool): If true, this is the child process, otherwise it is the
|
|
52
|
-
parent process.
|
|
53
|
-
|
|
54
|
-
timerCommand (QTimer): QTimer used to to check if there is data in the pipe, and
|
|
55
|
-
check if the parent process has closed.
|
|
56
|
-
|
|
57
|
-
parentCore (str): The name of the core that launched the child process. It is
|
|
58
|
-
used to handleData any core specific configuration required like not
|
|
59
|
-
parenting to the parent app.
|
|
60
|
-
|
|
61
|
-
Example:
|
|
62
|
-
|
|
63
|
-
In the parent process, this will spawn a child process if neccissary, and send
|
|
64
|
-
['treegrunt', 'Python_Logger'] to the child process. In this case it will launch
|
|
65
|
-
the Python_Logger tool. In the child process, it would send the message back up
|
|
66
|
-
the pipe to the parent process.
|
|
67
|
-
|
|
68
|
-
>>> import blurdev.external
|
|
69
|
-
>>> blurdev.external.External(['treegrunt', 'Python_Logger'])
|
|
70
|
-
"""
|
|
71
|
-
|
|
72
|
-
_instance = None
|
|
73
|
-
|
|
74
|
-
def __new__(cls, send=None):
|
|
75
|
-
if not cls._instance:
|
|
76
|
-
cls._instance = super(External, cls).__new__(cls, send=send)
|
|
77
|
-
cls._parentPipe = None
|
|
78
|
-
cls._childPipe = None
|
|
79
|
-
cls.checkIfOrphaned = False
|
|
80
|
-
cls.childProcess = None
|
|
81
|
-
cls.exitMonitorPid = None
|
|
82
|
-
cls.exitMonitorProcessName = ''
|
|
83
|
-
cls.isChildProcess = False
|
|
84
|
-
cls.timerCommand = None
|
|
85
|
-
cls.parentCore = ""
|
|
86
|
-
return cls._instance
|
|
87
|
-
|
|
88
|
-
def __init__(self, send=None):
|
|
89
|
-
super(External, self).__init__()
|
|
90
|
-
if send:
|
|
91
|
-
self.multiProcess()
|
|
92
|
-
self.send(send)
|
|
93
|
-
|
|
94
|
-
def checkPipe(self):
|
|
95
|
-
"""Poll the pipe to see if it contains data and return if it does and the data.
|
|
96
|
-
|
|
97
|
-
If the pipe is broken because the parent process was closed, it will call
|
|
98
|
-
shutdownIfParentClosed if checkIfOrphaned is enabled.
|
|
99
|
-
|
|
100
|
-
Returns:
|
|
101
|
-
bool: If the pipe had data
|
|
102
|
-
var: The data stored in the pipe
|
|
103
|
-
"""
|
|
104
|
-
pipe = self.pipe()
|
|
105
|
-
try:
|
|
106
|
-
if pipe and pipe.poll():
|
|
107
|
-
data = pipe.recv()
|
|
108
|
-
return True, data
|
|
109
|
-
except IOError as e:
|
|
110
|
-
if e.errno == 109:
|
|
111
|
-
# The pipe has been ended, shutdown blurdev and exit python even if the
|
|
112
|
-
# parent process is still running
|
|
113
|
-
if self.checkIfOrphaned:
|
|
114
|
-
self.shutdownIfParentClosed(force=True)
|
|
115
|
-
return False, None
|
|
116
|
-
|
|
117
|
-
def handleData(self, data):
|
|
118
|
-
"""Parses the data returned from the pipe and calls the proper handler.
|
|
119
|
-
|
|
120
|
-
Processes data retreived from the pipe, and uses
|
|
121
|
-
blurdev.protocols.BaseProtocolHandler to process the contents of data. Valid
|
|
122
|
-
data should be in the form of ['handlerName', 'handlerCommand'] or
|
|
123
|
-
['handlerName', 'handlerCommand', {'keyword', 'args'}]. It will also accept a
|
|
124
|
-
Exception as the only data. If a Exception is received it will be raised. If a
|
|
125
|
-
invalid request is received, it will send a InvalidHandlerError exception back
|
|
126
|
-
up the pipe.
|
|
127
|
-
|
|
128
|
-
Args:
|
|
129
|
-
data (list): ['handlerName', 'handlerCommand', {'keyword', 'args'}]
|
|
130
|
-
|
|
131
|
-
Returns:
|
|
132
|
-
bool: If a handler was found
|
|
133
|
-
"""
|
|
134
|
-
name = None
|
|
135
|
-
command = None
|
|
136
|
-
params = {}
|
|
137
|
-
if isinstance(data, Exception):
|
|
138
|
-
raise data
|
|
139
|
-
if isinstance(data, (list, tuple)) and len(data) > 1:
|
|
140
|
-
# Lists/tuple's are only valid if they contain an id string and a dictionary
|
|
141
|
-
name = data[0]
|
|
142
|
-
command = data[1]
|
|
143
|
-
# params are optional
|
|
144
|
-
if len(data) > 2:
|
|
145
|
-
params = data[2]
|
|
146
|
-
handler = data
|
|
147
|
-
if (
|
|
148
|
-
not isinstance(name, six.string_types)
|
|
149
|
-
or not isinstance(command, six.string_types)
|
|
150
|
-
or not isinstance(params, dict)
|
|
151
|
-
):
|
|
152
|
-
print("Invalid data", [name, command, params])
|
|
153
|
-
msg = (
|
|
154
|
-
"Please provide valid command handler arguments. Example: "
|
|
155
|
-
"['handlerName', 'handlerCommand', {'keyword', 'args'}]"
|
|
156
|
-
)
|
|
157
|
-
self.send(InvalidHandlerError(msg))
|
|
158
|
-
return
|
|
159
|
-
handler = BaseProtocolHandler.findHandler(name, command, params)
|
|
160
|
-
if handler:
|
|
161
|
-
handler.run()
|
|
162
|
-
return True
|
|
163
|
-
return False
|
|
164
|
-
|
|
165
|
-
def childIsAlive(self):
|
|
166
|
-
if not self.isChildProcess:
|
|
167
|
-
return self.childProcess.is_alive()
|
|
168
|
-
return False
|
|
169
|
-
|
|
170
|
-
@classmethod
|
|
171
|
-
def launch(
|
|
172
|
-
cls,
|
|
173
|
-
hwnd,
|
|
174
|
-
childPipe=None,
|
|
175
|
-
exitMonitorPid=None,
|
|
176
|
-
exitMonitorProcessName='',
|
|
177
|
-
parentCore='',
|
|
178
|
-
compid=None,
|
|
179
|
-
):
|
|
180
|
-
"""Used to initialize a new instance of python and start the Qt Event loop.
|
|
181
|
-
|
|
182
|
-
This function configures blurdev and starts Qt. It calls QApplication.exec_()
|
|
183
|
-
and will not exit until blurdev is shutdown.
|
|
184
|
-
|
|
185
|
-
Args:
|
|
186
|
-
hwnd(int): The win32 id used to parent Qt to the parent process
|
|
187
|
-
childPipe(multiProcess.Pipe):
|
|
188
|
-
The Pipe used for inter-process communication.
|
|
189
|
-
Defaults to None.
|
|
190
|
-
exitMonitorPid(int):
|
|
191
|
-
Shutdown blurdev when this pid becomes invalid.
|
|
192
|
-
Defaults to None.
|
|
193
|
-
exitMonitorProcessName(str):
|
|
194
|
-
Used with exitMonitorPid.
|
|
195
|
-
Closing applications with a multiprocessing instance running often
|
|
196
|
-
does not invalidate the pid, but changes the process name, checking
|
|
197
|
-
both, allows us to detect that the process has closed
|
|
198
|
-
even though the pid is still valid. Defaults to None.
|
|
199
|
-
compid(string):
|
|
200
|
-
A unique id used by Fusion to connect to the correct fusion if more than
|
|
201
|
-
one fusion is open. Defaults to None.
|
|
202
|
-
"""
|
|
203
|
-
instance = cls()
|
|
204
|
-
instance.exitMonitorProcessName = exitMonitorProcessName
|
|
205
|
-
instance.isChildProcess = True
|
|
206
|
-
instance.parentCore = parentCore
|
|
207
|
-
# Diffrent parent cores have diffrent requirements.
|
|
208
|
-
# Studiomax and other software cores are not importable externally,
|
|
209
|
-
# so we need to identify them by their object name.
|
|
210
|
-
parentCore = parentCore.lower()
|
|
211
|
-
if parentCore != "studiomax":
|
|
212
|
-
blurdev.core.setHwnd(hwnd)
|
|
213
|
-
blurdev.core._mfcApp = True
|
|
214
|
-
if childPipe:
|
|
215
|
-
# Monitor the pipe for communications from the parent application
|
|
216
|
-
instance._childPipe = childPipe
|
|
217
|
-
instance.startCheckingPipe(100)
|
|
218
|
-
if exitMonitorPid and Stone:
|
|
219
|
-
# Make parsePipe check if the parent process was closed, if so exit qt.
|
|
220
|
-
instance.exitMonitorPid = exitMonitorPid
|
|
221
|
-
instance.checkIfOrphaned = True
|
|
222
|
-
elif exitMonitorPid and Stone is None:
|
|
223
|
-
print(
|
|
224
|
-
"blur.Stone is not installed, "
|
|
225
|
-
"so this will not close automatically, or properly save prefs"
|
|
226
|
-
)
|
|
227
|
-
blurdev.core.setObjectName("multiprocessing")
|
|
228
|
-
# Notes: studiomax: max crashes if app.quitOnLastWindowClosed is False.
|
|
229
|
-
# fusion:if True, closing any window/dialog will cause qt to close and
|
|
230
|
-
# python to exit external: pdb auto continue on close is not triggered if
|
|
231
|
-
# app.quitOnLastWindowClosed is false
|
|
232
|
-
if parentCore == "fusion" or (
|
|
233
|
-
parentCore != "studiomax" and not instance.checkIfOrphaned
|
|
234
|
-
):
|
|
235
|
-
# If this is not set, Qt will close when ever a QDialog or QMainWindow is
|
|
236
|
-
# closed
|
|
237
|
-
app = blurdev.application
|
|
238
|
-
app.setQuitOnLastWindowClosed(False)
|
|
239
|
-
# This is neccissary as long as our stylesheets depend on Plastique as a base.
|
|
240
|
-
blurdev.application.setStyle(blurdev.core.defaultStyle())
|
|
241
|
-
# Initialize the logger
|
|
242
|
-
blurdev.core.logger()
|
|
243
|
-
# Start Qt's event loop
|
|
244
|
-
blurdev.startApplication()
|
|
245
|
-
|
|
246
|
-
def multiProcess(self):
|
|
247
|
-
"""Spawns or returns instance of python and the Pipe to communicate with.
|
|
248
|
-
|
|
249
|
-
It is safe to call this method multiple times in both the parent and child
|
|
250
|
-
processes. It will only spawn a new instance of python in the parent process if
|
|
251
|
-
the child process has been closed, or never launched. When called in the child
|
|
252
|
-
process it does nothing
|
|
253
|
-
"""
|
|
254
|
-
# Only create the subprocess if it hasn't already been created
|
|
255
|
-
if self.isChildProcess or (self.childProcess and self.childProcess.is_alive()):
|
|
256
|
-
return self.childProcess, self._parentPipe
|
|
257
|
-
# NOTE: I am using a blur.Stone function to monitor if the parent app is closed.
|
|
258
|
-
# If blur.Stone in not installed, you need a way to close it. For now I am
|
|
259
|
-
# showing a python console. In the future I may extract the win32 code so it can
|
|
260
|
-
# be checked, but it will probably be slower.
|
|
261
|
-
exe = "python.exe"
|
|
262
|
-
daemon = True
|
|
263
|
-
if Stone:
|
|
264
|
-
exe = "pythonw.exe"
|
|
265
|
-
daemon = False
|
|
266
|
-
exe = os.path.join(sys.exec_prefix, exe)
|
|
267
|
-
# Nuke's sys.exec_prefix is the root directory on windows. Should I just use
|
|
268
|
-
# pythonPath?
|
|
269
|
-
if not os.path.exists(exe):
|
|
270
|
-
exe = blurdev.osystem.pythonPath(pyw=bool(Stone))
|
|
271
|
-
multiprocessing.set_executable(exe)
|
|
272
|
-
if not hasattr(sys, "argv"):
|
|
273
|
-
# multiprocessing requires sys.argv so manually create it if it doesn't
|
|
274
|
-
# already exist
|
|
275
|
-
sys.argv = ['']
|
|
276
|
-
# Get all neccissary info to properly parent, communicate and detect closing
|
|
277
|
-
hwnd = blurdev.core.hwnd() # used to parent Qt to parent app
|
|
278
|
-
compid = (
|
|
279
|
-
blurdev.core.uuid()
|
|
280
|
-
) # Id used by 3rd party api's to connect to parent app
|
|
281
|
-
pid = os.getpid() # Detect if parent app was closed
|
|
282
|
-
|
|
283
|
-
self._parentPipe, self._childPipe = Pipe()
|
|
284
|
-
kwargs = {"compid": compid}
|
|
285
|
-
kwargs["childPipe"] = self._childPipe
|
|
286
|
-
kwargs["exitMonitorPid"] = pid
|
|
287
|
-
kwargs["parentCore"] = blurdev.core.objectName()
|
|
288
|
-
self.childProcess = Process(target=External.launch, args=(hwnd,), kwargs=kwargs)
|
|
289
|
-
self.childProcess.daemon = daemon
|
|
290
|
-
self.childProcess.start()
|
|
291
|
-
return self.childProcess, self._parentPipe
|
|
292
|
-
|
|
293
|
-
def parsePipe(self):
|
|
294
|
-
"""Callback used to monitor for incoming commands and execute them.
|
|
295
|
-
|
|
296
|
-
If checkIfOrphaned is True, and exitMonitorPid is populated,
|
|
297
|
-
it will check if the process is still running, if not,
|
|
298
|
-
it will call blurdev.core.shutdown() and allow python to close without
|
|
299
|
-
processing any queued pipe items.
|
|
300
|
-
"""
|
|
301
|
-
if self.checkIfOrphaned and self.exitMonitorPid:
|
|
302
|
-
if self.shutdownIfParentClosed():
|
|
303
|
-
return
|
|
304
|
-
hasData, data = self.checkPipe()
|
|
305
|
-
# Clear out all pending data in the pipe
|
|
306
|
-
while hasData:
|
|
307
|
-
self.handleData(data)
|
|
308
|
-
hasData, data = self.checkPipe()
|
|
309
|
-
|
|
310
|
-
def pipe(self):
|
|
311
|
-
"""Returns the pipe used to communicate with the other end of the application.
|
|
312
|
-
|
|
313
|
-
Returns:
|
|
314
|
-
multiprocessing.Pipe: used to communicate with the other process
|
|
315
|
-
"""
|
|
316
|
-
if self.isChildProcess:
|
|
317
|
-
return self._childPipe
|
|
318
|
-
return self._parentPipe
|
|
319
|
-
|
|
320
|
-
def send(self, data):
|
|
321
|
-
"""Sends a command to be handled in the other process
|
|
322
|
-
|
|
323
|
-
Commands must be a list. The first item is the name of the handler.
|
|
324
|
-
The second item is the
|
|
325
|
-
command to send to the handler.
|
|
326
|
-
You can optionally pass a dictionary of kwargs as the third argument.
|
|
327
|
-
|
|
328
|
-
See Also: blurdev.protocols
|
|
329
|
-
|
|
330
|
-
Args:
|
|
331
|
-
data(list): Command to send.
|
|
332
|
-
|
|
333
|
-
Returns:
|
|
334
|
-
bool: If data was sent
|
|
335
|
-
"""
|
|
336
|
-
pipe = self.pipe()
|
|
337
|
-
if pipe:
|
|
338
|
-
pipe.send(data)
|
|
339
|
-
return True
|
|
340
|
-
return False
|
|
341
|
-
|
|
342
|
-
def shutdownIfParentClosed(self, force=False):
|
|
343
|
-
"""Shutdown blurdev if parent process is closed.
|
|
344
|
-
|
|
345
|
-
Uses blur.Stone to check if the parent process is still running, if not,
|
|
346
|
-
it calls blurdev.core.shutdown() to close qt and allow python to exit.
|
|
347
|
-
|
|
348
|
-
Args:
|
|
349
|
-
force(bool): Ignore blur.Stone check and force blurdev to shutdown.
|
|
350
|
-
"""
|
|
351
|
-
if force or not Stone.isRunning(
|
|
352
|
-
self.exitMonitorPid, self.exitMonitorProcessName
|
|
353
|
-
):
|
|
354
|
-
args = {"app": self.parentCore.capitalize()}
|
|
355
|
-
msg = "{app} is no longer running, shutting down blurdev and saving prefs"
|
|
356
|
-
print(msg.format(**args))
|
|
357
|
-
if "python.exe" in sys.executable.lower():
|
|
358
|
-
time.sleep(1)
|
|
359
|
-
blurdev.core.shutdown()
|
|
360
|
-
return True
|
|
361
|
-
return False
|
|
362
|
-
|
|
363
|
-
def startCheckingPipe(self, interval):
|
|
364
|
-
"""Starts a QTimer that calls parsePipe at the provided interval.
|
|
365
|
-
|
|
366
|
-
This will process all pre-existing messages in the pipe
|
|
367
|
-
|
|
368
|
-
Args:
|
|
369
|
-
interval (int): The number of milliseconds between calling parsePipe
|
|
370
|
-
"""
|
|
371
|
-
if not self.timerCommand:
|
|
372
|
-
self.timerCommand = QTimer(blurdev.core)
|
|
373
|
-
self.timerCommand.timeout.connect(self.parsePipe)
|
|
374
|
-
self.timerCommand.start(interval)
|
|
375
|
-
|
|
376
|
-
def stopCheckingPipe(self):
|
|
377
|
-
"""Stops the timerCommand QTimer."""
|
|
378
|
-
if self.timerCommand:
|
|
379
|
-
self.timerCommand.stop()
|
|
380
|
-
|
|
381
|
-
def writeToPipe(self, msg, error=False):
|
|
382
|
-
command = "stderr" if error else "stdout"
|
|
383
|
-
# use wrapper to ensure that the pickle process
|
|
384
|
-
# doesn't end up creating a int or something.
|
|
385
|
-
self.send(
|
|
386
|
-
[
|
|
387
|
-
"stdoutput",
|
|
388
|
-
command,
|
|
389
|
-
{"msg": "!!!{}!!!".format(msg), "pdb": True, "wrapper": "!!!"},
|
|
390
|
-
]
|
|
391
|
-
)
|