diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml index 10ae9d692..e3f4f4bc5 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/AboutWindow.xaml @@ -11,9 +11,9 @@ - - - + + + diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/aboutscript.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/aboutscript.py index d6b45ebf5..1b0806de3 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/aboutscript.py +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/aboutscript.py @@ -4,7 +4,7 @@ from scriptutils import open_url from scriptutils.userinput import WPFWindow from pyrevit.coreutils.git import compare_branch_heads -from pyrevit.versionmgr import PYREVIT_VERSION +from pyrevit.versionmgr import PYREVIT_VERSION, PYREVIT_REPO from pyrevit.versionmgr.updater import get_pyrevit_repo, has_pending_updates @@ -20,7 +20,12 @@ def __init__(self, xaml_file_name): self.set_image_source('pyrevit_logo', 'pyRevitlogo.png') self.set_image_source('keybase_profile', 'keybase.png') - self.version_info.Text = 'v {}'.format(PYREVIT_VERSION.get_formatted()) + try: + self.version_info.Text = ' v{}'.format(PYREVIT_VERSION.get_formatted()) + if PYREVIT_REPO.branch != 'master': + self.branch_info.Text = ' ({})'.format(PYREVIT_REPO.branch) + except: + self.version_info.Text = '' self.pyrevit_subtitle.Text += '\nRunning on IronPython {}.{}.{}'.format(sys.version_info.major, sys.version_info.minor, sys.version_info.micro) diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase.png b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase.png index 4e35ba9f5..3109766a6 100644 Binary files a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase.png and b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase.png differ diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybasew.png b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase_old.png similarity index 55% rename from extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybasew.png rename to extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase_old.png index c975df173..4e35ba9f5 100644 Binary files a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybasew.png and b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/keybase_old.png differ diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/script.py deleted file mode 100644 index d6b45ebf5..000000000 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/About.pushbutton/script.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -import sys - -from scriptutils import open_url -from scriptutils.userinput import WPFWindow -from pyrevit.coreutils.git import compare_branch_heads -from pyrevit.versionmgr import PYREVIT_VERSION -from pyrevit.versionmgr.updater import get_pyrevit_repo, has_pending_updates - - -__doc__ = 'About pyrevit. Opens the pyrevit blog website. You can find detailed information on how pyrevit works, ' \ - 'updates about the new tools and changes, and a lot of other information there.' - - -class AboutWindow(WPFWindow): - def __init__(self, xaml_file_name): - WPFWindow.__init__(self, xaml_file_name) - - self.set_image_source('image_credits', 'credits.png') - self.set_image_source('pyrevit_logo', 'pyRevitlogo.png') - self.set_image_source('keybase_profile', 'keybase.png') - - self.version_info.Text = 'v {}'.format(PYREVIT_VERSION.get_formatted()) - self.pyrevit_subtitle.Text += '\nRunning on IronPython {}.{}.{}'.format(sys.version_info.major, - sys.version_info.minor, - sys.version_info.micro) - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def opengithubrepopage(self, sender, args): - open_url('https://github.com/eirannejad/pyRevit') - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def opengithubcommits(self, sender, args): - open_url('https://github.com/eirannejad/pyRevit/commits/master') - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def openrevisionhistory(self, sender, args): - open_url('http://eirannejad.github.io/pyRevit/releasenotes/') - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def opencredits(self, sender, args): - open_url('http://eirannejad.github.io/pyRevit/credits/') - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def openkeybaseprofile(self, sender, args): - open_url('https://keybase.io/ein') - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def handleclick(self, sender, args): - self.Close() - - # noinspection PyUnusedLocal - # noinspection PyMethodMayBeStatic - def onactivated(self, sender, args): - pass - # pyrvt_repo = get_pyrevit_repo() - # if has_pending_updates(pyrvt_repo): - # hist_div = compare_branch_heads(pyrvt_repo) - # self.version_info.Text = '{} {}'.format(self.version_info.Text, hist_div.BehindBy) - - -if __name__ == '__main__': - AboutWindow('AboutWindow.xaml').ShowDialog() diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Master Test.pushbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Master Test.pushbutton/script.py index 4b3c5c980..65734eca4 100644 --- a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Master Test.pushbutton/script.py +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Master Test.pushbutton/script.py @@ -100,8 +100,6 @@ def __selfinit__(script_cmp, commandbutton, __rvt__): print 'Window hndlr: {}'.format(__window__) print 'File: {}'.format(__file__) print 'Forced Debug: {}'.format(__forceddebugmode__) -print 'Message: {}'.format(__message__) -print 'Result: {}'.format(__result__) su.this_script.output.print_md('**Testing linkify:**') print('Clickable element id: {}'.format(su.this_script.output.linkify(ElementId(1557)))) diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Test Engine Performance.pushbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Test Engine Performance.pushbutton/script.py new file mode 100644 index 000000000..fbe0a3e10 --- /dev/null +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/Labs.pulldown/Test Engine Performance.pushbutton/script.py @@ -0,0 +1,73 @@ +import clr + +from pyrevit import PYTHON_LIB_DIR, MAIN_LIB_DIR +from pyrevit.coreutils import Timer + +from scriptutils import this_script + +clr.AddReference('System') +clr.AddReference('IronPython') +# noinspection PyUnresolvedReferences +from System.Collections.Generic import List +# noinspection PyUnresolvedReferences +import IronPython.Hosting +import IronPython.Runtime + + +TEST_UNIT = 100 +MAX_TESTS = 5 * TEST_UNIT +script = "import random; random.randint(1,10)" + + +def run(engine, runtime): + scope = runtime.CreateScope() + co = engine.GetCompilerOptions(scope) + # co.Module &= ~IronPython.Runtime.ModuleOptions.Optimized + source = engine.CreateScriptSourceFromString(script) + comped = source.Compile() + comped.Execute(scope) + + +def make_engine(): + options = {"Frames": True, "FullFrames": True, "LightweightScopes": True} + engine = IronPython.Hosting.Python.CreateEngine(options) + engine.SetSearchPaths(List[str]([PYTHON_LIB_DIR, MAIN_LIB_DIR])) + runtime = engine.Runtime + return engine, runtime + + +def shutdown(runtime): + runtime.Shutdown() + + +engine_times = [] +output_times = [] + +for idx in range(1, MAX_TESTS): + engine, runtime = make_engine() + engine_timer = Timer() + run(engine, runtime) + eng_time = engine_timer.get_time() + shutdown(runtime) + engine_times.append(eng_time) + + output_timer = Timer() + print('Engine {}: {}'.format(idx, eng_time)) + output_times.append(output_timer.get_time()) + + +chart = this_script.output.make_line_chart() +# chart.options.scales = {'xAxes': [{'ticks': {'fixedStepSize': 5}, 'type': 'category', 'position': 'bottom'}], +# 'yAxes': [{'ticks': {'fixedStepSize': 10}}]} + +chart.data.labels = [x for x in range(0, MAX_TESTS + 1)] + +engine_dataset = chart.data.new_dataset('engine_timer') +engine_dataset.set_color(0xc3, 0x10, 0x10, 0.4) +engine_dataset.data = engine_times + +output_dataset = chart.data.new_dataset('output_timer') +output_dataset.set_color(0xf0, 0xa7, 0x19, 0.4) +output_dataset.data = output_times + +chart.draw() diff --git a/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/WIP Tools.pulldown/Graph Area Types.pushbutton/script.py b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/WIP Tools.pulldown/Graph Area Types.pushbutton/script.py new file mode 100644 index 000000000..eda011782 --- /dev/null +++ b/extensions/pyRevitCore.extension/pyRevit.tab/pyRevit.panel/wip.stack3/WIP Tools.pulldown/Graph Area Types.pushbutton/script.py @@ -0,0 +1,35 @@ +"""Display the total area of different area types in a graph.""" + +from scriptutils import this_script +from revitutils import doc, selection + +# noinspection PyUnresolvedReferences +from Autodesk.Revit.DB import FilteredElementCollector, ElementId, BuiltInCategory, Area + + +areas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas)\ + .WhereElementIsNotElementType().ToElements() + + +total = dict() +for area in areas: + try: + area_type = area.LookupParameter('Area Type').AsValueString() + if area_type.lower() != '(none)': + if area_type in total: + total[area_type] += area.Area + else: + total[area_type] = area.Area + except: + continue + +this_script.output.set_width(400) +this_script.output.set_height(450) + +chart = this_script.output.make_pie_chart() +chart.data.labels = total.keys() +area_dataset = chart.data.new_dataset('area types') +area_dataset.data = [round(v, 2) for v in total.values()] + +chart.randomize_colors() +chart.draw() diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Copy Selected ElementIds To Clipboard.pushbutton/script.py b/extensions/pyRevitTools.extension/_deprecated tools/Copy Selected ElementIds To Clipboard.pushbutton/script.py similarity index 100% rename from extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Copy Selected ElementIds To Clipboard.pushbutton/script.py rename to extensions/pyRevitTools.extension/_deprecated tools/Copy Selected ElementIds To Clipboard.pushbutton/script.py diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Analyse.pulldown/Find Range Of Roof Slopes.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Analyse.pulldown/Find Range Of Roof Slopes.pushbutton/script.py index 3d2f9c1bf..82b295c8d 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Analyse.pulldown/Find Range Of Roof Slopes.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Analysis.panel/Tools.stack2/Analyse.pulldown/Find Range Of Roof Slopes.pushbutton/script.py @@ -1,3 +1,4 @@ +from scriptutils import this_script from revitutils import doc # noinspection PyUnresolvedReferences @@ -17,12 +18,15 @@ if p: s = p.AsValueString() if s in slopes.keys(): - slopes[s].append(el.Id.IntegerValue) + slopes[s].append(el.Id) else: - slopes[s] = [el.Id.IntegerValue] + slopes[s] = [el.Id] -for sl, elid in slopes.items(): +for sl, elids in slopes.items(): print('SLOPE: {0}'.format(sl)) print('ROOF ELEMENTS WITH THIS SLOPE:') - print(elid) + el_links = '' + for elid in elids: + el_links += this_script.output.linkify(elid) + print(el_links) print('\n') diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Add Group Elements.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Add Group Elements.pushbutton/icon.png new file mode 100644 index 000000000..ae2a79396 Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Add Group Elements.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Add Tagged Elements.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Add Tagged Elements.pushbutton/icon.png new file mode 100644 index 000000000..a35b3bfdb Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Add Tagged Elements.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Find And Select Entities Without Tags.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Find And Select Entities Without Tags.pushbutton/icon.png index 19f043c58..556b5c9fa 100644 Binary files a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Find And Select Entities Without Tags.pushbutton/icon.png and b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/Find And Select Entities Without Tags.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/icon.png b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/icon.png new file mode 100644 index 000000000..c660079e1 Binary files /dev/null and b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/icon.png differ diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/script.py index 5279123e2..9224bb066 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Selection.panel/select.stack3/Select.pulldown/List Selection as Clickable Links.pushbutton/script.py @@ -5,5 +5,5 @@ this_script.output.set_width(200) -for elid in selection.element_ids: - print(this_script.output.linkify(elid)) +for idx, elid in enumerate(selection.element_ids): + print('{}: {}'.format(idx+1, this_script.output.linkify(elid))) diff --git a/pyrevitlib/pyrevit/__init__.py b/pyrevitlib/pyrevit/__init__.py index 5f54c8961..5bc92178c 100644 --- a/pyrevitlib/pyrevit/__init__.py +++ b/pyrevitlib/pyrevit/__init__.py @@ -14,7 +14,7 @@ PYREVIT_ADDON_NAME = 'pyRevit' VERSION_MAJOR = 4 -VERSION_MINOR = 1 +VERSION_MINOR = 2 # ---------------------------------------------------------------------------------------------------------------------- diff --git a/pyrevitlib/pyrevit/coreutils/__init__.py b/pyrevitlib/pyrevit/coreutils/__init__.py index edd3eb3b0..c773a885d 100644 --- a/pyrevitlib/pyrevit/coreutils/__init__.py +++ b/pyrevitlib/pyrevit/coreutils/__init__.py @@ -266,6 +266,10 @@ def prepare_html_str(input_string): return input_string.replace('<', '&clt;').replace('>', '&cgt;') +def reverse_html(input_html): + return input_html.replace('&clt;', '<').replace('&cgt;', '>') + + # def check_internet_connection(): # client = WebClient() # try: diff --git a/pyrevitlib/pyrevit/coreutils/git.py b/pyrevitlib/pyrevit/coreutils/git.py index 444f22e45..b98c8a268 100644 --- a/pyrevitlib/pyrevit/coreutils/git.py +++ b/pyrevitlib/pyrevit/coreutils/git.py @@ -51,6 +51,7 @@ def __init__(self, repo): self.head_name = repo.Head.Name self.last_commit_hash = repo.Head.Tip.Id.Sha self.repo = repo + self.branch = repo.Head.Name self.username = self.password = None def __repr__(self): diff --git a/pyrevitlib/pyrevit/coreutils/logger.py b/pyrevitlib/pyrevit/coreutils/logger.py index 5a87e0e11..0657ce56e 100644 --- a/pyrevitlib/pyrevit/coreutils/logger.py +++ b/pyrevitlib/pyrevit/coreutils/logger.py @@ -75,8 +75,6 @@ def _log(self, level, msg, args, exc_info=None, extra=None): msg_str = str(msg) else: msg_str = msg - # get rid of unicode characters - msg_str = msg_str.encode('ascii', 'ignore') msg_str = msg_str.replace(os.path.sep, '/') msg_str = emojize(msg_str) if level == logging.INFO: diff --git a/pyrevitlib/pyrevit/loader/basetypes/_config.cs b/pyrevitlib/pyrevit/loader/basetypes/_config.cs index bd03b95e2..f812840f5 100644 --- a/pyrevitlib/pyrevit/loader/basetypes/_config.cs +++ b/pyrevitlib/pyrevit/loader/basetypes/_config.cs @@ -5,7 +5,7 @@ public static class ExternalConfig public static string doctype = ""; public static string htmlstyle = "font-size:9pt;font-family:Verdana;margin:0px 0px 15px 0px;padding:0px;height:100%;scrollbar-base-color:#EEE;scrollbar-face-color:#DDD;scrollbar-highlight-color:#EEE;scrollbar-shadow-color:#EEE;scrollbar-track-color:#EEE;scrollbar-arrow-color:#666;"; public static string defaultelement = "
"; - public static string errordiv = "
"; + public static string errordiv = "
"; public static string ipyerrtitle = "IronPython Traceback:"; public static string dotneterrtitle = "Script Executor Traceback:"; public static string progressbar = "
"; diff --git a/pyrevitlib/pyrevit/loader/basetypes/baseclasses.cs b/pyrevitlib/pyrevit/loader/basetypes/baseclasses.cs index f401962ba..a2ff3d11a 100644 --- a/pyrevitlib/pyrevit/loader/basetypes/baseclasses.cs +++ b/pyrevitlib/pyrevit/loader/basetypes/baseclasses.cs @@ -61,11 +61,10 @@ public Result Execute(ExternalCommandData commandData, ref string message, Eleme } // Get script executor - var executor = new ScriptExecutor( commandData, message, elements); + var executor = new ScriptExecutor(this, commandData, message, elements); // Execute script var result = executor.ExecuteScript(_script, _syspaths, _cmdName, _forcedDebugMode, _altScriptMode); - message = executor.Message; // Return results diff --git a/pyrevitlib/pyrevit/loader/basetypes/executor.cs b/pyrevitlib/pyrevit/loader/basetypes/executor.cs index 81f00404f..414646236 100644 --- a/pyrevitlib/pyrevit/loader/basetypes/executor.cs +++ b/pyrevitlib/pyrevit/loader/basetypes/executor.cs @@ -12,16 +12,18 @@ using Autodesk.Revit.DB; using System.Collections.Generic; + namespace PyRevitBaseClasses { /// Executes a script public class ScriptExecutor { private readonly ExternalCommandData _commandData; - private string _message; private readonly ElementSet _elements; private readonly UIApplication _revit; private readonly UIControlledApplication _uiControlledApplication; + private readonly PyRevitCommand _thisCommand; + public ScriptExecutor(UIApplication uiApplication, UIControlledApplication uiControlledApplication) { @@ -30,30 +32,21 @@ public ScriptExecutor(UIApplication uiApplication, UIControlledApplication uiCon _commandData = null; _elements = null; - _message = null; } - public ScriptExecutor(ExternalCommandData commandData, string message, ElementSet elements) + + public ScriptExecutor(PyRevitCommand cmd, ExternalCommandData commandData, string message, ElementSet elements) { + _thisCommand = cmd; _revit = commandData.Application; _commandData = commandData; _elements = elements; - _message = message; _uiControlledApplication = null; } - public string Message - { - get - { - return _message; - } - } - - /// Run the script and print the output to a new output window. public int ExecuteScript(string sourcePath, string syspaths, string cmdName, bool forcedDebugMode, bool altScriptMode) @@ -62,12 +55,13 @@ public int ExecuteScript(string sourcePath, string syspaths, string cmdName, { // Setup engine and set __file__ var engine = CreateEngine(); - var scope = SetupEnvironment(engine); + var scope = CreateScope(engine); // Get builtin scope to add custom variables var builtin = IronPython.Hosting.Python.GetBuiltinModule(engine); // add engine to builtins builtin.SetVariable("__ipyengine__", engine); + builtin.SetVariable("__externalcommand__", _thisCommand); // add command path to builtins builtin.SetVariable("__commandpath__", Path.GetDirectoryName(sourcePath)); builtin.SetVariable("__commandname__", cmdName); // add command name to builtins @@ -93,7 +87,7 @@ public int ExecuteScript(string sourcePath, string syspaths, string cmdName, // Setup IO streams engine.Runtime.IO.SetOutput(outputStream, Encoding.UTF8); engine.Runtime.IO.SetErrorOutput(outputStream, Encoding.UTF8); - engine.Runtime.IO.SetInput(outputStream, Encoding.UTF8); + // engine.Runtime.IO.SetInput(outputStream, Encoding.UTF8); scope.SetVariable("__file__", sourcePath); @@ -116,8 +110,6 @@ public int ExecuteScript(string sourcePath, string syspaths, string cmdName, outputStream.WriteError(string.Join("\n", ExternalConfig.ipyerrtitle, string.Join("\n", errors.Errors.ToArray()))); - _message = ""; - engine.Runtime.Shutdown(); return (int)Result.Cancelled; } @@ -127,14 +119,11 @@ public int ExecuteScript(string sourcePath, string syspaths, string cmdName, { script.Execute(scope); - _message = (scope.GetVariable("__message__") ?? "").ToString(); - engine.Runtime.Shutdown(); - return (int)(scope.GetVariable("__result__") ?? Result.Succeeded); + return (int)Result.Succeeded; } catch (SystemExitException) { // ok, so the system exited. That was bound to happen... - engine.Runtime.Shutdown(); return (int)Result.Succeeded; } catch (Exception exception) @@ -152,19 +141,17 @@ public int ExecuteScript(string sourcePath, string syspaths, string cmdName, _dotnet_err_message = string.Join("\n", ExternalConfig.dotneterrtitle, _dotnet_err_message); outputStream.WriteError(_ipy_err_messages + "\n\n" + _dotnet_err_message); - _message = ""; - engine.Runtime.Shutdown(); return (int)Result.Cancelled; } } catch (Exception ex) { - _message = ex.ToString(); return (int)Result.Failed; } } + private ScriptEngine CreateEngine() { var engine = IronPython.Hosting.Python.CreateEngine(new Dictionary() @@ -174,6 +161,7 @@ private ScriptEngine CreateEngine() return engine; } + private void AddEmbeddedLib(ScriptEngine engine) { // use embedded python lib @@ -189,22 +177,21 @@ where name.ToLowerInvariant().EndsWith("python_27_lib.zip") /// Set up an IronPython environment - for interactive shell or for canned scripts - public ScriptScope SetupEnvironment(ScriptEngine engine) + public ScriptScope CreateScope(ScriptEngine engine) { var scope = IronPython.Hosting.Python.CreateModule(engine, "__main__"); - SetupEnvironment(engine, scope); + SetupScope(engine, scope); return scope; } - public void SetupEnvironment(ScriptEngine engine, ScriptScope scope) + + public void SetupScope(ScriptEngine engine, ScriptScope scope) { // these variables refer to the signature of the IExternalCommand.Execute method scope.SetVariable("__commandData__", _commandData); - scope.SetVariable("__message__", _message); scope.SetVariable("__elements__", _elements); - scope.SetVariable("__result__", (int)Result.Succeeded); // add two special variables: __revit__ and __vars__ to be globally visible everywhere: var builtin = IronPython.Hosting.Python.GetBuiltinModule(engine); diff --git a/pyrevitlib/pyrevit/loader/basetypes/outputstream.cs b/pyrevitlib/pyrevit/loader/basetypes/outputstream.cs index 8165b5f49..d2b2c2cf8 100644 --- a/pyrevitlib/pyrevit/loader/basetypes/outputstream.cs +++ b/pyrevitlib/pyrevit/loader/basetypes/outputstream.cs @@ -16,35 +16,52 @@ namespace PyRevitBaseClasses public class ScriptOutputStream: Stream { private readonly ScriptOutput _gui; - private int _bomCharsLeft; // we want to get rid of pesky UTF8-BOM-Chars on write - private readonly Queue _completedLines; // one memorystream per line of input - private MemoryStream _inputBuffer; + private readonly Queue _outputBuffer = new Queue(); public ScriptOutputStream(ScriptOutput gui) { _gui = gui; - _gui.txtStdOut.Focus(); - - _completedLines = new Queue(); - _inputBuffer = new MemoryStream(); + _gui.FocusOutput(); } + public void write(string s) { Write(Encoding.ASCII.GetBytes(s), 0, s.Length); + Flush(); } + public void WriteError(string error_msg) { - var err_div = _gui.txtStdOut.Document.CreateElement(ExternalConfig.errordiv); - err_div.InnerHtml = error_msg.Replace("\n", "
"); + lock (this) + { + if (_gui.IsDisposed) + { + return; + } - var output_err_message = err_div.OuterHtml.Replace("<", "&clt;").Replace(">", "&cgt;"); - Write(Encoding.ASCII.GetBytes(output_err_message), 0, output_err_message.Length); + if (!_gui.Visible) + { + _gui.Show(); + } + + _gui.Write(error_msg.Replace("\n", "
"), ExternalConfig.errordiv); + } } + /// Append the text in the buffer to gui.txtStdOut public override void Write(byte[] buffer, int offset, int count) + { + // Copy written data to new buffer and add to output queue + byte[] data = new byte[count]; + Array.Copy(buffer, offset, data, 0, count); + _outputBuffer.Enqueue(data); + } + + + public override void Flush() { lock (this) { @@ -58,83 +75,73 @@ public override void Write(byte[] buffer, int offset, int count) _gui.Show(); } - var actualBuffer = new byte[count]; - Array.Copy(buffer, offset, actualBuffer, 0, count); - var text = Encoding.UTF8.GetString(actualBuffer); - _gui.BeginInvoke((Action)delegate() - { - // Cleanup output for html - var div = _gui.txtStdOut.Document.CreateElement(ExternalConfig.defaultelement); - // if (text.StartsWith("\n")) - // text = text.Remove(0); - if (text.EndsWith("\n")) - text = text.Remove(text.Length - 1); - text = text.Replace("<", "<").Replace(">", ">"); - text = text.Replace("&clt;", "<").Replace("&cgt;", ">"); - text = text.Replace("\n", "
"); - text = text.Replace("\t", "  "); - div.InnerHtml = text; - _gui.txtStdOut.Document.Body.AppendChild(div); - }); - _gui.ScrollToBottom(); + // pull everything out of the queue and create a string to be processed for html output + byte[] curr; + String text = String.Empty; + while (_outputBuffer.Count > 0) { + curr = _outputBuffer.Dequeue(); + text += Encoding.UTF8.GetString(curr); + } + + // Cleanup output for html + if (text.EndsWith("\n")) + text = text.Remove(text.Length - 1); + text = text.Replace("<", "<").Replace(">", ">"); + text = text.Replace("&clt;", "<").Replace("&cgt;", ">"); + text = text.Replace("\n", "
"); + text = text.Replace("\t", "  "); + + _gui.Write(text, ExternalConfig.defaultelement); } } - public override void Flush() - { - } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } + public override void SetLength(long value) { throw new NotImplementedException(); } - /// Read from the _inputBuffer, block until a new line has been entered... + public override int Read(byte[] buffer, int offset, int count) { - while (_completedLines.Count < 1) - { - if (_gui.Visible == false) - { - throw new EndOfStreamException(); - } - // wait for user to complete a line - Application.DoEvents(); - Thread.Sleep(10); - } - var line = _completedLines.Dequeue(); - return line.Read(buffer, offset, count); + throw new NotImplementedException(); } + public override bool CanRead { - get { return !_gui.IsDisposed; } + get { return false; } } + public override bool CanSeek { get { return false; } } + public override bool CanWrite { get { return true; } } + public override long Length { get { return _gui.txtStdOut.DocumentText.Length; } } + public override long Position { - get { return 0; } - set { } + get { return _gui.txtStdOut.DocumentText.Length; } + set {} } } } diff --git a/pyrevitlib/pyrevit/loader/basetypes/outputwindow.cs b/pyrevitlib/pyrevit/loader/basetypes/outputwindow.cs index ddf9e63be..9c37b5f2d 100644 --- a/pyrevitlib/pyrevit/loader/basetypes/outputwindow.cs +++ b/pyrevitlib/pyrevit/loader/basetypes/outputwindow.cs @@ -9,6 +9,7 @@ public partial class ScriptOutput : Form public delegate void CustomProtocolHandler(String url); public CustomProtocolHandler UrlHandler; + public ScriptOutput() { Application.EnableVisualStyles(); @@ -25,6 +26,7 @@ public ScriptOutput() } + private void ScriptOutput_Load(object sender, EventArgs e) {} public void ScrollToBottom() @@ -38,6 +40,22 @@ public void ScrollToBottom() } } + + public void FocusOutput() + { + txtStdOut.Focus(); + } + + + public void Write(String OutputText, String HtmlElementType) + { + var div = txtStdOut.Document.CreateElement(HtmlElementType); + div.InnerHtml = OutputText; + txtStdOut.Document.Body.AppendChild(div); + ScrollToBottom(); + } + + private void txtStdOut_Navigating(object sender, WebBrowserNavigatingEventArgs e) { if (!(e.Url.ToString().Equals("about:blank", StringComparison.InvariantCultureIgnoreCase))) @@ -54,6 +72,7 @@ private void txtStdOut_Navigating(object sender, WebBrowserNavigatingEventArgs e } } + public void ShowProgressBar() { // MOST IMP : processes all windows messages queue @@ -70,6 +89,7 @@ public void ShowProgressBar() } } + public void UpdateProgressBar(float curValue, float maxValue) { // MOST IMP : processes all windows messages queue @@ -87,6 +107,7 @@ public void UpdateProgressBar(float curValue, float maxValue) } } + public void SelfDestructTimer(int miliseconds) { @@ -97,6 +118,7 @@ public void SelfDestructTimer(int miliseconds) timer.Enabled = true; } + private static void SelfDestructTimerEvent(object source, System.Timers.ElapsedEventArgs e, ScriptOutput output_window) { output_window.Close(); diff --git a/pyrevitlib/pyrevit/versionmgr/__init__.py b/pyrevitlib/pyrevit/versionmgr/__init__.py index 03285bb60..094e18861 100644 --- a/pyrevitlib/pyrevit/versionmgr/__init__.py +++ b/pyrevitlib/pyrevit/versionmgr/__init__.py @@ -42,9 +42,11 @@ def get_pyrevit_repo(): if not EXEC_PARAMS.doc_mode: try: - PYREVIT_VERSION = PyRevitVersion(get_pyrevit_repo().last_commit_hash) + PYREVIT_REPO = get_pyrevit_repo() + PYREVIT_VERSION = PyRevitVersion(PYREVIT_REPO.last_commit_hash) except Exception as ver_err: logger.error('Can not get pyRevit patch number. | {}'.format(ver_err)) PYREVIT_VERSION = PyRevitVersion('?') else: + PYREVIT_REPO = None PYREVIT_VERSION = None