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/settings.py
DELETED
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
from __future__ import print_function
|
|
3
|
-
from __future__ import absolute_import
|
|
4
|
-
import os
|
|
5
|
-
import sys
|
|
6
|
-
import site
|
|
7
|
-
import re
|
|
8
|
-
import glob
|
|
9
|
-
|
|
10
|
-
try:
|
|
11
|
-
import configparser
|
|
12
|
-
except Exception:
|
|
13
|
-
import ConfigParser as configparser # noqa: N813
|
|
14
|
-
|
|
15
|
-
# define the default environment variables
|
|
16
|
-
OS_TYPE = ''
|
|
17
|
-
if os.name == 'posix':
|
|
18
|
-
OS_TYPE = 'Linux'
|
|
19
|
-
elif os.name == 'nt':
|
|
20
|
-
OS_TYPE = 'Windows'
|
|
21
|
-
elif os.name == 'osx':
|
|
22
|
-
OS_TYPE = 'MacOS'
|
|
23
|
-
|
|
24
|
-
# The sections to add from settings.ini
|
|
25
|
-
# The order matters. Add from most specific to least specific.
|
|
26
|
-
# Example: Add Windows Offline, then Windows, then Default.
|
|
27
|
-
# Environment variables that exist in os.environ will not be added.
|
|
28
|
-
_SECTIONS_TO_ADD = []
|
|
29
|
-
if os.getenv('BDEV_OFFLINE') == '1':
|
|
30
|
-
_SECTIONS_TO_ADD.append('{} Offline'.format(OS_TYPE))
|
|
31
|
-
_SECTIONS_TO_ADD += [OS_TYPE, 'Default']
|
|
32
|
-
|
|
33
|
-
_currentEnv = ''
|
|
34
|
-
_inited = False
|
|
35
|
-
defaults = {}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def environStr(value):
|
|
39
|
-
if sys.version_info[0] > 2:
|
|
40
|
-
# Python 3 requires a unicode value. aka str(), which these values already are
|
|
41
|
-
return value
|
|
42
|
-
# Python 2 requires str object, not unicode
|
|
43
|
-
return value.encode('utf8')
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def addConfigSection(config_parser, section):
|
|
47
|
-
"""
|
|
48
|
-
Add a config section to os.environ for a section.
|
|
49
|
-
|
|
50
|
-
Does not add options that already exist in os.environ.
|
|
51
|
-
|
|
52
|
-
Args:
|
|
53
|
-
config_parser (configparser.RawConfigParser): The parser to read from.
|
|
54
|
-
Must already be read.
|
|
55
|
-
section (str): The section name to add.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
for option in config_parser.options(section):
|
|
59
|
-
if option.upper() not in os.environ:
|
|
60
|
-
value = config_parser.get(section, option)
|
|
61
|
-
if value == 'None':
|
|
62
|
-
value = ''
|
|
63
|
-
# In python2.7 on windows you can't pass unicode values to
|
|
64
|
-
# subprocess.Popen's env argument. This is the reason we are calling str()
|
|
65
|
-
os.environ[environStr(option.upper())] = environStr(value)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# load the default environment from the settings INI
|
|
69
|
-
config = configparser.RawConfigParser()
|
|
70
|
-
config.read(os.path.dirname(__file__) + '/resource/settings.ini')
|
|
71
|
-
for section in _SECTIONS_TO_ADD:
|
|
72
|
-
addConfigSection(config, section)
|
|
73
|
-
|
|
74
|
-
# store the blurdev path in the environment
|
|
75
|
-
os.environ['BDEV_PATH'] = environStr(os.path.dirname(__file__))
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# define environment loading/restoring methods
|
|
79
|
-
def init():
|
|
80
|
-
global _inited
|
|
81
|
-
if _inited:
|
|
82
|
-
return
|
|
83
|
-
_inited = True
|
|
84
|
-
|
|
85
|
-
# register default paths
|
|
86
|
-
for key in sorted(list(os.environ.keys()), reverse=True):
|
|
87
|
-
if key.startswith('BDEV_INCLUDE_'):
|
|
88
|
-
path = os.environ[key]
|
|
89
|
-
if not path:
|
|
90
|
-
# If set to a empty value, don't register the path
|
|
91
|
-
continue
|
|
92
|
-
registerPath(path)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def normalizePath(path):
|
|
96
|
-
path = os.path.abspath(path)
|
|
97
|
-
# use lowercase for windows since we don't want duplicates - in other
|
|
98
|
-
# operating systems, the path is case-sensitive
|
|
99
|
-
if OS_TYPE == 'Windows':
|
|
100
|
-
path = path.lower()
|
|
101
|
-
return path
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def registerPath(path):
|
|
105
|
-
path = os.path.abspath(path)
|
|
106
|
-
# We won't register a path that does not exist to not clutter sys.path.
|
|
107
|
-
if path != '.' and path not in sys.path and os.path.exists(path):
|
|
108
|
-
# Add the path to the top of sys.path so code in this folder is run before
|
|
109
|
-
# other code with the same name.
|
|
110
|
-
sys.path.insert(0, path)
|
|
111
|
-
# Process any .pth files in this directory, Using our version of addsitedir
|
|
112
|
-
# so windows and linux paths in the .pth work. This makes it so any .egg-link
|
|
113
|
-
# installed packages get appended to sys.path and loaded. Egg-link installs
|
|
114
|
-
# are handled by the easy-install.pth file
|
|
115
|
-
addsitedir(path)
|
|
116
|
-
return True
|
|
117
|
-
return False
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def addpackage(sitedir, name, known_paths):
|
|
121
|
-
"""Process a .pth file within the site-packages directory:
|
|
122
|
-
For each line in the file, either combine it with sitedir to a path
|
|
123
|
-
and add that to known_paths, or execute it if it starts with 'import '.
|
|
124
|
-
|
|
125
|
-
NOTE: this function replicates the function in python's site module
|
|
126
|
-
It adds the ability to translate linux or windows paths to the current
|
|
127
|
-
platform in pth files. It can be used as a direct replacement to calling
|
|
128
|
-
the site function. See the `toSystemPath` function.
|
|
129
|
-
"""
|
|
130
|
-
if known_paths is None:
|
|
131
|
-
known_paths = site._init_pathinfo()
|
|
132
|
-
reset = True
|
|
133
|
-
else:
|
|
134
|
-
reset = False
|
|
135
|
-
fullname = os.path.join(sitedir, name)
|
|
136
|
-
try:
|
|
137
|
-
f = open(fullname, "r")
|
|
138
|
-
except OSError:
|
|
139
|
-
return
|
|
140
|
-
with f:
|
|
141
|
-
for n, line in enumerate(f):
|
|
142
|
-
if line.startswith("#"):
|
|
143
|
-
continue
|
|
144
|
-
try:
|
|
145
|
-
if line.startswith(("import ", "import\t")):
|
|
146
|
-
exec(line)
|
|
147
|
-
continue
|
|
148
|
-
line = toSystemPath(line.rstrip())
|
|
149
|
-
dir, dircase = site.makepath(sitedir, line)
|
|
150
|
-
if dircase not in known_paths and os.path.exists(dir):
|
|
151
|
-
sys.path.append(dir)
|
|
152
|
-
known_paths.add(dircase)
|
|
153
|
-
except Exception:
|
|
154
|
-
print(
|
|
155
|
-
"Error processing line {:d} of {}:\n".format(n + 1, fullname),
|
|
156
|
-
file=sys.stderr,
|
|
157
|
-
)
|
|
158
|
-
import traceback
|
|
159
|
-
|
|
160
|
-
for record in traceback.format_exception(*sys.exc_info()):
|
|
161
|
-
for line in record.splitlines():
|
|
162
|
-
print(' ' + line, file=sys.stderr)
|
|
163
|
-
print("\nRemainder of file ignored", file=sys.stderr)
|
|
164
|
-
break
|
|
165
|
-
if reset:
|
|
166
|
-
known_paths = None
|
|
167
|
-
return known_paths
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def addsitedir(sitedir, known_paths=None):
|
|
171
|
-
"""Add 'sitedir' argument to sys.path if missing and handle .pth files in
|
|
172
|
-
'sitedir'
|
|
173
|
-
|
|
174
|
-
NOTE: this function replicates the function in python's site module
|
|
175
|
-
It adds the ability to translate linux or windows paths to the current
|
|
176
|
-
platform in pth files. It can be used as a direct replacement to calling
|
|
177
|
-
the site function. See the `toSystemPath` function.
|
|
178
|
-
"""
|
|
179
|
-
if known_paths is None:
|
|
180
|
-
known_paths = site._init_pathinfo()
|
|
181
|
-
reset = True
|
|
182
|
-
else:
|
|
183
|
-
reset = False
|
|
184
|
-
sitedir, sitedircase = site.makepath(sitedir)
|
|
185
|
-
if sitedircase not in known_paths:
|
|
186
|
-
sys.path.append(sitedir) # Add path component
|
|
187
|
-
known_paths.add(sitedircase)
|
|
188
|
-
try:
|
|
189
|
-
names = os.listdir(sitedir)
|
|
190
|
-
except OSError:
|
|
191
|
-
return
|
|
192
|
-
names = [name for name in names if name.endswith(".pth")]
|
|
193
|
-
for name in sorted(names):
|
|
194
|
-
addpackage(sitedir, name, known_paths)
|
|
195
|
-
if reset:
|
|
196
|
-
known_paths = None
|
|
197
|
-
return known_paths
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def pathReplacements():
|
|
201
|
-
"""A list of replacements to apply to file paths.
|
|
202
|
-
|
|
203
|
-
Returns a list of ('windows', 'linux') tuples. `toSystemPath` uses this list
|
|
204
|
-
to translate file paths to the current system.
|
|
205
|
-
|
|
206
|
-
This list is controlled by the BDEV_PATH_REPLACEMENTS environment variable.
|
|
207
|
-
Each windows/linux mapping is defined as windows,linux. These are separated
|
|
208
|
-
by a ;. This ensures that we can define drive letter replacements that work
|
|
209
|
-
on linux.
|
|
210
|
-
|
|
211
|
-
Example:
|
|
212
|
-
`BDEV_PATH_REPLACEMENTS=\\aserver\ashare,/mnt/ashare;G:,/blur/g`
|
|
213
|
-
|
|
214
|
-
Returns:
|
|
215
|
-
list: The list of path replacements.
|
|
216
|
-
"""
|
|
217
|
-
ret = os.environ.get('BDEV_PATH_REPLACEMENTS', '').split(';')
|
|
218
|
-
return [mapping.split(',') for mapping in ret]
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
def pthPaths(dirname):
|
|
222
|
-
"""Returns the absolute paths defined in any .pth file in dirname.
|
|
223
|
-
|
|
224
|
-
This does not process any imports in the .pth file. The file paths are
|
|
225
|
-
converted to the current operating system by `toSystemPath`. These paths
|
|
226
|
-
have os.path.normpath, abspath and normcase called on them.
|
|
227
|
-
|
|
228
|
-
Args:
|
|
229
|
-
dirname (str): All .pth files in this directory are searched for paths.
|
|
230
|
-
|
|
231
|
-
Returns:
|
|
232
|
-
paths (list): A list of paths that will be added to sys.path when `addsitedir
|
|
233
|
-
` is called.
|
|
234
|
-
skipped (list): A list of .pth files that could not be read.
|
|
235
|
-
pthFiles (list): All .pth file paths that were processed.
|
|
236
|
-
"""
|
|
237
|
-
paths = []
|
|
238
|
-
skipped = []
|
|
239
|
-
pthFiles = glob.glob(os.path.join(dirname, '*.pth'))
|
|
240
|
-
for filename in pthFiles:
|
|
241
|
-
try:
|
|
242
|
-
with open(filename, 'r') as f:
|
|
243
|
-
for line in f:
|
|
244
|
-
if line.startswith(("import ", "import\t", "#")):
|
|
245
|
-
# For this code, we don't actually want to process imports
|
|
246
|
-
# and always want to ignore comment lines
|
|
247
|
-
continue
|
|
248
|
-
# Adjust path for the current os and call os.path.normpath
|
|
249
|
-
line = toSystemPath(line.rstrip())
|
|
250
|
-
# dircase has os.path.abspath and os.path.normcase called on it
|
|
251
|
-
_, dircase = site.makepath(dirname, line)
|
|
252
|
-
paths.append(dircase)
|
|
253
|
-
except IOError:
|
|
254
|
-
# We can't process this item, likely due to permissions.
|
|
255
|
-
skipped.append(filename)
|
|
256
|
-
return paths, skipped, pthFiles
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
def _path_escape(pattern):
|
|
260
|
-
"""Changes the pattern to match forward and backslash path separators.
|
|
261
|
-
|
|
262
|
-
Replaces backslashes with `[\\\\/]` so we can match windows and linux paths.
|
|
263
|
-
It then applies the same `re.escape` logic to any other characters as python 2.
|
|
264
|
-
"""
|
|
265
|
-
s = list(pattern)
|
|
266
|
-
alphanum = frozenset(
|
|
267
|
-
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
268
|
-
)
|
|
269
|
-
for i, c in enumerate(pattern):
|
|
270
|
-
if c in {'\\', '/'}:
|
|
271
|
-
s[i] = '[\\\\/]'
|
|
272
|
-
elif c not in alphanum:
|
|
273
|
-
if c == "\000":
|
|
274
|
-
s[i] = "\\000"
|
|
275
|
-
else:
|
|
276
|
-
s[i] = "\\" + c
|
|
277
|
-
return pattern[:0].join(s)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def toSystemPath(path, os_type=OS_TYPE):
|
|
281
|
-
"""Ensure the file path is correct for the current os.
|
|
282
|
-
|
|
283
|
-
Args:
|
|
284
|
-
path (str): The file path to convert to the current operating system.
|
|
285
|
-
os_type (str, optional): Override the os the path is generated for. Defaults
|
|
286
|
-
to `blurdev.settings.OS_TYPE`.
|
|
287
|
-
|
|
288
|
-
Returns:
|
|
289
|
-
All replacements in `pathReplacements` applied to path, with `os.path.normpath`
|
|
290
|
-
called on it for Windows. For Linux all `\\` are converted to forward slashes.
|
|
291
|
-
"""
|
|
292
|
-
replacements = pathReplacements()
|
|
293
|
-
if os_type == 'Windows':
|
|
294
|
-
src = 1
|
|
295
|
-
dest = 0
|
|
296
|
-
else:
|
|
297
|
-
src = 0
|
|
298
|
-
dest = 1
|
|
299
|
-
for replacement in replacements:
|
|
300
|
-
|
|
301
|
-
def repl(match):
|
|
302
|
-
# Don't modify our replacement string, just insert it.
|
|
303
|
-
return replacement[dest]
|
|
304
|
-
|
|
305
|
-
pattern = replacement[src]
|
|
306
|
-
pattern = _path_escape(pattern)
|
|
307
|
-
# Find and replace the text of the file paths ignoring case without
|
|
308
|
-
# affecting the case of the remaining string case.
|
|
309
|
-
path = re.sub(pattern, repl, path, flags=re.I)
|
|
310
|
-
if os_type == 'Windows':
|
|
311
|
-
return os.path.normpath(path)
|
|
312
|
-
return path.replace('\\', '/')
|
blurdev/utils/error.py
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
|
|
3
|
-
# standard library imports
|
|
4
|
-
from __future__ import absolute_import
|
|
5
|
-
from collections import OrderedDict
|
|
6
|
-
from datetime import datetime
|
|
7
|
-
import os
|
|
8
|
-
import getpass
|
|
9
|
-
import traceback
|
|
10
|
-
import sys
|
|
11
|
-
import platform
|
|
12
|
-
import socket
|
|
13
|
-
import string
|
|
14
|
-
|
|
15
|
-
# blur imports
|
|
16
|
-
import blurdev
|
|
17
|
-
from blurdev.contexts import ErrorReport
|
|
18
|
-
|
|
19
|
-
_host_information = None
|
|
20
|
-
_user_information = None
|
|
21
|
-
_environment_information = None
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def get_host_information(refresh=False):
|
|
25
|
-
"""
|
|
26
|
-
Aggregates several sources of host metadata, constructing an informative
|
|
27
|
-
dictionary. Example information: hostname, operating system, IP address,
|
|
28
|
-
host type (i.e. farm server vs. workstation).
|
|
29
|
-
|
|
30
|
-
Information is gathered only once per runtime and stored globally. One may
|
|
31
|
-
force a refresh by setting the `refresh` argument to True.
|
|
32
|
-
|
|
33
|
-
Args:
|
|
34
|
-
refresh (bool, optional): force refresh of all host information
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
OrderedDict: various data regarding current host
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
global _host_information
|
|
41
|
-
|
|
42
|
-
if _host_information is None or refresh:
|
|
43
|
-
|
|
44
|
-
hostname = socket.gethostname()
|
|
45
|
-
_host_information = OrderedDict(
|
|
46
|
-
[
|
|
47
|
-
("hostname", hostname),
|
|
48
|
-
("ip_address", socket.gethostbyname(hostname)),
|
|
49
|
-
("host_type", platform.node().strip(string.digits)),
|
|
50
|
-
("os", platform.system()),
|
|
51
|
-
("os.release", platform.release()),
|
|
52
|
-
("os.version", platform.version()),
|
|
53
|
-
]
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
return _host_information
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def get_user_information(refresh=False):
|
|
60
|
-
"""
|
|
61
|
-
Gathers information about the current user. Will attempt to query data
|
|
62
|
-
from Trax otherwise falling back to the current user logged onto host.
|
|
63
|
-
|
|
64
|
-
Information is gathered only once per runtime and stored globally. One may
|
|
65
|
-
force a refresh by setting the `refresh` argument to True.
|
|
66
|
-
|
|
67
|
-
Args:
|
|
68
|
-
refresh (bool, optional): force refresh of all user information
|
|
69
|
-
|
|
70
|
-
Returns:
|
|
71
|
-
OrderedDict: various data regarding current user
|
|
72
|
-
"""
|
|
73
|
-
global _user_information
|
|
74
|
-
|
|
75
|
-
if _user_information is None or refresh:
|
|
76
|
-
_user_information = OrderedDict([("username", getpass.getuser())])
|
|
77
|
-
|
|
78
|
-
return _user_information
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def get_environment_information(refresh=False):
|
|
82
|
-
"""
|
|
83
|
-
Supplies a dictionary of runtime environment information, such as:
|
|
84
|
-
core application, active environment, executable, and python version.
|
|
85
|
-
Conditionally, additional information regarding core-specific messages,
|
|
86
|
-
burner jobs, and/or Qt, may be supplied.
|
|
87
|
-
|
|
88
|
-
Information is gathered only once per runtime and stored globally. One may
|
|
89
|
-
force a refresh by setting the `refresh` argument to True.
|
|
90
|
-
|
|
91
|
-
Args:
|
|
92
|
-
refresh (bool, optional): force refresh of all environment information
|
|
93
|
-
|
|
94
|
-
Returns:
|
|
95
|
-
OrderedDict: various data regarding environment
|
|
96
|
-
"""
|
|
97
|
-
global _environment_information
|
|
98
|
-
|
|
99
|
-
if _environment_information is None or refresh:
|
|
100
|
-
|
|
101
|
-
_environment_information = OrderedDict(
|
|
102
|
-
[
|
|
103
|
-
("core", blurdev.core.objectName()),
|
|
104
|
-
("exe", sys.executable),
|
|
105
|
-
("python", "{}.{}.{}".format(*sys.version_info[:3])),
|
|
106
|
-
]
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
# burner job info
|
|
110
|
-
burner_information = OrderedDict(
|
|
111
|
-
[
|
|
112
|
-
("burn.jobid", os.environ.get("AB_JOBID", None)),
|
|
113
|
-
("burn.dir", os.environ.get("AB_BURNDIR", None)),
|
|
114
|
-
("burn.file", os.environ.get("AB_BURNFILE", None)),
|
|
115
|
-
]
|
|
116
|
-
)
|
|
117
|
-
for key, value in burner_information.items():
|
|
118
|
-
if value:
|
|
119
|
-
_environment_information[key] = value
|
|
120
|
-
|
|
121
|
-
# miscellaneous email info
|
|
122
|
-
prefix = "BDEV_EMAILINFO_"
|
|
123
|
-
for key, value in os.environ.items():
|
|
124
|
-
if key.startswith(prefix) and value:
|
|
125
|
-
trimmed_key = key.replace(prefix, "").lower()
|
|
126
|
-
_environment_information[trimmed_key] = value
|
|
127
|
-
|
|
128
|
-
# root application window
|
|
129
|
-
if not blurdev.core.headless:
|
|
130
|
-
from Qt.QtWidgets import QApplication
|
|
131
|
-
|
|
132
|
-
window = QApplication.activeWindow()
|
|
133
|
-
|
|
134
|
-
if window is not None:
|
|
135
|
-
window_class = window.__class__.__name__
|
|
136
|
-
|
|
137
|
-
if window_class in ("LoggerWindow", "ErrorDialog"):
|
|
138
|
-
window = window.parent()
|
|
139
|
-
window_class = window.__class__.__name__
|
|
140
|
-
|
|
141
|
-
if hasattr(window, "objectName"):
|
|
142
|
-
_environment_information["window"] = window.objectName()
|
|
143
|
-
_environment_information["window.class"] = window_class
|
|
144
|
-
|
|
145
|
-
# core-specific message, checked per-error
|
|
146
|
-
core_message = blurdev.core.errorCoreText()
|
|
147
|
-
if core_message:
|
|
148
|
-
_environment_information["core.message"] = core_message
|
|
149
|
-
|
|
150
|
-
return _environment_information
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def get_error_reports():
|
|
154
|
-
"""
|
|
155
|
-
Supplies a list of any reports generated by the `ErrorReport` decorator.
|
|
156
|
-
|
|
157
|
-
Returns:
|
|
158
|
-
list/None: list of tuples with the the error report title and report
|
|
159
|
-
contents as members
|
|
160
|
-
"""
|
|
161
|
-
reports = ErrorReport.generateReport()
|
|
162
|
-
if reports:
|
|
163
|
-
return reports
|
|
164
|
-
return None
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def all_information_by_section(refresh=False):
|
|
168
|
-
"""
|
|
169
|
-
Convenience function to return a dictionary of each section's dictionary of
|
|
170
|
-
relevant debug information.
|
|
171
|
-
|
|
172
|
-
Note: Information is gathered only once per runtime and stored globally.
|
|
173
|
-
One may force a refresh by setting the `refresh` argument to True.
|
|
174
|
-
|
|
175
|
-
Args:
|
|
176
|
-
refresh (bool, optional): force refresh of all environment information
|
|
177
|
-
|
|
178
|
-
Returns:
|
|
179
|
-
OrderedDict: section names as keys, section information dictionaries as values
|
|
180
|
-
"""
|
|
181
|
-
info_functions = (
|
|
182
|
-
("user", get_user_information),
|
|
183
|
-
("host", get_host_information),
|
|
184
|
-
("environment", get_environment_information),
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
information_dictionary = OrderedDict()
|
|
188
|
-
for label, func in info_functions:
|
|
189
|
-
results = func(refresh)
|
|
190
|
-
if results:
|
|
191
|
-
information_dictionary[label] = results
|
|
192
|
-
|
|
193
|
-
return information_dictionary
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def all_information(refresh=False):
|
|
197
|
-
"""
|
|
198
|
-
Convenience function to return a flattened version of all sessions'
|
|
199
|
-
relevant debug information dictionaries.
|
|
200
|
-
|
|
201
|
-
Note: Information is gathered only once per runtime and stored globally.
|
|
202
|
-
One may force a refresh by setting the `refresh` argument to True.
|
|
203
|
-
|
|
204
|
-
Args:
|
|
205
|
-
refresh (bool, optional): force refresh of all environment information
|
|
206
|
-
|
|
207
|
-
Returns:
|
|
208
|
-
OrderedDict: debug information
|
|
209
|
-
"""
|
|
210
|
-
information_dictionary = OrderedDict()
|
|
211
|
-
for section_dictionary in all_information_by_section(refresh).values():
|
|
212
|
-
information_dictionary.update(section_dictionary)
|
|
213
|
-
return information_dictionary
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
def highlight_code(code, linenos=False):
|
|
217
|
-
"""
|
|
218
|
-
Given a formatted traceback, return syntax-highlighted HTML codeblock with
|
|
219
|
-
inline CSS styles.
|
|
220
|
-
|
|
221
|
-
Args:
|
|
222
|
-
code (list): pre-formatted stack trace with exception information;
|
|
223
|
-
created via `traceback.format_exception`
|
|
224
|
-
linenos (str/bool): manor in which line numbers will be presented;
|
|
225
|
-
options: `inline` (default), `table`, or False
|
|
226
|
-
|
|
227
|
-
Returns:
|
|
228
|
-
str: valid HTML of syntax-highlighted exception with inline styles
|
|
229
|
-
"""
|
|
230
|
-
import pygments
|
|
231
|
-
from pygments.lexers.python import PythonTracebackLexer
|
|
232
|
-
from pygments.formatters import HtmlFormatter
|
|
233
|
-
|
|
234
|
-
formatted_code = pygments.highlight(
|
|
235
|
-
"".join(code),
|
|
236
|
-
PythonTracebackLexer(),
|
|
237
|
-
HtmlFormatter(noclasses=True, linenos=linenos),
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
return formatted_code
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
def sentry_before_send_callback(event, hint):
|
|
244
|
-
"""
|
|
245
|
-
Callback function to be used with Sentry's python SDK. Executed before an
|
|
246
|
-
event is sent to the Sentry server, gathers all error information and adds
|
|
247
|
-
it to the event.
|
|
248
|
-
|
|
249
|
-
Args:
|
|
250
|
-
event (dict): Sentry event supplied before submission to server
|
|
251
|
-
hint (dict): additional information, such as exc_info, log_record or
|
|
252
|
-
httplib_request
|
|
253
|
-
|
|
254
|
-
Returns:
|
|
255
|
-
dict: modified Sentry event dictionary
|
|
256
|
-
"""
|
|
257
|
-
info = all_information_by_section()
|
|
258
|
-
user_info = info.pop("user")
|
|
259
|
-
|
|
260
|
-
# add user data
|
|
261
|
-
event_user = event.setdefault("user", dict())
|
|
262
|
-
event_user.update(user_info)
|
|
263
|
-
|
|
264
|
-
# add additional tags
|
|
265
|
-
event_tags = event.setdefault("tags", dict())
|
|
266
|
-
for section in info.values():
|
|
267
|
-
event_tags.update(section)
|
|
268
|
-
|
|
269
|
-
# add error reports
|
|
270
|
-
event_extra = event.setdefault("extra", dict())
|
|
271
|
-
error_reports = get_error_reports()
|
|
272
|
-
if error_reports:
|
|
273
|
-
event_extra["error_reports"] = error_reports
|
|
274
|
-
|
|
275
|
-
return event
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
class ErrorEmail(object):
|
|
279
|
-
"""
|
|
280
|
-
Error email generator and sender.
|
|
281
|
-
|
|
282
|
-
Assembles a litany of relevant debug information for regarding the supplied
|
|
283
|
-
exception event, then (via Jinja2) produces valid HTML with inline CSS
|
|
284
|
-
properties to email as desired.
|
|
285
|
-
|
|
286
|
-
Args:
|
|
287
|
-
exc_type (type): exception type class object
|
|
288
|
-
exc_value (exception): class instance of exception parameter
|
|
289
|
-
exc_traceback (traceback): encapsulation of call stack for exception
|
|
290
|
-
"""
|
|
291
|
-
|
|
292
|
-
def __init__(self, exc_type, exc_value, exc_traceback):
|
|
293
|
-
self.exc_type = exc_type
|
|
294
|
-
self.exc_value = exc_value
|
|
295
|
-
self.exc_traceback = exc_traceback
|
|
296
|
-
|
|
297
|
-
self.traceback_message = traceback.format_exception(
|
|
298
|
-
self.exc_type, self.exc_value, self.exc_traceback
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
self.info = all_information_by_section()
|
|
302
|
-
|
|
303
|
-
def sender(self):
|
|
304
|
-
"""
|
|
305
|
-
The "from"-address for the error email.
|
|
306
|
-
|
|
307
|
-
To circumvent Gmail's truncation of emails with a majority of content
|
|
308
|
-
being identical, we append a unique identifier (in this case, a hashing of
|
|
309
|
-
the error email's subject line) to the `thepipe@blur.com` address.
|
|
310
|
-
|
|
311
|
-
Returns:
|
|
312
|
-
str: unique "The Pipe" email address derived from subject
|
|
313
|
-
"""
|
|
314
|
-
return blurdev.core.emailAddressMd5Hash(self.subject())
|
|
315
|
-
|
|
316
|
-
def subject(self, max_length=150):
|
|
317
|
-
"""
|
|
318
|
-
Error email subject line; includes several basic bits of information
|
|
319
|
-
for quick identification within ones Inbox.
|
|
320
|
-
|
|
321
|
-
By default, subject is truncated to 150 characters. May be disabled by
|
|
322
|
-
setting `max_length` to None.
|
|
323
|
-
|
|
324
|
-
Args:
|
|
325
|
-
max_length (int): maximum length for subject line; truncates string
|
|
326
|
-
to `max_length - 3` and adds an ellipsis `...`
|
|
327
|
-
|
|
328
|
-
Returns:
|
|
329
|
-
str: email subject
|
|
330
|
-
"""
|
|
331
|
-
tags = ""
|
|
332
|
-
tag_keys = ["username", "core", "environment", "window.class"]
|
|
333
|
-
for key in tag_keys:
|
|
334
|
-
value = all_information().get(key, None)
|
|
335
|
-
if value:
|
|
336
|
-
tags += "[{label}:{value}]".format(label=key[0].upper(), value=value)
|
|
337
|
-
|
|
338
|
-
subject = "[Python Error]{tags} {message}".format(
|
|
339
|
-
tags=tags, message=self.traceback_message[-1].strip("\n")
|
|
340
|
-
)
|
|
341
|
-
|
|
342
|
-
# conditionally truncate subject length
|
|
343
|
-
if isinstance(max_length, int) and max_length > 0:
|
|
344
|
-
subject = "{subject:.{length}}{ellipsis}".format(
|
|
345
|
-
subject=subject,
|
|
346
|
-
length=max_length - 3,
|
|
347
|
-
ellipsis="..." if len(subject) > max_length else "",
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
return subject
|
|
351
|
-
|
|
352
|
-
def message(self):
|
|
353
|
-
"""
|
|
354
|
-
Using a pre-made Jinja2 HTML template, render the contents of the
|
|
355
|
-
error email.
|
|
356
|
-
|
|
357
|
-
Returns:
|
|
358
|
-
str: fully valid HTML output for error email with inline CSS
|
|
359
|
-
properties
|
|
360
|
-
"""
|
|
361
|
-
from jinja2 import Environment, PackageLoader
|
|
362
|
-
|
|
363
|
-
# Jinja2 environment to import template from resources directory and
|
|
364
|
-
# add `highlight_code` to environment namespace for code-highlighting
|
|
365
|
-
# process within the template
|
|
366
|
-
jinja_env = Environment(loader=PackageLoader("blurdev", "resource"))
|
|
367
|
-
jinja_env.globals["highlight_code"] = highlight_code
|
|
368
|
-
|
|
369
|
-
template = jinja_env.get_template("error_mail_inline.html")
|
|
370
|
-
render = template.render(
|
|
371
|
-
subject=self.subject(max_length=None),
|
|
372
|
-
info_dict=self.info,
|
|
373
|
-
error_report=get_error_reports(),
|
|
374
|
-
traceback=self.traceback_message,
|
|
375
|
-
send_time=datetime.now().strftime("%b %d, %Y @ %I:%M %p"),
|
|
376
|
-
)
|
|
377
|
-
|
|
378
|
-
return render
|
|
379
|
-
|
|
380
|
-
def send(self, recipients):
|
|
381
|
-
"""
|
|
382
|
-
Initiates sending of error email to supplied recipient list.
|
|
383
|
-
|
|
384
|
-
Args:
|
|
385
|
-
recipients (list): email addresses of recipients for error email
|
|
386
|
-
"""
|
|
387
|
-
blurdev.core.sendEmail(
|
|
388
|
-
self.sender(), recipients, self.subject(), self.message()
|
|
389
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|