├── .deploy-extras └── macos │ ├── IMPORTANT-README-BEFORE-RUNNING.txt │ ├── fix-permissions-automator-app.zip │ └── fix-permissions.command ├── .env ├── .github └── workflows │ ├── build-snap.yml │ └── offline │ ├── build-all-os-except-mac.yml │ ├── build-all-os.yml │ ├── build-mac.yml │ ├── build-snap-18.04.yml │ └── run-unittests.yml ├── .gitignore ├── .requirement-extras ├── buildwin_github-actions.iss ├── requirements-linux-22.txt ├── requirements-linux-common.txt └── requirements-travis.txt ├── .travis.yml ├── .vscode ├── launch.json ├── pynsource-multi.code-workspace └── settings.json ├── Admin ├── 2to3_Research.filelist.log ├── 2to3_Research.log ├── 2to3_src.filelist.log ├── 2to3_src.log ├── README.md ├── announcements │ ├── Readme_deprecated.txt │ ├── comp.lang.python.announce - Google Groups.url │ ├── pynsource yahoo group.url │ ├── web_macpedia_2012.png │ └── web_modelling_blog_2012.png ├── bitly-releases │ ├── bitly.py │ └── requirements-bitlytool.txt ├── doco-uml │ ├── Documentation on PyNSource models.docx │ ├── Documentation on PyNSource models.odt │ ├── OGL-like UML 2015.png │ ├── Overlap Unit Test Visual Doco.docx │ ├── ParsereportgenUML1.pdf │ ├── UML pynsource - corelayout1.pdf │ ├── UML pynsource - pynsourcegui1.pdf │ ├── UML_pynsource parse01.pdf │ ├── UML_pynsourceGUI.pdf │ ├── UML_wxOGL.pdf │ ├── comment nodes - UML class-sequence-combo diagram 2019.pdf │ ├── epydoc_pynsource_proj1.prj │ ├── gen_epydoc.bat │ ├── gui_uml.plantuml │ ├── gui_uml_01_sha_884410.png │ ├── gui_uml_latest.png │ ├── parse_model_uml.png │ ├── pynsource 1 - overview uml july 2012.pdf │ ├── pynsource 1.eap │ ├── pynsource classentry dict 1.png │ ├── pynsource devel notes scans.pdf │ ├── pynsourceUML-2015.mic │ ├── pynsourceUML-2015.pdf │ └── uml_ascii_sideways1.txt ├── site-andypatterns │ ├── AndyPatterns old Download.htm │ ├── AndyPatterns old PyNSource - UML tool for Python.htm │ ├── When 1.6 release old_pages_archived.html │ └── yUml vs Ogl render 1.png ├── site-atug │ ├── pynsource-latest-devel.txt │ └── pynsource-latest.txt ├── site-sourceforge │ ├── PyNSource Home on SourceForge.net.url │ ├── readme moved to google.markdown │ ├── sfmigrate.bat │ └── sourceforge info misc.txt ├── svnlog.txt └── todo │ └── todo.txt ├── BUILDING.md ├── CHANGELOG.md ├── DOWNLOADS.md ├── INSTALL-TIPS.md ├── README.md ├── Research ├── async play │ ├── frame_and_event_linux_bug.py │ ├── report_snap_env.py │ ├── repro_wxasync_042_bug.py │ ├── requirements-linux.txt │ ├── rubber_band_async.py │ ├── simplest_wxapp.py │ ├── simplest_wxapp_with_menu.py │ ├── snapcraft-verbose.yaml │ ├── snapcraft.yaml │ ├── turtle_avoidance_all.py │ ├── turtle_avoidance_oninit_all.py │ ├── turtle_avoidance_oninit_coroutine.py │ ├── wxasync041.py │ ├── wxasync042.py │ ├── wxasync1.py │ ├── wxasync_local.py │ └── wxasync_official_bug.py ├── config techniques │ ├── pynsource.ini │ └── testConfigObj.py ├── hexmvc │ ├── .vscode │ │ └── settings.json │ ├── Overview of HexMVC.txt │ ├── architecture2 │ │ ├── architecture1.py │ │ ├── architecture2.py │ │ ├── architecture2_gui_formbuilder - broken.fbp │ │ ├── architecture2_gui_formbuilder.fbp │ │ └── architecture2_gui_gen.py │ ├── architecture3 │ │ ├── App.py │ │ ├── AppMainConfigDotnet │ │ │ ├── AppMainConfigDotnet.sln │ │ │ ├── AppMainConfigDotnetWinForm.pyproj │ │ │ ├── Program.py │ │ │ ├── ServerDotnet.py │ │ │ ├── ServerDotnetAdapter.py │ │ │ ├── UtilJsonDotnetAdapter.py │ │ │ ├── UtilRandomDotnetAdapter.py │ │ │ ├── ViewDotnetWinForm.py │ │ │ ├── ViewDotnetWinForm.resx │ │ │ ├── ViewDotnetWinFormAdapter.py │ │ │ ├── app.config │ │ │ ├── app_python_location_TEMPLATE.config │ │ │ ├── lib_andy_python │ │ │ │ ├── IronPython.Modules.dll │ │ │ │ ├── IronPython.Modules.xml │ │ │ │ ├── IronPython.dll │ │ │ │ ├── IronPython.xml │ │ │ │ ├── Microsoft.Dynamic.dll │ │ │ │ ├── Microsoft.Scripting.Metadata.dll │ │ │ │ └── Microsoft.Scripting.dll │ │ │ └── run.bat │ │ ├── AppMainConfigOo.py │ │ ├── AppMainConfigSql.py │ │ ├── Controller.py │ │ ├── ModelAdapterBase.py │ │ ├── ModelOo.py │ │ ├── ModelOoAdapter.py │ │ ├── ModelSql.py │ │ ├── ModelSqlAdapter.py │ │ ├── PersistenceOoHomegrown.py │ │ ├── PersistenceOoPickle.py │ │ ├── ServerBottleAdapter.py │ │ ├── ServerMockAdapter.py │ │ ├── UtilJsonStdpythonAdapter.py │ │ ├── UtilRandomStdpythonAdapter.py │ │ ├── ViewWx.fbp │ │ ├── ViewWx.py │ │ ├── ViewWxAdapter.py │ │ └── arch3.eap │ ├── bottle tests │ │ ├── bottle1.py │ │ ├── bottle1_bug.py │ │ ├── bottle3.py │ │ └── flask1.py │ ├── grand unified │ │ └── listing1.py │ ├── hexagon3 │ │ ├── favicon.ico │ │ ├── hexagon1.py │ │ ├── hexagon2.py │ │ ├── hexagon3.py │ │ ├── hexapp.py │ │ ├── hexappmodel.py │ │ ├── hexmodel_simple.py │ │ ├── hexmodel_sqlobject.py │ │ ├── hexmvc uml01.txt │ │ ├── hexmvcgui.py │ │ ├── hexmvcgui_formbuilder.fbp │ │ ├── hexmvcgui_gen.py │ │ ├── hexpersistence.py │ │ ├── hexpersistence_sqlobject.py │ │ ├── hexserver.py │ │ ├── junk.py │ │ ├── scraps.fbp │ │ ├── scraps.py │ │ ├── scrapswx.py │ │ ├── test1.fbp │ │ ├── tests │ │ │ └── test_hexmvc01.py │ │ └── views │ │ │ ├── ajax1.tpl │ │ │ └── hello_template.tpl │ ├── lib │ │ └── architecture_support.py │ ├── orm copycat test │ │ ├── copycat1.py │ │ └── files │ │ │ ├── copycat.log │ │ │ ├── snapshot_000000000000002.dat │ │ │ └── transaction_000000000000003.log │ ├── orm sqlobject test │ │ ├── Download SQLObject.url │ │ ├── andyormtest1.db │ │ └── andyormtest1.py │ └── puremv_minimal_to_hexmvc │ │ ├── puremvcminimalwx0nostartupcmd.py │ │ ├── puremvcminimalwx1_puremvc_stripped_out.py │ │ └── puremvcminimalwx2_as_hexmvc.py ├── joint │ ├── joint2019 │ │ ├── backbone.js │ │ ├── fullscreen_bug.py │ │ ├── joint.css │ │ ├── joint.js │ │ ├── joint.py │ │ ├── joint.shapes.uml.js │ │ ├── joint_uml_big1.html │ │ ├── jquery.js │ │ ├── lodash.js │ │ ├── umlcd.css │ │ └── umlcd.js │ ├── old_0.4 │ │ ├── joint.all.min.js │ │ ├── joint_andy1.html │ │ └── joint_andy2.html │ └── uml_1 │ │ ├── joint.css │ │ ├── joint.js │ │ ├── joint.shapes.uml.js │ │ └── joint_uml1.html ├── layout force spring │ ├── Test Graphs │ │ ├── graph b2 vs d42.txt │ │ ├── graph big 01.txt │ │ ├── graph big 02.txt │ │ ├── graph for unit tests 1.txt │ │ ├── graph line overlap 1.txt │ │ ├── graph line overlap little 1.txt │ │ ├── graph line overlap little 2.txt │ │ ├── graph line overlap little 2a.txt │ │ ├── graph line overlap little 2b.txt │ │ ├── graph line overlap little 2c.txt │ │ ├── graph snug up.txt │ │ ├── graph spring 1.txt │ │ ├── graph spring 2.txt │ │ ├── graph spring 3.txt │ │ ├── graph stress1.txt │ │ ├── graph tangle1.txt │ │ ├── graph tangle2 simple.txt │ │ ├── graph weight1.txt │ │ ├── graph weight2.txt │ │ ├── graph1.txt │ │ ├── graph2.txt │ │ └── jumbled3.txt │ ├── geometry_experiments.py │ ├── gui.py │ ├── gui_text.py │ ├── html-js-sketches-fun │ │ ├── box-layout1.html │ │ ├── box-layout2.html │ │ ├── box-layout3.html │ │ └── box-layout4.html │ ├── ori javascript │ │ ├── graph.js │ │ ├── index.html │ │ └── prototype-1.4.0.js │ ├── somepythonbug1.py │ └── test1.sqlite3 ├── misc information and doco │ ├── Coordinate System Used in PynSource Gui.txt │ ├── PyNSource.png │ ├── VisualPython by Guido 1994 talk.txt │ ├── Website - parseme java source for pic generation │ │ ├── Blah.java │ │ ├── ParseMeTest.java │ │ ├── ParseMeTest2.java │ │ └── variant.java │ ├── ppcomp.py │ ├── project names.txt │ ├── pyNSourceUML_example01.gif │ ├── pyNsourceGuiReversingItself01.gif │ ├── pynsource gui doodlings on coord systems.pdf │ ├── tokeniser google doco good short 01.htm │ ├── tokenize.htm │ ├── what tokens mean - sample 01.txt │ ├── what tokens mean - sample 02.txt │ └── xmi spec - 03-05-02.pdf ├── misc │ ├── IAN Online Conceptual Diagram Creator.url │ ├── Jacobo draw2d files demo.html │ ├── colorizePython.html │ ├── colorizePython.py │ ├── graph layout pictures.mic │ └── prtok.py ├── networkx graphs │ ├── README networkx install.txt │ ├── WCC.pgn.bz2 │ ├── andylayoutuml.py │ ├── atlas.py │ ├── chess_masters.png │ ├── chess_masters.py │ ├── edgelist.utf-8 │ ├── weighted_graph.png │ └── weighted_graph.py ├── ogl tests 01 │ ├── OGLlike.py │ ├── OGLlike_original.py │ ├── OGLlike_pylab.py │ ├── andyOgl01_oldwx.py │ ├── andyOgl02_oldwx.py │ ├── images.py │ ├── images_oldwx.py │ ├── img_uml01.png │ ├── ogl notes.txt │ ├── ogl_andyshape1.py │ ├── ogl_animate1.py │ ├── ogl_animate1_threaded.py │ ├── ogl_mousechasing.py │ ├── ogl_official_demo1.py │ ├── ogl_redraw_f_logic.py │ ├── ogl_resize_frame1.py │ ├── ogl_scroll1.py │ ├── ogl_scroll2.py │ ├── ogl_scroll3_gtk_virtarea_draw_bug.py │ ├── ogl_scroll_for_maillist.py │ ├── ogl_scroll_for_maillist2.py │ ├── ogl_simple1.py │ ├── ogl_simple2.py │ ├── ogl_simple2_wxasync.py │ ├── ogl_simple3.py │ ├── ogllike_pylab_test.py │ └── ogllike_uml.py ├── overlap_removal_server │ ├── README.md │ ├── client_example │ │ ├── animated-move.js │ │ ├── editing.js │ │ ├── editing_offline.js │ │ ├── index.html │ │ ├── init.js │ │ ├── package-lock.json │ │ ├── remove-overlaps.js │ │ └── settings.js │ ├── flask_main.py │ ├── misc │ │ ├── animate_node.html │ │ ├── flask_play.py │ │ ├── notes-on-dbl-click.js │ │ └── payload1.js │ └── screenshots │ │ ├── example_client.png │ │ └── geogebra_debugging.png ├── parsing │ ├── ast_and_typed_ast │ │ ├── astbug_python3_8_regular_ast_ok.py │ │ ├── astbug_python3_8_typed_ast_fails.py │ │ └── astbug_python3_8_typed_ast_fails_simple.py │ ├── codegen.py │ ├── codegen_with_diagnostics.py │ ├── issues_85_93_94_parsing │ │ ├── demo.py │ │ ├── issue_85_type_hint.py │ │ ├── issue_93_subscript.py │ │ ├── issue_94_walrus.py │ │ └── type_hint_example.py │ ├── misc_parsing_play1.py │ └── pynsource-cli-deprecated.py ├── plantuml │ ├── api_example1.txt │ └── pynsource-plantuml-gui.py ├── python advanced │ ├── command_invokers1.py │ ├── decorator_dump_params1.py │ ├── decorator_function_call_counter1.py │ ├── decorator_function_call_counter2.py │ ├── interfaces1.py │ ├── interfaces2.py │ ├── listdiff.py │ ├── multicast.py │ ├── multicast_csharp_style1.py │ ├── multicast_csharp_style2 - threaded.py │ ├── multicast_csharp_style2.py │ ├── multicast_simplified_style2.py │ └── properties1.py ├── run_research_guis.bat ├── state chart editor │ ├── Adders.py │ ├── Editor.py │ ├── GUI.py │ ├── Globals.py │ ├── Handler.py │ ├── Link.py │ ├── Separator.py │ ├── State.py │ ├── Statechart.py │ ├── TopHandler.py │ ├── TransformHandlers.py │ ├── Transition.py │ ├── andy01.stt │ ├── icon16win.ico │ ├── junk.log │ ├── junk.pdf │ ├── junk.ps │ ├── junk.stt │ └── junk2.stt ├── winerack ogl and floatcanvas │ ├── Moo.jpg │ ├── fc_FloatCanvasDemo.py │ ├── fc_MiniDemo.py │ ├── fc_PolyEditor.py │ ├── fc_ProcessDiagram.py │ ├── fc_ScaleDemo.py │ ├── fc_ScaledBitmap2Demo.py │ ├── fc_world.dat │ ├── myimages.py │ ├── rackdesigner.py │ └── rackdesignerFC.py ├── wx doco │ ├── Custom CommandEvent in wxPython.url │ ├── ImageInHtml.py │ ├── ImageViewer0.py │ ├── ImageViewer0a.py │ ├── ImageViewer0b.py │ ├── ImageViewer1_pil.py │ ├── ImageViewer2.py │ ├── ImageViewer3.py │ ├── ImageViewer4.py │ ├── ImageViewer4scaled.py │ ├── ImageViewer6.py │ ├── ImageViewer7.py │ ├── ImageViewer7a.py │ ├── ImageViewer7b.py │ ├── Images │ │ ├── Moo.jpg │ │ ├── Physics-4.jpg │ │ ├── SPLASHSCREEN.BMP │ │ ├── SliderPuzzle.jpg │ │ ├── fish1.png │ │ ├── img_uml01.png │ │ ├── outyuml.png │ │ ├── outyuml_big.png │ │ ├── pickle.jpg │ │ ├── shader-ReflectiveBumpedVertexLit-0.jpg │ │ └── w05_783sidebar.jpg │ ├── LongRunning wx.gauge no while-loop.url │ ├── LongRunningTasks - wxPyWiki.url │ ├── MessageBox - MessageDialog - wxPython-users - Google Groups.url │ ├── Moo.jpg │ ├── Response from MessageDialog.url │ ├── about01.py │ ├── accelerator_bug.py │ ├── aui library Advanced Generic Widgets v0.9.1 documentation.url │ ├── bootstrap_for_wxdemos.py │ ├── custom_dialog01.py │ ├── drag-button.py │ ├── frameshow1.py │ ├── html_demo.py │ ├── images.py │ ├── inspector_mixin_play.py │ ├── put_icon_in_taskbar.py │ ├── python - wxPython- Making a scrollable DC - Stack Overflow.url │ ├── rclick_popup_menu1.py │ ├── resize_scroll_01.py │ ├── resize_scroll_02.py │ ├── rubber_band.py │ ├── scroll_window_in_action1.py │ ├── scrolling_panel01.py │ ├── someStyledTextCtrl1.py │ ├── someStyledTextCtrl2.py │ ├── someStyledTextCtrl3.py │ ├── someStyledTextCtrl4_spe1.py │ ├── some_wxaui1.py │ ├── some_wxaui2.py │ ├── somedoodle.py │ ├── somedoublebufferingdemo.py │ ├── somelongthread1.py │ ├── somelongthread1_main.py │ ├── somelongthread2_yield.py │ ├── somelongthread3_idle.py │ ├── somelongthread4_easy.py │ ├── somelongthread4_easy_interruptable.py │ ├── somenotebook0.py │ ├── somenotebook1.py │ ├── somepanelswitcher1.py │ ├── someplot1.py │ ├── someplot2_scroll.py │ ├── somesimple1.py │ ├── syntax_highlighting.py │ ├── wx Index.url │ ├── wx.MessageDialog.url │ ├── wx.ScrolledWindow.url │ ├── wx.Window.url │ ├── wx.lib.ogl.Diagram.url │ ├── wx.lib.ogl.url │ ├── wxOGL - wxPyWiki - MAIN EXAMPLES.url │ ├── wxPython dialogs.url │ ├── wxglade1 │ │ ├── wxgladeapp1.py │ │ ├── wxgladeapp2.py │ │ ├── wxglage1project.wxg │ │ ├── wxglage2project.wxg │ │ ├── wxglage2project.wxg.bak │ │ └── wxglage3project.wxg │ ├── wxpython Overview Of GDI.url │ └── zoom_canvas2d-plugin.py ├── wx form builder │ ├── 2019test1 │ │ ├── run.sh │ │ ├── test1.fbp │ │ ├── test1.py │ │ ├── test1_gen.py │ │ └── toucan.png │ ├── Doco Custom Component.png │ ├── Doco ogl Custom Component.png │ ├── fbogl1.fbp │ ├── fbogl1.py │ ├── fbogl1_gen.py │ ├── fbpyn1.fbp │ ├── fbpyn1.py │ ├── fbpyn1_gen.py │ ├── fbpyn1_scintilla.py │ ├── fbtest01.fbp │ ├── fbtest01.py │ ├── fbtest01_gen.py │ ├── icons16 │ │ ├── katomic.png │ │ ├── kcmprocessor.png │ │ ├── kcmscsi.png │ │ ├── kedit.png │ │ └── khangman.png │ ├── icons22 │ │ ├── kaboodleloop.png │ │ ├── kalarm.png │ │ ├── kalzium.png │ │ ├── kcmmidi.png │ │ ├── kcmprocessor.png │ │ ├── kcmscsi.png │ │ ├── kcontrol.png │ │ ├── kedit.png │ │ ├── khangman.png │ │ ├── kmid.png │ │ ├── kmoon.png │ │ ├── kopete_offline.png │ │ ├── kreversi.png │ │ ├── package_development.png │ │ ├── reload.png │ │ ├── roll.png │ │ └── tool_timer.png │ ├── icons32 │ │ ├── kalzium.png │ │ ├── kcmmidi.png │ │ ├── kcmprocessor.png │ │ ├── kcmscsi.png │ │ ├── kcontrol.png │ │ ├── kedit.png │ │ ├── khangman.png │ │ └── kmoon.png │ ├── images.py │ ├── someStyledTextCtrl2.py │ ├── some_fb1.fbp │ ├── some_fb1.py │ ├── some_fb2.fbp │ ├── some_fb2_1.py │ ├── some_fb2_2.py │ ├── some_fb2_2_altered.py │ ├── some_fb2_3.py │ ├── some_fb2_gen.py │ ├── some_fb2_gen_altered.py │ └── splitwin01.py ├── wxglade │ ├── test1 │ │ ├── test1.wxg │ │ └── wxglade_out.py │ └── test2 │ │ ├── myout │ │ ├── test2.py │ │ └── test2.wxg └── yuml_python │ ├── chromium launch idea.txt │ ├── copypng.py │ ├── create_yuml_class_diagram.py │ ├── example yuml1.txt │ ├── order.bat │ ├── outyuml2.png │ ├── png.py │ ├── pynsource-yuml-gui.py │ ├── pynsource1.bat │ ├── pynsource2.bat │ ├── pynsource3.bat │ ├── read_yuml_from_png.py │ ├── sample_pynsource_yuml.txt │ ├── write_end_of_png.py │ ├── yuml_order_example.png │ ├── yuml_pynsource1_example.png │ ├── yuml_pynsource2_example.png │ └── yuml_pynsource3_example.png ├── bin ├── _buildmedia.sh ├── _buildsamples.py ├── blackall ├── build-package ├── build-snap ├── build-snap-clean ├── build-snap-clean-python-stuff ├── build-snap-debug ├── buildmac ├── buildwin.bat ├── install-linux-18.04 ├── install-linux-20.04 ├── install-linux-fedora-33 ├── install-snap ├── lxd-containers-ls ├── lxd-shell ├── pip-install-ogl2-alsm-rego ├── pkill_python.command ├── publish-snap ├── r ├── run ├── run-py37 ├── run-py38 ├── run-snap ├── run-snap-with-shell ├── run-win10.bat ├── runpro ├── runpro-imac ├── runpro-linux ├── runpro-py37 ├── runpro-py38 ├── runpro-win10.bat ├── snap-bash-multipass ├── snap-build-multipass ├── snap-deploy ├── snap-expand-extensions ├── snap-install ├── snap-ls ├── snap-stopvm-multipass ├── snap-tree ├── testall ├── testall-win10.bat ├── testone ├── uninstall-snap └── viewconfig ├── requirements.txt ├── setup.py ├── snap ├── gui │ ├── pynsource.desktop │ └── pynsource.png ├── local │ ├── andy-diagnostics │ │ └── report_snap_env.py │ └── snapcraft-18.04.yaml └── snapcraft.yaml ├── src ├── .coveragerc ├── app │ ├── __init__.py │ ├── app.py │ ├── cmds │ │ ├── __init__.py │ │ ├── base_cmd.py │ │ ├── blackboard_frame.py │ │ ├── blackboard_thread.py │ │ ├── colouring.py │ │ ├── deletion.py │ │ ├── diagnostics.py │ │ ├── filemgmt.py │ │ ├── insertion.py │ │ ├── layouts.py │ │ ├── line_edge_type.py │ │ └── selection.py │ ├── controller.py │ └── settings.py ├── ascii_uml │ ├── __init__.py │ ├── asciiworkspace.py │ └── layout_ascii.py ├── bin │ ├── covergui │ ├── covertests │ ├── testcli │ └── testsingle ├── common │ ├── __init__.py │ ├── add_line_numbers.py │ ├── approx_equal.py │ ├── architecture_support.py │ ├── command_pattern.py │ ├── dialog_dir_path.py │ ├── gui_imageviewer.py │ ├── logger.py │ ├── logwriter.py │ ├── messages.py │ ├── plantuml.py │ ├── png.py │ ├── printframework.py │ ├── uml_colours.py │ └── url_to_data.py ├── dialogs │ ├── DialogChooseFromList.fbp │ ├── DialogChooseFromList.py │ ├── DialogChooseFromList_run.py │ ├── DialogComment.fbp │ ├── DialogComment.py │ ├── DialogPlantUmlText.fbp │ ├── DialogPlantUmlText.py │ ├── DialogRego.fbp │ ├── DialogRego.py │ ├── DialogRego_run.py │ ├── DialogUmlNodeEdit.fbp │ ├── DialogUmlNodeEdit.fbp.bak │ ├── DialogUmlNodeEdit.py │ ├── DialogUmlNodeEdit_run.py │ ├── FrameDeepLayout.fbp │ ├── FrameDeepLayout.py │ ├── FrameDeepLayout_run.py │ ├── FramePyYuml.fbp │ ├── FramePyYuml.py │ ├── HelpWindow.fbp │ ├── HelpWindow.html │ ├── HelpWindow.py │ ├── HelpWindow2.py │ ├── __init__.py │ └── help-images │ │ ├── cytoscape.png │ │ ├── gituml.jpg │ │ ├── help-ascii.jpg │ │ ├── help-colour.jpg │ │ ├── help01.jpg │ │ ├── plantuml01.jpg │ │ └── pro.jpg ├── generate_code │ ├── __init__.py │ ├── gen_asciiart.py │ ├── gen_base.py │ ├── gen_delphi.py │ ├── gen_java.py │ ├── gen_plantuml.py │ ├── gen_yuml.py │ └── plantuml_html_scan.py ├── gui │ ├── __init__.py │ ├── canvas_resizer.py │ ├── coord_utils.py │ ├── node_edit_multi_purpose.py │ ├── repair_ogl.py │ ├── settings.py │ ├── settings_wx.py │ ├── shape_menu_mgr.py │ ├── uml_canvas.py │ ├── uml_lines.py │ ├── uml_shape_handler.py │ ├── uml_shapes.py │ └── wx_log.py ├── layout │ ├── __init__.py │ ├── animation.py │ ├── blackboard.py │ ├── coordinate_mapper.py │ ├── data_testgraphs.py │ ├── layout_spring.py │ ├── line_crosses_shape.py │ ├── line_intersection.py │ ├── overlap_removal.py │ ├── permutations.py │ └── snapshots.py ├── media │ ├── about.png │ ├── images.py │ ├── pro.png │ ├── pynsource.ico │ └── pynsource.png ├── ogl │ ├── __init__.py │ ├── basic.py │ ├── bmpshape.py │ ├── canvas.py │ ├── composit.py │ ├── diagram.py │ ├── divided.py │ ├── drawn.py │ ├── lines.py │ └── oglmisc.py ├── parsing │ ├── __init__.py │ ├── alsm_set_module.py │ ├── api.py │ ├── class_entry.py │ ├── core_parser_ast.py │ ├── core_parser_old.py │ ├── dump_pmodel.py │ ├── keywords.py │ ├── parse_rhs_analyser.py │ ├── parse_source.py │ └── quick_parse.py ├── pynsource_cli.py ├── pynsource_gui.py ├── samples │ ├── __init__.py │ ├── a simple example.pyns │ ├── classic example.pyns │ ├── composition relationship.pyns │ ├── files_as_resource.py │ ├── multi level inheritance.pyns │ ├── nice diagram with comment.pyns │ ├── simple inheritance.pyns │ ├── the command pattern full.pyns │ ├── the command pattern.pyns │ ├── wx ogl architecture.pyns │ └── wx ogl divided shape.pyns ├── tests │ ├── __init__.py │ ├── alltests.py │ ├── misc manually run scripts │ │ ├── run_pynsource_asciiart.bat │ │ └── run_pynsource_yuml.bat │ ├── python-in │ │ ├── p2.py │ │ ├── p3.py │ │ ├── sort_attrs_example.py │ │ ├── testmodule01.py │ │ ├── testmodule02.py │ │ ├── testmodule03.py │ │ ├── testmodule04.py │ │ ├── testmodule05.py │ │ ├── testmodule06.py │ │ ├── testmodule07.py │ │ ├── testmodule08_multiple_inheritance.py │ │ ├── testmodule09_intense.py │ │ ├── testmodule10_old_cant_parse.py │ │ ├── testmodule11_incoming_bugs.py │ │ ├── testmodule66.py │ │ ├── testmodule67clippy.py │ │ ├── testmodule_asciiworkspace.py │ │ ├── testmodule_bug_pyplecs.py │ │ ├── testmodule_command_pattern.py │ │ ├── testmodule_printframework.py │ │ └── testmodule_pynsource.py │ ├── readme-tests.md │ ├── settings.py │ ├── test_asciiworkspace_01.py │ ├── test_asciiworkspace_02.py │ ├── test_ast_quickparse.py │ ├── test_coords.py │ ├── test_displaymodel.py │ ├── test_except.py │ ├── test_graph_nodes.py │ ├── test_java_delphi_gen.py │ ├── test_overlaps1.py │ ├── test_overlaps2stress.py │ ├── test_parse_01.py │ ├── test_parse_02.py │ ├── test_parse_03.py │ ├── test_parse_04.py │ ├── test_parse_05.py │ ├── test_parse_06.py │ ├── test_parse_07.py │ ├── test_parse_08.py │ ├── test_parse_bugs_incoming.py │ ├── test_parse_old_vs_new.py │ ├── test_parse_plantuml.py │ ├── test_parse_type_annotations.py │ ├── test_parse_yuml_01.py │ ├── test_persistence_01.py │ ├── test_plantuml_html_scan.py │ ├── test_quickparse_python.py │ ├── test_rhs_analyser.py │ ├── testing-generate-delphi │ │ ├── delphi-out │ │ │ ├── EventPlayAPI.pas │ │ │ ├── PlayAPI.pas │ │ │ ├── Playhead.pas │ │ │ ├── PlayheadMediator.pas │ │ │ ├── TestCase00.pas │ │ │ ├── TestCase01.pas │ │ │ ├── TestCase02.pas │ │ │ ├── TimePlayAPI.pas │ │ │ ├── TurnPlayAPI.pas │ │ │ ├── UniqueList.pas │ │ │ ├── unit_dict.pas │ │ │ ├── unit_list.pas │ │ │ └── unit_unittest.pas │ │ ├── python-in │ │ │ ├── playhead.py │ │ │ ├── playheadmanager.py │ │ │ └── utilcc.py │ │ └── run.bat │ └── testing-generate-java │ │ ├── java-ide-import-results │ │ ├── ea-JavaImportProj01.eap │ │ ├── ea-enterprisearchitect-uml.pdf │ │ ├── ea-enterprisearchitect01.emf │ │ ├── ess-first import diagram ess model.xmi │ │ ├── ess-pic01.png │ │ └── ess-pic01.wmf │ │ ├── java-out │ │ ├── EventPlayAPI.java │ │ ├── PlayAPI.java │ │ ├── Playhead.java │ │ ├── PlayheadMediator.java │ │ ├── TestCase00.java │ │ ├── TestCase01.java │ │ ├── TestCase02.java │ │ ├── TimePlayAPI.java │ │ ├── TurnPlayAPI.java │ │ ├── UniqueList.java │ │ ├── dict.java │ │ ├── list.java │ │ ├── object.java │ │ ├── unittest.java │ │ └── variant.java │ │ ├── python-in │ │ ├── playhead.py │ │ ├── playheadmanager.py │ │ └── utilcc.py │ │ └── run.bat └── view │ ├── __init__.py │ ├── display_model.py │ ├── graph.py │ └── graph_persistence.py └── tbump.toml /.deploy-extras/macos/IMPORTANT-README-BEFORE-RUNNING.txt: -------------------------------------------------------------------------------- 1 | After you download and unzip the release, you need to give permission for the app to run on your machine. 2 | This is because the app is not signed via the Apple Developer program which would otherwise cost me USD $99 per year. 3 | To do this, open a terminal and type: 4 | 5 | xattr -dr com.apple.quarantine ~/Downloads/pynsource-macos-version-1.85/Pynsource.app 6 | 7 | otherwise 8 | 9 | 🎉 Easier Technique: Right click on the supplied bash script "fix-permissions.command" and choose "Open" 10 | -------------------------------------------------------------------------------- /.deploy-extras/macos/fix-permissions-automator-app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/.deploy-extras/macos/fix-permissions-automator-app.zip -------------------------------------------------------------------------------- /.deploy-extras/macos/fix-permissions.command: -------------------------------------------------------------------------------- 1 | # Fix permissions on the .app because it is not signed (which would cost me approx AUD $150 each year) 2 | SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" 3 | APP_NAME="Pynsource.app" 4 | APP=$SCRIPTPATH/$APP_NAME 5 | xattr -dr com.apple.quarantine $APP 6 | # check if error 7 | if [ $? -eq 0 ]; then 8 | echo "Success: $APP_NAME permissions fixed - you should be able to run it now" 9 | osascript -e 'display dialog "permissions fixed"' 10 | else 11 | echo "Error fixing permissions" 12 | osascript -e 'display dialog "Error fixing permissions"' 13 | fi 14 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=src:${PYTHONPATH} -------------------------------------------------------------------------------- /.github/workflows/build-snap.yml: -------------------------------------------------------------------------------- 1 | name: Pynsource Snap 2 | on: 3 | push: 4 | # branches: [ main ] 5 | tags: ['v*', 'pre*'] 6 | 7 | # To trigger a build when above is set to tag 8 | # git tag -l 9 | # git tag -a v1.nn 10 | # git push --follow-tags 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - uses: snapcore/action-build@v1 18 | id: snapcraft 19 | 20 | - uses: actions/upload-artifact@v3 21 | with: 22 | name: snap 23 | path: ${{ steps.snapcraft.outputs.snap }} 24 | 25 | # Uploads the snap to edge channel, test via: sudo snap refresh pynsource --edge 26 | # This fails because of symlink issues, hopefully snapcraft 7.3.1.post17+git8b3ed19b and later fix it 27 | # 28 | - name: Snap upload 29 | id: snapcraft_upload 30 | env: 31 | SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.snapcraft_store_credentials }} 32 | run: | 33 | snapcraft upload *.snap --release edge 34 | -------------------------------------------------------------------------------- /.github/workflows/offline/build-snap-18.04.yml: -------------------------------------------------------------------------------- 1 | name: Pynsource Snap 2 | 3 | on: 4 | push: 5 | # branches: [ master ] 6 | # tags: ['build-test-*'] 7 | tags: ['pre-*', 'version-*'] 8 | 9 | jobs: 10 | my-snap-building-job: 11 | runs-on: ubuntu-18.04 # ubuntu-20.04 breaks 12 | 13 | steps: 14 | - name: Check out Git repository 15 | uses: actions/checkout@v2 16 | 17 | # https://github.com/marketplace/actions/snapcraft-action 18 | - name: Install Snapcraft, LXD and set Auth 19 | uses: samuelmeuli/action-snapcraft@v1 20 | with: 21 | use_lxd: true 22 | snapcraft_token: ${{ secrets.snapcraft_token }} 23 | 24 | # You can now run Snapcraft shell commands 25 | - name: Use Snapcraft - show help 26 | run: snapcraft --help 27 | 28 | - name: Build snap 29 | run: | 30 | sg lxd -c 'snapcraft --use-lxd' 31 | ls -l 32 | # unsquashfs -l *.snap 33 | 34 | - name: Save snap as artifact 35 | uses: actions/upload-artifact@v2 36 | with: 37 | name: snap_artifact 38 | path: ./*.snap 39 | 40 | # https://github.com/samuelmeuli/action-snapcraft/issues/28 41 | # Uploads the snap to edge channel, test via: sudo snap refresh pynsource --edge 42 | - name: Snap upload 43 | id: snapcraft 44 | run: | 45 | snapcraft upload *.snap --release edge 46 | -------------------------------------------------------------------------------- /.github/workflows/offline/run-unittests.yml: -------------------------------------------------------------------------------- 1 | # Run unittests under multiple OS's and multiple Pythons. 2 | # I also have a travis integration running these same tests under Python 3.9 on xenial (Ubuntu 16.04) - see .travis.yml 3 | name: Unittests 4 | on: 5 | push: 6 | branches: [ master, gh-building ] 7 | pull_request: 8 | branches: [ master ] 9 | jobs: 10 | build: 11 | runs-on: ${{ matrix.os }} 12 | 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest, macos-latest, windows-latest] 16 | python-version: [3.6, 3.7, 3.8, 3.9] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Set up Python 21 | uses: actions/setup-python@v1 22 | with: 23 | python-version: ${{ matrix.python-version }} 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip 27 | pip install -r .requirement-extras/requirements-travis.txt 28 | - name: Test with unittest 29 | shell: bash 30 | run: | 31 | export TRAVIS=1 32 | sh -c 'cd src && mkdir tests/logs && ./bin/testall' 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | out.png 3 | venv*/ 4 | .idea/ 5 | dist/ 6 | build/ 7 | .eggs 8 | Research/wxglade/*/*~ 9 | .coverage 10 | htmlcov/ 11 | src/tests/logs/ 12 | Research/wx doco/drag-button.spec 13 | .python-version 14 | *.snap 15 | junk*.py 16 | *.egg-info 17 | .flatpak-builder/ -------------------------------------------------------------------------------- /.requirement-extras/requirements-linux-22.txt: -------------------------------------------------------------------------------- 1 | # For linux users who want to install and actually build wxpython 2 | # which works on intel and also on linux on arm. You will first need to run 3 | # sudo apt-get install dpkg-dev build-essential python3-dev freeglut3-dev libgl1-mesa-dev libglu1-mesa-dev libgstreamer-plugins-base1.0-dev libgtk-3-dev libjpeg-dev libnotify-dev libpng-dev libsdl2-dev libsm-dev libtiff-dev libwebkit2gtk-4.0-dev libxtst-dev 4 | # and pip install attrdict3 (see https://github.com/wxWidgets/Phoenix/issues/2225) 5 | #wxPython>=4.0,<4.2.0 ; platform_system=="Linux" # See https://github.com/wxWidgets/Phoenix/issues/2225 6 | #wxPython==4.2.0 ; platform_system!="Linux" 7 | wxpython 8 | 9 | wxasync 10 | configobj 11 | requests 12 | typed_ast 13 | astpretty 14 | termcolor 15 | beautifultable 16 | appdirs 17 | wheel 18 | pydbg 19 | aiohttp 20 | async_lru 21 | 22 | Pillow 23 | py2app 24 | click 25 | #pytest 26 | #coverage 27 | #pytest-cov 28 | #black 29 | -------------------------------------------------------------------------------- /.requirement-extras/requirements-linux-common.txt: -------------------------------------------------------------------------------- 1 | # linux users please use the script bin/install-linux-* and not this file 2 | configobj 3 | requests 4 | typed_ast 5 | astpretty 6 | termcolor 7 | beautifultable 8 | appdirs 9 | wheel 10 | pydbg 11 | aiohttp 12 | async_lru 13 | 14 | Pillow 15 | py2app 16 | click 17 | pytest 18 | coverage 19 | pytest-cov 20 | black 21 | -------------------------------------------------------------------------------- /.requirement-extras/requirements-travis.txt: -------------------------------------------------------------------------------- 1 | # requirements for travis ci testing 2 | configobj 3 | requests 4 | typed_ast 5 | astpretty 6 | termcolor 7 | beautifultable 8 | appdirs 9 | pydbg 10 | aiohttp 11 | async_lru 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # need 'xenial' to get python 3.7 and over, otherwise travis defaults to 'trusty' which only goes to python 3.6 2 | dist: xenial 3 | language: python 4 | python: 3.9 5 | # command to install dependencies 6 | install: "pip install -r .requirement-extras/requirements-travis.txt" 7 | # command to run tests 8 | # script: sh -c 'cd src && mkdir tests/logs && ./bin/testall' 9 | script: sh -c 'mkdir src/tests/logs && ./bin/testall' 10 | 11 | # Set up notification options 12 | notifications: 13 | email: 14 | recipients: 15 | - abulka@gmail.com 16 | # change is when the repo status goes from pass to fail or vice versa 17 | on_success: change 18 | on_failure: always 19 | 20 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Current File", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${file}", 12 | "console": "integratedTerminal", 13 | "justMyCode": true 14 | }, 15 | { 16 | "name": "Python: pynsource", 17 | "type": "python", 18 | "request": "launch", 19 | "cwd": "${workspaceFolder}/src", 20 | "program": "pynsource_gui.py", 21 | "console": "integratedTerminal", 22 | "justMyCode": false 23 | }, 24 | { 25 | "name": "Python: pynsource PRO", 26 | "type": "python", 27 | "request": "launch", 28 | "cwd": "${workspaceFolder}/src", 29 | "env": { 30 | "PYTHONPATH": "${workspaceFolder}/../ogl2:${workspaceFolder}/../pynsource-rego" 31 | }, 32 | "program": "pynsource_gui.py", 33 | "console": "integratedTerminal", 34 | "justMyCode": true 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /.vscode/pynsource-multi.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "/Users/Andy/Devel/pynsource" 5 | }, 6 | { 7 | "path": "/Users/Andy/Devel/pynsource-rego" 8 | }, 9 | { 10 | "path": "/Users/Andy/Devel/ogl2" 11 | }, 12 | { 13 | "path": "/Users/Andy/Library/Preferences/PyNSource" 14 | }, 15 | { 16 | "path": "/Users/Andy/Devel/pynsource-web" 17 | } 18 | ], 19 | "settings": {} 20 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.testing.unittestArgs": [ 3 | "-v", 4 | "-s", 5 | "./src", 6 | "-p", 7 | "test_*.py" 8 | ], 9 | "python.testing.pytestEnabled": false, 10 | "python.testing.unittestEnabled": true 11 | } -------------------------------------------------------------------------------- /Admin/announcements/comp.lang.python.announce - Google Groups.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://groups.google.com/group/comp.lang.python.announce/topics 3 | -------------------------------------------------------------------------------- /Admin/announcements/pynsource yahoo group.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://tech.groups.yahoo.com/group/pynsource/ 3 | -------------------------------------------------------------------------------- /Admin/announcements/web_macpedia_2012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/announcements/web_macpedia_2012.png -------------------------------------------------------------------------------- /Admin/announcements/web_modelling_blog_2012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/announcements/web_modelling_blog_2012.png -------------------------------------------------------------------------------- /Admin/bitly-releases/requirements-bitlytool.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4 2 | beautifultable 3 | -------------------------------------------------------------------------------- /Admin/doco-uml/Documentation on PyNSource models.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/Documentation on PyNSource models.docx -------------------------------------------------------------------------------- /Admin/doco-uml/Documentation on PyNSource models.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/Documentation on PyNSource models.odt -------------------------------------------------------------------------------- /Admin/doco-uml/OGL-like UML 2015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/OGL-like UML 2015.png -------------------------------------------------------------------------------- /Admin/doco-uml/Overlap Unit Test Visual Doco.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/Overlap Unit Test Visual Doco.docx -------------------------------------------------------------------------------- /Admin/doco-uml/ParsereportgenUML1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/ParsereportgenUML1.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/UML pynsource - corelayout1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/UML pynsource - corelayout1.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/UML pynsource - pynsourcegui1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/UML pynsource - pynsourcegui1.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/UML_pynsource parse01.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/UML_pynsource parse01.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/UML_pynsourceGUI.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/UML_pynsourceGUI.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/UML_wxOGL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/UML_wxOGL.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/comment nodes - UML class-sequence-combo diagram 2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/comment nodes - UML class-sequence-combo diagram 2019.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/epydoc_pynsource_proj1.prj: -------------------------------------------------------------------------------- 1 | (dp0 2 | S'show_imports' 3 | p1 4 | I0 5 | sS'prj_name' 6 | p2 7 | S'pynsource doco' 8 | p3 9 | sS'docformat' 10 | p4 11 | S'epytext' 12 | p5 13 | sS'inheritance' 14 | p6 15 | S'grouped' 16 | p7 17 | sS'help' 18 | p8 19 | NsS'modules' 20 | p9 21 | (VF:/Documents/AndyTabletXp2/Documents and Settings/Andy/My Documents/Software Development/aa python/pyNsource/pynsource/core_parser.py 22 | p10 23 | VF:/Documents/AndyTabletXp2/Documents and Settings/Andy/My Documents/Software Development/aa python/pyNsource/pynsource/gen_asciiart.py 24 | p11 25 | VF:/Documents/AndyTabletXp2/Documents and Settings/Andy/My Documents/Software Development/aa python/pyNsource/pynsource/gen_base.py 26 | p12 27 | VF:/Documents/AndyTabletXp2/Documents and Settings/Andy/My Documents/Software Development/aa python/pyNsource/pynsource/gen_delphi.py 28 | p13 29 | tp14 30 | sS'private' 31 | p15 32 | I1 33 | sS'prj_url' 34 | p16 35 | NsS'introspect_or_parse' 36 | p17 37 | S'both' 38 | p18 39 | sS'frames' 40 | p19 41 | I1 42 | sS'css' 43 | p20 44 | S'default' 45 | p21 46 | sS'target' 47 | p22 48 | S'C:/Users/Andy/Desktop/try' 49 | p23 50 | s. -------------------------------------------------------------------------------- /Admin/doco-uml/gen_epydoc.bat: -------------------------------------------------------------------------------- 1 | python C:\Python26\Lib\site-packages\epydoc\cli.py -o c:\users\andy\desktop\try --graph umlclasstree --dotpath "\program files\graphviz2.26.3\bin\dot.exe" "F:\Documents\AndyTabletXp2\Documents and Settings\Andy\My Documents\Software Development\aa python\pyNsource\pynsource\*.py" 2 | -------------------------------------------------------------------------------- /Admin/doco-uml/gui_uml_01_sha_884410.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/gui_uml_01_sha_884410.png -------------------------------------------------------------------------------- /Admin/doco-uml/gui_uml_latest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/gui_uml_latest.png -------------------------------------------------------------------------------- /Admin/doco-uml/parse_model_uml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/parse_model_uml.png -------------------------------------------------------------------------------- /Admin/doco-uml/pynsource 1 - overview uml july 2012.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/pynsource 1 - overview uml july 2012.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/pynsource 1.eap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/pynsource 1.eap -------------------------------------------------------------------------------- /Admin/doco-uml/pynsource classentry dict 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/pynsource classentry dict 1.png -------------------------------------------------------------------------------- /Admin/doco-uml/pynsource devel notes scans.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/pynsource devel notes scans.pdf -------------------------------------------------------------------------------- /Admin/doco-uml/pynsourceUML-2015.mic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/pynsourceUML-2015.mic -------------------------------------------------------------------------------- /Admin/doco-uml/pynsourceUML-2015.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/doco-uml/pynsourceUML-2015.pdf -------------------------------------------------------------------------------- /Admin/site-andypatterns/yUml vs Ogl render 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/site-andypatterns/yUml vs Ogl render 1.png -------------------------------------------------------------------------------- /Admin/site-atug/pynsource-latest-devel.txt: -------------------------------------------------------------------------------- 1 | { 2 | "latest_version" : 1.84, 3 | "latest_announcement" : """ 4 | - fixed: more robust handling of type annotations on function and method arguments e.g. def foo(a: Optional[str]) 5 | 6 | Recent changes: 7 | - fixed: PlantUML diagram rendering due to PlantUML server changes (again) 8 | - fixed: UML Ascii Art formatting on Mac 9 | - Matrix Multiplication operator @ now parsed correctly (fixes issue 102) 10 | - Handle any type of nested string parameter annotation e.g. "A" or "A.B" or "A.B.C" etc. (fixes issue 103) 11 | - Fix missing app icon on Mac and Ubuntu builds 12 | - Ability to Export diagram to XML 13 | 14 | """, 15 | "version_syntax_format" : 1, 16 | "download_url" : "http://bit.ly/pynsource-upgrade-download" 17 | } 18 | 19 | # Versions 1.51 and higher check for this announcement file. 20 | # Commit this file to Github, Pynsource now checks GitHub repo directly 21 | # No longer checks http://www.atug.com/downloads/pynsource-latest.txt -------------------------------------------------------------------------------- /Admin/site-atug/pynsource-latest.txt: -------------------------------------------------------------------------------- 1 | { 2 | "latest_version" : 1.84, 3 | "latest_announcement" : """ 4 | - fixed: more robust handling of type annotations on function and method arguments e.g. def foo(a: Optional[str]) 5 | 6 | Recent changes: 7 | - fixed: PlantUML diagram rendering due to PlantUML server changes (again) 8 | - fixed: UML Ascii Art formatting on Mac 9 | - Matrix Multiplication operator @ now parsed correctly (fixes issue 102) 10 | - Handle any type of nested string parameter annotation e.g. "A" or "A.B" or "A.B.C" etc. (fixes issue 103) 11 | - Fix missing app icon on Mac and Ubuntu builds 12 | - Ability to Export diagram to XML 13 | 14 | """, 15 | "version_syntax_format" : 1, 16 | "download_url" : "http://bit.ly/pynsource-upgrade-download" 17 | } 18 | 19 | # Versions 1.51 and higher check for this announcement file. 20 | # Commit this file to Github, Pynsource now checks GitHub repo directly 21 | # No longer checks http://www.atug.com/downloads/pynsource-latest.txt -------------------------------------------------------------------------------- /Admin/site-sourceforge/PyNSource Home on SourceForge.net.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://sourceforge.net/projects/pyidea/ 3 | -------------------------------------------------------------------------------- /Admin/site-sourceforge/readme moved to google.markdown: -------------------------------------------------------------------------------- 1 | *Latest* Source code and latest downloads of PyNsource have now moved to [pynsource at google code](http://code.google.com/p/pynsource/) 2 | 3 | Sourceforge now hosts an old version. 4 | -------------------------------------------------------------------------------- /Admin/site-sourceforge/sfmigrate.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Admin/site-sourceforge/sfmigrate.bat -------------------------------------------------------------------------------- /Admin/site-sourceforge/sourceforge info misc.txt: -------------------------------------------------------------------------------- 1 | Check out from 2 | https://pyidea.svn.sourceforge.net/svnroot/pyidea/pynsource/trunk/ 3 | (remember the https or you won't be able to move/rename things) 4 | 5 | http://pyidea.sourceforge.net/ 6 | 7 | was original hosting page 8 | I changed to 9 | 10 | http://www.andypatterns.com/index.php/products/pynsource_-_uml_tool_for_python/ 11 | 12 | using the Project Admin settings page. 13 | 14 | You can change the default download to a particular file by clicking on the "i" details symbol 15 | and specifying any particular file as a default for a particular o/s. 16 | I made the windows default the gui exe 1.4c on march 2011 - 17 | rather than 1.4.zip which was not an exe but also was old version (not 1.4c). 18 | 19 | 20 | -------------------------------------------------------------------------------- /Admin/todo/todo.txt: -------------------------------------------------------------------------------- 1 | All issues moved to 2 | http://code.google.com/p/pynsource/issues 3 | 4 | ---- 5 | 6 | -------------------------------------------------------------------------------- /INSTALL-TIPS.md: -------------------------------------------------------------------------------- 1 | # Fedora installation tips 2 | 3 | Fedora Linux Users: can use the script `bin/install-linux-fedora-33` in conjunction with Python 3.8. There is no wxpython wheel for Python 3.9 so simply install Python 3.8 using [pyenv](https://github.com/pyenv/pyenv/wiki#suggested-build-environment) e.g. 4 | 5 | $ sudo dnf install make gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel 6 | $ curl https://pyenv.run | bash 7 | 8 | Remember to update your `.bashrc` and restart your shell. 9 | 10 | Now that `pyenv` is installed, install a version of Python 11 | 12 | $ sudo dnf install python3-devel 13 | $ PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.8.8 14 | 15 | Now that a specific version of Python is installed, activate it globally or just locally 16 | 17 | $ cd pynsource 18 | $ pyenv local 3.8.8 19 | 20 | Run the script that installs Pynsource and its dependencies 21 | 22 | $ bin/install-linux-fedora-33 23 | 24 | Finally, run Pynsource 25 | 26 | $ bin/run 27 | 28 | Alternatively run the prebuilt [Fedora Pynsource binary](https://github.com/abulka/pynsource/releases/download/version-1.77/pynsource-1.77-fedora-33.zip) from the terminal like this 29 | 30 | `./Pynsource` 31 | 32 | and it should start up ok, even though it is of a type `application/x-sharedlib`. Unfortunately double clicking on the executable from file manager in Fedora doesn't seem to work. 33 | -------------------------------------------------------------------------------- /Research/async play/report_snap_env.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | try: 3 | import wx 4 | except: 5 | print("can't import wx") 6 | else: 7 | print("import wx succeeded OK") 8 | 9 | print("sys.path") 10 | print(sys.path) 11 | print() 12 | 13 | print("\n".join(sys.path)) 14 | print() 15 | 16 | print("os.getcwd()") 17 | print(os.getcwd()) 18 | print() 19 | 20 | print("os.listdir()") 21 | print(os.listdir()) 22 | print() 23 | 24 | -------------------------------------------------------------------------------- /Research/async play/repro_wxasync_042_bug.py: -------------------------------------------------------------------------------- 1 | # shows how coroutine calls fails because of 2 | # frame is created inside app OnInit architecture. 3 | # 4 | # update - but now works cos of fix in 5 | # git+https://github.com/sirk390/wxasync.git@a2aa71eca525169f996be46a4515674028c8e6f5 6 | # 7 | # but now is broken again as of 0.42 8 | # reported https://github.com/sirk390/wxasync/issues/12 9 | # 10 | import wx 11 | import time 12 | # from wxasync import AsyncBind, WxAsyncApp, StartCoroutine 13 | # from wxasync041 import AsyncBind, WxAsyncApp, StartCoroutine # OK 14 | from wxasync042 import AsyncBind, WxAsyncApp, StartCoroutine # FAILED - but OK now if use self.frame below 15 | import asyncio 16 | from asyncio.events import get_event_loop 17 | import wx.lib.newevent 18 | 19 | SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent() 20 | 21 | class MainApp(WxAsyncApp): 22 | 23 | def OnInit(self): 24 | self.frame = wx.Frame(None, -1, "test",) 25 | self.frame.CreateStatusBar() 26 | self.frame.Show(True) 27 | StartCoroutine(self.async_callback, self.frame) # 2nd param must be self.frame not just self 28 | return True 29 | 30 | async def async_callback(self): 31 | self.frame.SetStatusText("Button clicked") 32 | await asyncio.sleep(1) 33 | self.frame.SetStatusText("Working") 34 | await asyncio.sleep(1) 35 | self.frame.SetStatusText("Completed") 36 | 37 | def main_async(): 38 | application = MainApp(0) 39 | loop = get_event_loop() 40 | loop.run_until_complete(application.MainLoop()) 41 | 42 | if __name__ == "__main__": 43 | main_async() 44 | -------------------------------------------------------------------------------- /Research/async play/requirements-linux.txt: -------------------------------------------------------------------------------- 1 | configobj 2 | requests 3 | typed_ast==1.1.1 4 | astpretty 5 | termcolor 6 | beautifultable 7 | appdirs 8 | wheel 9 | py2app 10 | click 11 | pytest 12 | coverage 13 | pytest-cov 14 | black 15 | pydbg 16 | aiohttp 17 | async_lru 18 | Pillow 19 | wxasync 20 | -------------------------------------------------------------------------------- /Research/async play/simplest_wxapp.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | class MainApp(wx.App): 4 | def OnInit(self): 5 | self.frame = wx.Frame(None, -1, "test",) 6 | self.frame.CreateStatusBar() 7 | self.frame.Show(True) 8 | return True 9 | 10 | def main(): 11 | application = MainApp(0) 12 | application.MainLoop() 13 | 14 | if __name__ == "__main__": 15 | main() 16 | -------------------------------------------------------------------------------- /Research/async play/wxasync1.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from wxasync import AsyncBind, WxAsyncApp, StartCoroutine 3 | import asyncio 4 | from asyncio.events import get_event_loop 5 | import time 6 | 7 | class TestFrame(wx.Frame): 8 | def __init__(self, parent=None): 9 | super(TestFrame, self).__init__(parent) 10 | vbox = wx.BoxSizer(wx.VERTICAL) 11 | button1 = wx.Button(self, label="Submit") 12 | self.edit = wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ST_NO_AUTORESIZE) 13 | self.edit_timer = wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ST_NO_AUTORESIZE) 14 | vbox.Add(button1, 2, wx.EXPAND|wx.ALL) 15 | vbox.AddStretchSpacer(1) 16 | vbox.Add(self.edit, 1, wx.EXPAND|wx.ALL) 17 | vbox.Add(self.edit_timer, 1, wx.EXPAND|wx.ALL) 18 | self.SetSizer(vbox) 19 | self.Layout() 20 | AsyncBind(wx.EVT_BUTTON, self.async_callback, button1) 21 | StartCoroutine(self.update_clock, self) 22 | 23 | async def async_callback(self, event): 24 | self.edit.SetLabel("Button clicked") 25 | await asyncio.sleep(1) 26 | self.edit.SetLabel("Working") 27 | await asyncio.sleep(1) 28 | self.edit.SetLabel("Completed") 29 | 30 | async def update_clock(self): 31 | while True: 32 | self.edit_timer.SetLabel(time.strftime('%H:%M:%S')) 33 | await asyncio.sleep(0.5) 34 | 35 | app = WxAsyncApp() 36 | frame = TestFrame() 37 | frame.Show() 38 | app.SetTopWindow(frame) 39 | loop = get_event_loop() 40 | loop.run_until_complete(app.MainLoop()) 41 | 42 | -------------------------------------------------------------------------------- /Research/config techniques/pynsource.ini: -------------------------------------------------------------------------------- 1 | keyword1 = 100 2 | keyword2 = hi there 3 | -------------------------------------------------------------------------------- /Research/config techniques/testConfigObj.py: -------------------------------------------------------------------------------- 1 | # import wx 2 | import os 3 | 4 | PYNSOURCE_CONFIG_FILE = "pynsource.ini" 5 | PYNSOURCE_CONFIG_DIR = "PyNSource" 6 | 7 | 8 | def InitConfig(): 9 | # config_dir = os.path.join(wx.StandardPaths.Get().GetUserConfigDir(), PYNSOURCE_CONFIG_DIR) 10 | config_dir = "." 11 | try: 12 | os.makedirs(config_dir) 13 | except OSError: 14 | pass 15 | user_config_file = os.path.join(config_dir, PYNSOURCE_CONFIG_FILE) 16 | print("Pynsource config file", user_config_file) 17 | 18 | # shelf = shelve.open(user_config_file) 19 | # shelf["users"] = ["David", "Abraham"] 20 | # shelf.sync() # Save 21 | 22 | from configobj import ConfigObj # easy_install configobj 23 | 24 | config = ConfigObj( 25 | user_config_file 26 | ) # doco at http://www.voidspace.org.uk/python/configobj.html 27 | print(config) 28 | config["keyword1"] = 100 29 | config["keyword2"] = "hi there" 30 | value1 = config["keyword1"] 31 | value2 = config["keyword2"] 32 | # config['section1']['keyword3'] = "hi there" 33 | print(config) 34 | config.write() 35 | 36 | 37 | print("hi") 38 | InitConfig() 39 | -------------------------------------------------------------------------------- /Research/hexmvc/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "/Users/Andy/.pyenv/shims/python" 3 | } -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/AppMainConfigDotnet.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | # SharpDevelop 4.2.0.8649-Beta 2 5 | Project("{FD48973F-F585-4F70-812B-4D0503B36CE9}") = "AppMainConfigDotnetWinForm", "AppMainConfigDotnetWinForm.pyproj", "{EA8D3EA0-9D40-4607-B7EE-D1DE72BEC9EE}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x86 = Debug|x86 10 | Release|x86 = Release|x86 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {EA8D3EA0-9D40-4607-B7EE-D1DE72BEC9EE}.Debug|x86.Build.0 = Debug|x86 14 | {EA8D3EA0-9D40-4607-B7EE-D1DE72BEC9EE}.Debug|x86.ActiveCfg = Debug|x86 15 | {EA8D3EA0-9D40-4607-B7EE-D1DE72BEC9EE}.Release|x86.Build.0 = Release|x86 16 | {EA8D3EA0-9D40-4607-B7EE-D1DE72BEC9EE}.Release|x86.ActiveCfg = Release|x86 17 | EndGlobalSection 18 | EndGlobal 19 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/UtilJsonDotnetAdapter.py: -------------------------------------------------------------------------------- 1 | # from System.Runtime.Serialization.Json import DataContractJsonSerializer 2 | # 3 | # Whats the proper way to use this class ? 4 | 5 | # Andy hack 6 | def JsonFromDictFunction(o): 7 | print("dotnet json.dumps") 8 | s = str(o) 9 | return s.replace("'", '"') # json require double quotes, not single 10 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/UtilRandomDotnetAdapter.py: -------------------------------------------------------------------------------- 1 | import System.Random 2 | 3 | 4 | def RandomIntFunction(n, m): 5 | print("dot net random") 6 | return System.Random().Next(m) 7 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/app_python_location_TEMPLATE.config: -------------------------------------------------------------------------------- 1 | normal_python_lib=c:\python27\lib -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/IronPython.Modules.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/IronPython.Modules.dll -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/IronPython.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/IronPython.dll -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/Microsoft.Dynamic.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/Microsoft.Dynamic.dll -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/Microsoft.Scripting.Metadata.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/Microsoft.Scripting.Metadata.dll -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/Microsoft.Scripting.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/architecture3/AppMainConfigDotnet/lib_andy_python/Microsoft.Scripting.dll -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigDotnet/run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM "C:\Program Files (x86)\SharpDevelop\4.2\AddIns\BackendBindings\PythonBinding\ipy.exe" 3 | REM set IRONPYTHONPATH=c:\Python26\Lib 4 | ipy.exe Program.py 5 | 6 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigOo.py: -------------------------------------------------------------------------------- 1 | from ModelOo import Model 2 | from ModelOoAdapter import ModelOoAdapter 3 | 4 | # from PersistenceOoPickle import Persistence 5 | from PersistenceOoHomegrown import Persistence 6 | 7 | from ServerBottleAdapter import Server 8 | 9 | # from ServerMockAdapter import Server 10 | 11 | from ViewWxAdapter import MyWxApp 12 | import wx 13 | from UtilRandomStdpythonAdapter import RandomIntFunction 14 | from UtilJsonStdpythonAdapter import JsonFromDictFunction 15 | from App import App 16 | 17 | # Create Model - Object Oriented instances in memory 18 | model_oo = Model() 19 | persistence = Persistence() 20 | model = ModelOoAdapter(model_oo, persistence) 21 | 22 | # Create Server 23 | server = Server(host="localhost", port=8081) 24 | 25 | # Create Gui 26 | wxapp = MyWxApp(redirect=False) 27 | gui = ( 28 | wxapp.myframe 29 | ) # gui mediator inherits from gui rather than wrapping it, in this implementation 30 | 31 | # Hook up Utility adapters 32 | gui.random = RandomIntFunction 33 | server.json_from_dict = JsonFromDictFunction 34 | 35 | # Create Core Hexagon App and inject adapters 36 | app = App(model, server, gui) 37 | wx.CallAfter(app.Boot) 38 | 39 | # Start Gui 40 | wxapp.MainLoop() 41 | 42 | print("DONE") 43 | 44 | # Stops any background server threads. 45 | import sys 46 | 47 | sys.exit() 48 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/AppMainConfigSql.py: -------------------------------------------------------------------------------- 1 | from ModelSqlAdapter import ModelSqlObjectAdapter 2 | 3 | from ServerBottleAdapter import Server 4 | 5 | # from ServerMockAdapter import Server 6 | 7 | from ViewWxAdapter import MyWxApp 8 | from UtilRandomStdpythonAdapter import RandomIntFunction 9 | import wx 10 | from App import App 11 | 12 | # Create Model - SqlObject 13 | model_sql = ModelSqlObjectAdapter.GetModel() 14 | model = ModelSqlObjectAdapter(model_sql) 15 | 16 | # Create Server 17 | server = Server(host="localhost", port=8081) 18 | 19 | # Create Gui 20 | wxapp = MyWxApp(redirect=False) 21 | gui = ( 22 | wxapp.myframe 23 | ) # gui mediator inherits from gui rather than wrapping it, in this implementation 24 | 25 | # Hook up Utility adapters 26 | gui.random = RandomIntFunction 27 | 28 | # Create Core Hexagon App and inject adapters 29 | app = App(model, server, gui) 30 | wx.CallAfter(app.Boot) 31 | 32 | # Start Gui 33 | wxapp.MainLoop() 34 | print("DONE") 35 | 36 | # Stops any background server threads. 37 | import sys 38 | 39 | sys.exit() 40 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/ModelOo.py: -------------------------------------------------------------------------------- 1 | # Simple (in memory) Model 2 | 3 | 4 | class Model(object): 5 | def __init__(self): 6 | self.things = [] 7 | self.next_id = 1 8 | 9 | def Clear(self): 10 | self.things = [] 11 | print("simple model cleared") 12 | 13 | def AddThing(self, info, id=None): 14 | thing = Thing(info) 15 | thing.model = self # backpointer 16 | if not id: 17 | id = self.next_id 18 | self.next_id += 1 19 | thing.id = id 20 | self.things.append(thing) 21 | return thing 22 | 23 | @property 24 | def size(self): 25 | return len(self.things) 26 | 27 | 28 | class Thing: 29 | def __init__(self, info): 30 | self.model = None # backpointer 31 | self.info = info 32 | self.id = None 33 | 34 | def __str__(self): 35 | return "Thing %d - %s" % (self.id, self.info) 36 | 37 | def to_dict(self): 38 | return {"id": self.id, "info": self.info} 39 | 40 | def AddInfo(self, msg): 41 | self.info += " " + msg 42 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/ModelOoAdapter.py: -------------------------------------------------------------------------------- 1 | from ModelAdapterBase import ModelAdapterBase 2 | 3 | 4 | class ModelOoAdapter(ModelAdapterBase): 5 | def __init__(self, model, persistence): 6 | ModelAdapterBase.__init__(self, model) 7 | self.persistence = persistence 8 | 9 | def DeleteThing(self, thing): 10 | self.model.things.remove(thing) 11 | self.observers.MODEL_THING_DELETED(thing) 12 | 13 | def LoadAll(self, filename=None): 14 | self.model = self.persistence.LoadAll(self.model, filename) 15 | 16 | self.observers.MODEL_STATUS_LOAD_OR_SAVE_ALL("Load All", True) 17 | self.observers.MODEL_CHANGED(self.model.things) 18 | 19 | def SaveAll(self, filename=None): 20 | self.persistence.SaveAll(self.model, filename) 21 | 22 | self.observers.MODEL_STATUS_LOAD_OR_SAVE_ALL("Save All", True) 23 | 24 | def FindThing(self, id): 25 | assert type(id) is int 26 | for thing in self.model.things: 27 | if thing.id == id: 28 | return thing 29 | return None 30 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/ModelSql.py: -------------------------------------------------------------------------------- 1 | # SqlObject Model 2 | 3 | from sqlobject import * 4 | 5 | 6 | class Model(SQLObject): 7 | things = MultipleJoin("Thing") 8 | 9 | @property 10 | def size(self): 11 | return len(self.things) 12 | 13 | def Clear(self): 14 | for thing in self.things: 15 | Thing.delete(thing.id) 16 | 17 | def AddThing(self, info): 18 | thing = Thing(info=info, model=self) 19 | return thing 20 | 21 | 22 | class Thing(SQLObject): 23 | info = StringCol(length=50) 24 | model = ForeignKey("Model", default=None) 25 | 26 | def __str__(self): 27 | return "Thing %d - %s" % (self.id, self.info) 28 | 29 | def to_dict(self): 30 | return {"id": self.id, "info": self.info} 31 | 32 | def AddInfo(self, msg): 33 | self.info += " " + msg 34 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/ModelSqlAdapter.py: -------------------------------------------------------------------------------- 1 | from ModelSql import Model, Thing 2 | from ModelAdapterBase import ModelAdapterBase 3 | 4 | from sqlobject.sqlite import builder 5 | from sqlobject import sqlhub 6 | 7 | 8 | class ModelSqlObjectAdapter(ModelAdapterBase): 9 | def DeleteThing(self, thing): 10 | Thing.delete(thing.id) 11 | self.observers.MODEL_THING_DELETED(thing) 12 | 13 | @classmethod 14 | def GetModel(self): 15 | SQLiteConnection = builder() 16 | conn = SQLiteConnection("hexmodel_sqlobject.db", debug=False) 17 | sqlhub.processConnection = conn 18 | try: 19 | model = Model.get(1) 20 | # a_thing = Thing.get(1) 21 | except: 22 | print("Oops - possibly no database - creating one now...") 23 | Model.dropTable(True) 24 | Model.createTable() 25 | Thing.dropTable(True) 26 | Thing.createTable() 27 | 28 | the_model = Model() 29 | assert the_model == Model.get(1) 30 | # ~ thing1 = Thing(info="mary", model=model) 31 | # ~ thing2 = Thing(info="fred", model=model) 32 | 33 | model = Model.get(1) 34 | 35 | return model 36 | 37 | # Sql we are always persistent - unless perhaps if we set up transactions 38 | 39 | def LoadAll(self, filename=None): 40 | pass 41 | 42 | def SaveAll(self, filename=None): 43 | pass 44 | 45 | def FindThing(self, id): 46 | assert type(id) is int 47 | thing = Thing.get(id) # nice and fast sql lookup 48 | return thing 49 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/PersistenceOoHomegrown.py: -------------------------------------------------------------------------------- 1 | # Home grown - needs to know about model's innards 2 | 3 | from ModelOo import Model, Thing 4 | 5 | DEFAULT_FILENAME = "hexmodel_homegrown.db.txt" 6 | 7 | 8 | class Persistence: 9 | def LoadAll(self, model, filename): 10 | if not filename: 11 | filename = DEFAULT_FILENAME 12 | output = open(filename, "r") 13 | 14 | # Could also just create a new model e.g. 15 | # model = Model() 16 | # since we return a model object 17 | # (whether its totally new or just the old existing one repopulated) 18 | # and the layer above resets the app to use whatever we return here. 19 | model.Clear() 20 | 21 | # read model container, with all important next id allocator 22 | label, id = output.readline().strip().split("=") 23 | model.next_id = int(id) 24 | 25 | for line in output.readlines(): 26 | id, info = line.strip().split(",") 27 | model.AddThing(info, int(id)) 28 | output.close() 29 | 30 | return model 31 | 32 | def SaveAll(self, model, filename): 33 | if not filename: 34 | filename = DEFAULT_FILENAME 35 | output = open(filename, "w") 36 | 37 | # persist model container, with all important id allocator 38 | output.write("model.next_id=%s\n" % model.next_id) 39 | 40 | for thing in model.things: 41 | output.write("%s,%s\n" % (thing.id, thing.info)) 42 | output.close() 43 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/PersistenceOoPickle.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | 3 | # Safer if Persistence doesn't permanently have a ref to the model since the 4 | # model changes when loaded fresh, so hanging on to an old model would be bad. 5 | # We could safely update Persistence class's reference to self.model in our 6 | # LoadAll() but perhaps that would be presumptious since we don't really know 7 | # how the model is being managed and referred to. 8 | 9 | # This particular pickle persistence technique is oblivious of the 10 | # innards of the model. 11 | 12 | DEFAULT_FILENAME = "hexmodel_sqlobject.pickle" 13 | 14 | 15 | class Persistence: 16 | def LoadAll(self, model, filename): 17 | if not filename: 18 | filename = DEFAULT_FILENAME 19 | # ignore existing model paramter since pickle creates a new one. 20 | output = open(filename, "r") 21 | model = pickle.load(output) 22 | output.close() 23 | return model 24 | 25 | def SaveAll(self, model, filename): 26 | if not filename: 27 | filename = DEFAULT_FILENAME 28 | output = open(filename, "w") 29 | pickle.dump(model, output, protocol=0) 30 | output.close() 31 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/ServerMockAdapter.py: -------------------------------------------------------------------------------- 1 | from architecture_support import * 2 | 3 | 4 | class Server(object): 5 | def __init__(self, host, port): 6 | self.host = host 7 | self.port = port 8 | 9 | self.app = None # inject 10 | self.model = None # inject 11 | self.thread_id = None 12 | self.observers = multicast() 13 | 14 | @property 15 | def url_server(self): 16 | return "http://%s:%s" % (self.host, self.port) 17 | 18 | def StartServer(self): 19 | print("Mock server started") 20 | 21 | def StopServer(self): 22 | print("Stopped Mock server") 23 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/UtilJsonStdpythonAdapter.py: -------------------------------------------------------------------------------- 1 | import simplejson as json # easy_install simplejson 2 | 3 | 4 | def JsonFromDictFunction(o): 5 | print("python json.dumps") 6 | return json.dumps(o) 7 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/UtilRandomStdpythonAdapter.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def RandomIntFunction(n, m): 5 | print("python random") 6 | return random.randint(n, m) 7 | -------------------------------------------------------------------------------- /Research/hexmvc/architecture3/arch3.eap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/architecture3/arch3.eap -------------------------------------------------------------------------------- /Research/hexmvc/bottle tests/bottle1.py: -------------------------------------------------------------------------------- 1 | from bottle import debug, route, run, request 2 | 3 | 4 | @route("/:name") 5 | def index(name="World"): 6 | return "Helloooo %s!!" % name 7 | 8 | 9 | debug(True) 10 | run( 11 | host="localhost", port=5000 12 | ) # reloader=True behaves strangely, restarts the server when there is a 13 | # web request, even though its killed! Also, source is not reparsed, so whats the point. 14 | # might be a windows thing. 15 | -------------------------------------------------------------------------------- /Research/hexmvc/bottle tests/flask1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from flask import Flask 4 | 5 | app = Flask(__name__) 6 | 7 | 8 | @app.route("/") 9 | def hello(): 10 | return "Hello World!@!!! ok" 11 | 12 | 13 | if __name__ == "__main__": 14 | app.run() 15 | -------------------------------------------------------------------------------- /Research/hexmvc/grand unified/listing1.py: -------------------------------------------------------------------------------- 1 | import requests # Listing 1 2 | from urllib.parse import urlencode 3 | 4 | def find_definition(word): 5 | q = 'define ' + word 6 | url = 'http://api.duckduckgo.com/?' 7 | url += urlencode({'q': q, 'format': 'json'}) 8 | print(url) 9 | response = requests.get(url) # I/O 10 | print(response.status_code) 11 | data = response.json() # I/O 12 | print(data) 13 | definition = data['Definition'] 14 | if definition == '': 15 | raise ValueError('that is not a word') 16 | return definition 17 | 18 | find_definition("cat") 19 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/hexagon3/favicon.ico -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/hexagon1.py: -------------------------------------------------------------------------------- 1 | # BOOT WIRING 2 | 3 | from hexappmodel import App, Thing 4 | from hexpersistence import PersistenceMock, PersistenceMock2 5 | 6 | # app = App(PersistenceMock()) 7 | app = App(PersistenceMock2()) 8 | 9 | # UNIT TEST 10 | 11 | app.Load() 12 | print(app.model) 13 | 14 | thing1 = app.GetThing(0) 15 | app.AddInfoToThing(thing1, "once") 16 | print(app.model) 17 | 18 | app.New() 19 | app.CreateThing("once") 20 | app.CreateThing("upon a time") 21 | app.Save() 22 | print(app.model) 23 | 24 | app.New() 25 | print(app.model) 26 | 27 | app.Load() 28 | print(app.model) 29 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/hexagon2.py: -------------------------------------------------------------------------------- 1 | # HEXMVC BOOT WIRING v2 - assumes app and model in the same import module 2 | 3 | from hexappmodel import App 4 | from hexpersistence import PersistenceMock2 5 | from hexserver import Server1 6 | from hexmvcgui import MyWxApp 7 | import wx 8 | 9 | # Create Gui 10 | wxapp = MyWxApp(redirect=False) 11 | gui = wxapp.myframe # arguably too wx based to be a true adapter, but as long 12 | # as we call nothing wx specific, it acts as an adapter ok. 13 | # Create Server 14 | server = Server1(host="localhost", port=8081) 15 | 16 | # Create Persistence 17 | persistence = PersistenceMock2() 18 | 19 | # Create Core Hexagon App and inject adapters 20 | app = App(persistence, server, gui) 21 | wx.CallAfter(app.Boot) 22 | 23 | # Start Gui 24 | wxapp.MainLoop() 25 | 26 | print("DONE") 27 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/hexmodel_simple.py: -------------------------------------------------------------------------------- 1 | class Model: 2 | def __init__(self, persistence): 3 | self.persistence = persistence 4 | self.things = [] 5 | self.Clear() 6 | 7 | def __str__(self): 8 | return str([str(t) for t in self.things]) 9 | 10 | def __len__(self): 11 | return len(self.things) 12 | 13 | def SetApp(self, app): 14 | self.app = app 15 | 16 | def Clear(self): 17 | self.things = [] 18 | 19 | def LoadAll(self): 20 | self.things = self.persistence.LoadAll() 21 | 22 | def SaveAll(self): 23 | self.persistence.SaveAll(self.things) 24 | 25 | def CreateThing(self, info): 26 | return Thing(info) 27 | 28 | def DeleteThing(self, thing): 29 | self.things.remove(thing) 30 | 31 | 32 | class Thing: 33 | def __init__(self, info): 34 | self.info = info 35 | 36 | def __str__(self): 37 | return "A-" + self.info 38 | 39 | def AddInfo(self, msg): 40 | self.info += " " + msg 41 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/hexpersistence.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from hexappmodel import Thing 4 | 5 | 6 | class PersistenceMock: 7 | def Save(self, model): 8 | pass 9 | 10 | def Load(self): 11 | pass 12 | 13 | 14 | class PersistenceMock2: 15 | def __init__(self): 16 | self.savedmodel = [Thing("100"), Thing("101")] 17 | 18 | def SetApp(self, app): 19 | self.app = app 20 | 21 | def SaveAll(self, model): 22 | self.savedmodel = model 23 | 24 | def LoadAll(self): 25 | return self.savedmodel 26 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/junk.py: -------------------------------------------------------------------------------- 1 | print(6) 2 | input("Press Enter to continue...") 3 | print(7) 4 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/scraps.py: -------------------------------------------------------------------------------- 1 | class Controller: 2 | def __init__(self, app): 3 | self.app = app 4 | 5 | def Execute(self): 6 | pass 7 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/scrapswx.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ########################################################################### 4 | ## Python code generated with wxFormBuilder (version Mar 22 2011) 5 | ## http://www.wxformbuilder.org/ 6 | ## 7 | ## PLEASE DO "NOT" EDIT THIS FILE! 8 | ########################################################################### 9 | 10 | import wx 11 | 12 | ########################################################################### 13 | ## Class MyFrame2 14 | ########################################################################### 15 | 16 | 17 | class MyFrame2(wx.Frame): 18 | def __init__(self, parent): 19 | wx.Frame.__init__( 20 | self, 21 | parent, 22 | id=wx.ID_ANY, 23 | title=wx.EmptyString, 24 | pos=wx.DefaultPosition, 25 | size=wx.Size(500, 300), 26 | style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, 27 | ) 28 | 29 | self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 30 | 31 | bSizer6 = wx.BoxSizer(wx.VERTICAL) 32 | 33 | self.m_hyperlink2 = wx.HyperlinkCtrl( 34 | self, 35 | wx.ID_ANY, 36 | "wxFB Website", 37 | "http://www.wxformbuilder.org", 38 | wx.DefaultPosition, 39 | wx.DefaultSize, 40 | wx.HL_DEFAULT_STYLE, 41 | ) 42 | bSizer6.Add(self.m_hyperlink2, 0, wx.ALL, 5) 43 | 44 | self.SetSizer(bSizer6) 45 | self.Layout() 46 | 47 | self.Centre(wx.BOTH) 48 | 49 | def __del__(self): 50 | pass 51 | -------------------------------------------------------------------------------- /Research/hexmvc/hexagon3/views/hello_template.tpl: -------------------------------------------------------------------------------- 1 | %if name == 'World': 2 |

Hello {{name}}!

3 |

This is a test.

4 | %else: 5 |

Hello {{name.title()}}!

6 |

How are you?

-------------------------------------------------------------------------------- /Research/hexmvc/orm copycat test/copycat1.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | 4 | class WikiPage: 5 | def __init__(self, id, content): 6 | self.id = id 7 | self.content = content 8 | self.history = [] 9 | self.last_modify = datetime.datetime.now() 10 | 11 | 12 | class Wiki: 13 | def __init__(self): 14 | self.pages = {} 15 | 16 | def create_page(self, page_id, content): 17 | page = None 18 | if page_id in self.pages: 19 | page = self.pages[page_id] 20 | if not page: 21 | page = WikiPage(page_id, content) 22 | self.pages[page_id] = page 23 | return page 24 | 25 | 26 | from copycat import init_system 27 | 28 | wiki = init_system(Wiki(), "./files") 29 | # wiki.create_page('My First Page', 'My First Page Content') 30 | page = wiki.pages["My First Page"] 31 | print(page) 32 | -------------------------------------------------------------------------------- /Research/hexmvc/orm copycat test/files/snapshot_000000000000002.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/orm copycat test/files/snapshot_000000000000002.dat -------------------------------------------------------------------------------- /Research/hexmvc/orm copycat test/files/transaction_000000000000003.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/orm copycat test/files/transaction_000000000000003.log -------------------------------------------------------------------------------- /Research/hexmvc/orm sqlobject test/Download SQLObject.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://sqlobject.org/download.html 3 | -------------------------------------------------------------------------------- /Research/hexmvc/orm sqlobject test/andyormtest1.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/hexmvc/orm sqlobject test/andyormtest1.db -------------------------------------------------------------------------------- /Research/joint/joint2019/umlcd.css: -------------------------------------------------------------------------------- 1 | .joint-type-uml-composition .marker-target { 2 | fill: #4a4e69; 3 | stroke: #4a4e69; 4 | } 5 | -------------------------------------------------------------------------------- /Research/joint/old_0.4/joint_andy1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph b2 vs d42.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'B1', 'x':117, 'y':217, 'width':56, 'height':106} 2 | {'type':'node', 'id':'B2', 'x':398, 'y':304, 'width':64, 'height':132} 3 | {'type':'node', 'id':'A', 'x':117, 'y':327, 'width':206, 'height':136} 4 | {'type':'node', 'id':'m1', 'x':201, 'y':262, 'width':62, 'height':60} 5 | {'type':'node', 'id':'D42', 'x':268, 'y':208, 'width':54, 'height':114} 6 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph for unit tests 1.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'D25', 'x':7, 'y':6, 'width':159, 'height':106} 2 | {'type':'node', 'id':'D13', 'x':6, 'y':119, 'width':119, 'height':73} 3 | {'type':'node', 'id':'m1', 'x':171, 'y':9, 'width':139, 'height':92} 4 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph line overlap 1.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':13, 'y':12, 'width':84, 'height':126} 2 | {'type':'node', 'id':'B', 'x':122, 'y':11, 'width':157, 'height':79} 3 | {'type':'node', 'id':'C', 'x':8, 'y':292, 'width':194, 'height':91} 4 | {'type':'node', 'id':'m1', 'x':102, 'y':95, 'width':123, 'height':144} 5 | {'type':'edge', 'id':'A_to_B', 'source':'A', 'target':'B'} 6 | {'type':'edge', 'id':'A_to_C', 'source':'A', 'target':'C'} 7 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph line overlap little 1.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':13, 'y':12, 'width':84, 'height':126} 2 | {'type':'node', 'id':'B', 'x':122, 'y':11, 'width':157, 'height':79} 3 | {'type':'node', 'id':'C', 'x':81, 'y':270, 'width':288, 'height':91} 4 | {'type':'node', 'id':'m1', 'x':374, 'y':242, 'width':28, 'height':66} 5 | {'type':'edge', 'id':'A_to_B', 'source':'A', 'target':'B'} 6 | {'type':'edge', 'id':'A_to_C', 'source':'A', 'target':'C'} 7 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph line overlap little 2.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':3, 'y':12, 'width':84, 'height':126} 2 | {'type':'node', 'id':'B', 'x':167, 'y':11, 'width':157, 'height':79} 3 | {'type':'node', 'id':'C', 'x':21, 'y':228, 'width':288, 'height':91} 4 | {'type':'node', 'id':'m1', 'x':192, 'y':117, 'width':56, 'height':66} 5 | {'type':'edge', 'id':'A_to_B', 'source':'A', 'target':'B'} 6 | {'type':'edge', 'id':'A_to_C', 'source':'A', 'target':'C'} 7 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph line overlap little 2a.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':115, 'y':270, 'width':250, 'height':250} 2 | {'type':'node', 'id':'c', 'x':370, 'y':220, 'width':60, 'height':60} 3 | {'type':'node', 'id':'c3', 'x':376, 'y':337, 'width':60, 'height':60} 4 | {'type':'node', 'id':'c5', 'x':75, 'y':135, 'width':60, 'height':120} 5 | {'type':'edge', 'id':'c_to_c3', 'source':'c', 'target':'c3'} 6 | {'type':'edge', 'id':'c_to_c5', 'source':'c', 'target':'c5'} 7 | {'type':'edge', 'id':'A_to_c', 'source':'A', 'target':'c'} 8 | {'type':'edge', 'id':'A_to_c5', 'source':'A', 'target':'c5'} 9 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph line overlap little 2b.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':115, 'y':290, 'width':250, 'height':250} 2 | {'type':'node', 'id':'c', 'x':370, 'y':240, 'width':60, 'height':60} 3 | {'type':'node', 'id':'c5', 'x':60, 'y':135, 'width':60, 'height':120} 4 | {'type':'edge', 'id':'c_to_c5', 'source':'c', 'target':'c5'} 5 | {'type':'edge', 'id':'A_to_c', 'source':'A', 'target':'c'} 6 | {'type':'edge', 'id':'A_to_c5', 'source':'A', 'target':'c5'} 7 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph line overlap little 2c.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':125, 'y':285, 'width':250, 'height':250} 2 | {'type':'node', 'id':'c', 'x':205, 'y':165, 'width':60, 'height':60} 3 | {'type':'node', 'id':'c5', 'x':330, 'y':145, 'width':60, 'height':120} 4 | {'type':'edge', 'id':'c_to_c5', 'source':'c', 'target':'c5'} 5 | {'type':'edge', 'id':'A_to_c', 'source':'A', 'target':'c'} 6 | {'type':'edge', 'id':'A_to_c5', 'source':'A', 'target':'c5'} 7 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph snug up.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'B1', 'x':17, 'y':17, 'width':56, 'height':106} 2 | {'type':'node', 'id':'B2', 'x':164, 'y':9, 'width':52, 'height':112} 3 | {'type':'node', 'id':'A', 'x':17, 'y':127, 'width':206, 'height':136} 4 | {'type':'node', 'id':'m1', 'x':84, 'y':40, 'width':62, 'height':60} 5 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph tangle2 simple.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':145, 'y':10, 'width':90, 'height':102} 2 | {'type':'node', 'id':'c', 'x':10, 'y':115, 'width':60, 'height':60} 3 | {'type':'node', 'id':'D86', 'x':194, 'y':256, 'width':73, 'height':86} 4 | {'type':'node', 'id':'D35', 'x':271, 'y':106, 'width':79, 'height':126} 5 | {'type':'edge', 'id':'A_to_c', 'source':'A', 'target':'c'} 6 | {'type':'edge', 'id':'A_to_D86', 'source':'A', 'target':'D86'} 7 | {'type':'edge', 'id':'A_to_D35', 'source':'A', 'target':'D35'} 8 | {'type':'edge', 'id':'D86_to_D35', 'source':'D86', 'target':'D35'} 9 | {'type':'edge', 'id':'D35_to_c', 'source':'D35', 'target':'c'} 10 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph weight1.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':21, 'y':21, 'width':108, 'height':68} 2 | {'type':'node', 'id':'B', 'x':84, 'y':105, 'width':102, 'height':81} 3 | {'type':'node', 'id':'C', 'x':26, 'y':204, 'width':89, 'height':72} 4 | {'type':'edge', 'id':'A_to_B', 'source':'A', 'target':'B', 'weight':30} 5 | {'type':'edge', 'id':'B_to_C', 'source':'B', 'target':'C', 'weight':1} 6 | {'type':'edge', 'id':'C_to_A', 'source':'C', 'target':'A', 'weight':1} -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph weight2.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'A', 'x':29, 'y':10, 'width':108, 'height':68} 2 | {'type':'node', 'id':'B', 'x':10, 'y':88, 'width':178, 'height':500} 3 | {'type':'node', 'id':'C', 'x':193, 'y':83, 'width':136, 'height':318} 4 | {'type':'edge', 'id':'A_to_B', 'source':'A', 'target':'B', 'weight':100} 5 | {'type':'edge', 'id':'B_to_C', 'source':'B', 'target':'C', 'weight':1} 6 | {'type':'edge', 'id':'C_to_A', 'source':'C', 'target':'A', 'weight':1} 7 | -------------------------------------------------------------------------------- /Research/layout force spring/Test Graphs/graph2.txt: -------------------------------------------------------------------------------- 1 | {'type':'node', 'id':'B', 'x':50, 'y':185, 'width':60, 'height':60} 2 | {'type':'node', 'id':'B1', 'x':160, 'y':25, 'width':160, 'height':60} 3 | {'type':'node', 'id':'c2', 'x':30, 'y':26, 'width':88, 'height':90} 4 | {'type':'node', 'id':'c3', 'x':140, 'y':225, 'width':60, 'height':130} 5 | {'type':'edge', 'id':'B_to_c2', 'source':'B', 'target':'c2'} 6 | -------------------------------------------------------------------------------- /Research/layout force spring/somepythonbug1.py: -------------------------------------------------------------------------------- 1 | class SomePythonBug: 2 | def Do(self, param=[]): 3 | assert param == [], param 4 | param.append(1) # appending to or extending an optional parameter affects it for next time! 5 | 6 | 7 | b = SomePythonBug() 8 | 9 | # Triggers the bug 10 | b.Do() 11 | b.Do() 12 | 13 | # Avoids the bug by forcing param to be [] 14 | b.Do() 15 | b.Do(param=[]) 16 | 17 | print("Done") 18 | -------------------------------------------------------------------------------- /Research/layout force spring/test1.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/layout force spring/test1.sqlite3 -------------------------------------------------------------------------------- /Research/misc information and doco/Coordinate System Used in PynSource Gui.txt: -------------------------------------------------------------------------------- 1 | Coordinate System Used in PynSource Gui 2 | --------------------------------------- 3 | 4 | (200,200) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | (1000,1500) 13 | -------------------------------------------------------------------------------- /Research/misc information and doco/PyNSource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/misc information and doco/PyNSource.png -------------------------------------------------------------------------------- /Research/misc information and doco/Website - parseme java source for pic generation/Blah.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.atug.com/andypatterns/pynsource.htm 2 | 3 | public class Blah { 4 | public void __init__() { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Research/misc information and doco/Website - parseme java source for pic generation/ParseMeTest.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.atug.com/andypatterns/pynsource.htm 2 | public class ParseMeTest { 3 | public variant a; 4 | public Blah b = new Blah(); 5 | public static variant d; 6 | public variant e; 7 | public Blah f = new Blah(); 8 | public void __init__() { 9 | } 10 | public void IsInBattle() { 11 | } 12 | public void DoA() { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Research/misc information and doco/Website - parseme java source for pic generation/ParseMeTest2.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.atug.com/andypatterns/pynsource.htm 2 | public class ParseMeTest2 extends ParseMeTest { 3 | public variant _secretinfo; 4 | public void DoB() { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Research/misc information and doco/Website - parseme java source for pic generation/variant.java: -------------------------------------------------------------------------------- 1 | public class variant { 2 | } -------------------------------------------------------------------------------- /Research/misc information and doco/project names.txt: -------------------------------------------------------------------------------- 1 | pyDeCode 2 | pyNsource ;-) 3 | pySource 4 | pySauce 5 | pyDestructure 6 | pyStructure 7 | pySkeleton 8 | pyBones 9 | pyReverseThatActuallyWorks 10 | 11 | 12 | others from Mark... 13 | 14 | pyBase 15 | pyArchitect 16 | pyAuthor 17 | pyBuilder ! 18 | pyConstructor 19 | pyDesigner 20 | pyFather 21 | pyGenerator 22 | pyMaker 23 | pyInspiration 24 | pyBuild 25 | -------------------------------------------------------------------------------- /Research/misc information and doco/pyNSourceUML_example01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/misc information and doco/pyNSourceUML_example01.gif -------------------------------------------------------------------------------- /Research/misc information and doco/pyNsourceGuiReversingItself01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/misc information and doco/pyNsourceGuiReversingItself01.gif -------------------------------------------------------------------------------- /Research/misc information and doco/pynsource gui doodlings on coord systems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/misc information and doco/pynsource gui doodlings on coord systems.pdf -------------------------------------------------------------------------------- /Research/misc information and doco/xmi spec - 03-05-02.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/misc information and doco/xmi spec - 03-05-02.pdf -------------------------------------------------------------------------------- /Research/misc/IAN Online Conceptual Diagram Creator.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://ian.umces.edu/diagrammer/editor/svg-editor.html 3 | -------------------------------------------------------------------------------- /Research/misc/graph layout pictures.mic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/misc/graph layout pictures.mic -------------------------------------------------------------------------------- /Research/networkx graphs/WCC.pgn.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/networkx graphs/WCC.pgn.bz2 -------------------------------------------------------------------------------- /Research/networkx graphs/chess_masters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/networkx graphs/chess_masters.png -------------------------------------------------------------------------------- /Research/networkx graphs/edgelist.utf-8: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #heavy_metal_umlaut.py 3 | # GMT Sat Mar 05 00:49:31 2011 4 | # 5 | Blue Öyster Cult 2 6 | Mötley Crüe {} 7 | Deathtöngue {} 8 | Motörhead 3 9 | Deathtöngue {} 10 | Spın̈al Tap {} 11 | Hüsker Dü {} 12 | Hüsker Dü 0 13 | Mötley Crüe 1 14 | Spın̈al Tap {} 15 | Spın̈al Tap 2 16 | Queensrÿche {} 17 | Deathtöngue {} 18 | Deathtöngue 0 19 | Queensrÿche 0 20 | -------------------------------------------------------------------------------- /Research/networkx graphs/weighted_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/networkx graphs/weighted_graph.png -------------------------------------------------------------------------------- /Research/networkx graphs/weighted_graph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | An example using Graph as a weighted network. 4 | """ 5 | __author__ = """Aric Hagberg (hagberg@lanl.gov)""" 6 | try: 7 | import matplotlib.pyplot as plt 8 | except: 9 | raise 10 | 11 | import networkx as nx 12 | 13 | G = nx.Graph() 14 | 15 | G.add_edge("a", "b", weight=0.6) 16 | G.add_edge("a", "c", weight=0.2) 17 | G.add_edge("c", "d", weight=0.1) 18 | G.add_edge("c", "e", weight=0.7) 19 | G.add_edge("c", "f", weight=0.9) 20 | G.add_edge("a", "d", weight=0.3) 21 | 22 | elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] > 0.5] 23 | esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] <= 0.5] 24 | 25 | pos = nx.spring_layout(G) # positions for all nodes 26 | 27 | # nodes 28 | nx.draw_networkx_nodes(G, pos, node_size=700) 29 | 30 | # edges 31 | nx.draw_networkx_edges(G, pos, edgelist=elarge, width=6) 32 | nx.draw_networkx_edges(G, pos, edgelist=esmall, width=6, alpha=0.5, edge_color="b", style="dashed") 33 | 34 | # labels 35 | nx.draw_networkx_labels(G, pos, font_size=20, font_family="sans-serif") 36 | 37 | plt.axis("off") 38 | plt.savefig("weighted_graph.png") # save as png 39 | plt.show() # display 40 | -------------------------------------------------------------------------------- /Research/ogl tests 01/img_uml01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/ogl tests 01/img_uml01.png -------------------------------------------------------------------------------- /Research/ogl tests 01/ogl_simple1.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import wx.lib.ogl as ogl 3 | 4 | 5 | class AppFrame(wx.Frame): 6 | def __init__(self): 7 | wx.Frame.__init__(self, None, -1, "Demo", size=(300, 200), style=wx.DEFAULT_FRAME_STYLE) 8 | sizer = wx.BoxSizer(wx.VERTICAL) 9 | # put stuff into sizer 10 | 11 | canvas = ogl.ShapeCanvas(self) 12 | sizer.Add(canvas, 1, wx.GROW) 13 | 14 | canvas.SetBackgroundColour("LIGHT BLUE") # 15 | 16 | diagram = ogl.Diagram() 17 | canvas.SetDiagram(diagram) 18 | diagram.SetCanvas(canvas) 19 | 20 | shape = ogl.CircleShape(20.0) # 21 | shape.SetX(25.0) # 22 | shape.SetY(25.0) # 23 | canvas.AddShape(shape) # 24 | diagram.ShowAll(1) # 25 | 26 | # apply sizer 27 | self.SetSizer(sizer) 28 | self.SetAutoLayout(1) 29 | self.Show(1) 30 | 31 | # test TextEntryDialog 32 | dlg = wx.TextEntryDialog( 33 | self, "What is your favorite programming language?", "Eh??", "Python" 34 | ) 35 | dlg.SetValue("Python is the best!") 36 | if dlg.ShowModal() == wx.ID_OK: 37 | print(("You entered: %s\n" % dlg.GetValue())) 38 | 39 | dlg.Destroy() 40 | 41 | 42 | app = wx.PySimpleApp() 43 | ogl.OGLInitialize() 44 | frame = AppFrame() 45 | app.MainLoop() 46 | app.Destroy() 47 | -------------------------------------------------------------------------------- /Research/ogl tests 01/ogl_simple2.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import wx.lib.ogl as ogl 3 | 4 | 5 | class AppFrame(wx.Frame): 6 | def __init__(self): 7 | wx.Frame.__init__(self, None, -1, "Demo", size=(300, 200), style=wx.DEFAULT_FRAME_STYLE) 8 | sizer = wx.BoxSizer(wx.VERTICAL) 9 | # put stuff into sizer 10 | 11 | canvas = ogl.ShapeCanvas(self) 12 | sizer.Add(canvas, 1, wx.GROW) 13 | 14 | canvas.SetBackgroundColour("LIGHT BLUE") # 15 | 16 | diagram = ogl.Diagram() 17 | canvas.SetDiagram(diagram) 18 | diagram.SetCanvas(canvas) 19 | 20 | shape = ogl.RectangleShape(60, 60) 21 | shape.SetX(30) 22 | shape.SetY(30) 23 | print(shape.GetBoundingBoxMax()) 24 | canvas.AddShape(shape) 25 | 26 | shape = ogl.RectangleShape(60, 60) 27 | shape.SetX(90) 28 | shape.SetY(30) 29 | canvas.AddShape(shape) 30 | 31 | shape = ogl.RectangleShape(60, 60) 32 | shape.SetX(150) 33 | shape.SetY(30) 34 | canvas.AddShape(shape) 35 | 36 | diagram.ShowAll(1) 37 | 38 | # apply sizer 39 | self.SetSizer(sizer) 40 | self.SetAutoLayout(1) 41 | self.Show(1) 42 | 43 | 44 | app = wx.PySimpleApp() 45 | ogl.OGLInitialize() 46 | frame = AppFrame() 47 | app.MainLoop() 48 | app.Destroy() 49 | -------------------------------------------------------------------------------- /Research/overlap_removal_server/client_example/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "vis-network": { 6 | "version": "8.3.2", 7 | "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-8.3.2.tgz", 8 | "integrity": "sha512-vJDctP2gZzZbpgpB+MJxNudsqRGdkRablwdLOWd6yZKZQuEBZltOJSBaSCsyQVMD1gY8mjuYhNRoIcy7g+PDvQ==" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Research/overlap_removal_server/client_example/settings.js: -------------------------------------------------------------------------------- 1 | let enablePhysicsDuringDrag = true 2 | let drawCartesianGrid = false 3 | let emitGeogebraPositions = false // paste into https://www.geogebra.org/calculator 4 | let debugPayloads = false 5 | 6 | function to_node_centrexy(node) { 7 | // visjs moves a node to x,y to the centrepoint - not the left, top - so convert 8 | let x = node.left + node.width / 2 9 | let y = node.top + node.height / 2 10 | return [x, y] 11 | } -------------------------------------------------------------------------------- /Research/overlap_removal_server/misc/flask_play.py: -------------------------------------------------------------------------------- 1 | import flask 2 | 3 | app = flask.Flask(__name__) 4 | app.config["DEBUG"] = True 5 | 6 | 7 | @app.route('/', methods=['GET']) 8 | def home(): 9 | return "

Distant Reading Archive

This site ANDY is a prototype API for distant reading of science fiction novels.

" 10 | 11 | app.run() 12 | -------------------------------------------------------------------------------- /Research/overlap_removal_server/misc/payload1.js: -------------------------------------------------------------------------------- 1 | /* 2 | how to represent 3 | a = GraphNode("A", 0, 0, 250, 250) 4 | a1 = GraphNode("A1", 0, 0) 5 | a2 = GraphNode("A2", 0, 0) 6 | g.AddEdge(a, a1) 7 | g.AddEdge(a, a2) 8 | as a data structure - well let's convert it to JSON 9 | */ 10 | 11 | let default_width = 60 12 | let default_height = 60 13 | let payload = { 14 | nodes: [ 15 | { id: "a", label: "A", left: 0, top: 0, width: 250, height: 250 }, 16 | { id: "a1", label: "A1", left: 0, top: 0 }, 17 | { id: "a2", label: "A2", left: 0, top: 0 } 18 | ], 19 | edges: [ 20 | { from: "a", to: "a1" }, 21 | { from: "a", to: "a2" }, 22 | ] 23 | } 24 | 25 | console.log(JSON.stringify(payload)) 26 | 27 | /* 28 | {"nodes":[{"id":"a","label":"A","left":0,"top":0,"width":250,"height":250},{"id":"a1","label":"A1","left":0,"top":0},{"id":"a2","label":"A2","left":0,"top":0}],"edges":[{"from":"a","to":"a1"},{"from":"a","to":"a2"}]} 29 | */ 30 | -------------------------------------------------------------------------------- /Research/overlap_removal_server/screenshots/example_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/overlap_removal_server/screenshots/example_client.png -------------------------------------------------------------------------------- /Research/overlap_removal_server/screenshots/geogebra_debugging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/overlap_removal_server/screenshots/geogebra_debugging.png -------------------------------------------------------------------------------- /Research/parsing/ast_and_typed_ast/astbug_python3_8_regular_ast_ok.py: -------------------------------------------------------------------------------- 1 | import ast 2 | 3 | # Proof regular ast works ok in python 3.8 4 | 5 | source = """ 6 | variable = 'a' 7 | x = 29 8 | print(f'{variable=} and {x=}') 9 | """ 10 | node = ast.parse(source) 11 | print(node) 12 | -------------------------------------------------------------------------------- /Research/parsing/ast_and_typed_ast/astbug_python3_8_typed_ast_fails.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | """ 4 | Proof that typed_ast.ast3 cannot handle Python 3.8 syntax. 5 | This models what Pynsource src/parsing/core_parser_ast.py does 6 | 7 | This is as is expected. 8 | 9 | NOTE: The official word on this is: https://github.com/python/typed_ast 10 | typed_ast will not be updated to support parsing Python 3.8 and newer. 11 | Instead, it is recommended to use the stdlib ast module there, which 12 | has been augmented to support extracting type comments and has limited 13 | support for parsing older versions of Python 3. 14 | """ 15 | 16 | # lookup tables e.g. BOOLOP_SYMBOLS in a more general way e.g. 'And' 17 | import ast as ast_native # native ast of the Python that is running 18 | 19 | if sys.version_info >= (3, 0): 20 | import typed_ast.ast27 # py2 (requires Python 3 to be running) 21 | import typed_ast.ast3 # py3 (requires Python 3 to be running) 22 | 23 | source = """ 24 | variable = 'a' 25 | x = 29 26 | print(f'{variable=} and {x=}') 27 | """ 28 | ast = typed_ast.ast3 29 | node = ast.parse(source) 30 | print(node) 31 | -------------------------------------------------------------------------------- /Research/parsing/ast_and_typed_ast/astbug_python3_8_typed_ast_fails_simple.py: -------------------------------------------------------------------------------- 1 | # import ast 2 | from typed_ast import ast3 3 | 4 | """ 5 | Proof that typed_ast.ast3 cannot handle Python 3.8 syntax. 6 | Simplified test case. 7 | 8 | This is as is expected. 9 | 10 | NOTE: The official word on this is: https://github.com/python/typed_ast 11 | typed_ast will not be updated to support parsing Python 3.8 and newer. 12 | Instead, it is recommended to use the stdlib ast module there, which 13 | has been augmented to support extracting type comments and has limited 14 | support for parsing older versions of Python 3. 15 | """ 16 | 17 | source = """ 18 | variable = 'a' 19 | x = 29 20 | print(f'{variable=} and {x=}') 21 | """ 22 | node = ast3.parse(source) 23 | print(node) 24 | -------------------------------------------------------------------------------- /Research/parsing/issues_85_93_94_parsing/demo.py: -------------------------------------------------------------------------------- 1 | x = 10 2 | SETTINGS = 'something' 3 | module_ref = SomeOtherClass() 4 | 5 | class Customer: 6 | def __init__(self, restaurant): 7 | self.restaurant: Restaurant = restaurant 8 | self.fred: Fred 9 | self.xx: Mary = None 10 | 11 | class Employee: 12 | def __init__(self, restaurant): 13 | self.restaurant: Restaurant = restaurant 14 | 15 | class Boss(Employee): 16 | salary = 1000 17 | reputation = 'good' 18 | 19 | def test(): 20 | pass 21 | 22 | def main(): 23 | pass 24 | 25 | -------------------------------------------------------------------------------- /Research/parsing/issues_85_93_94_parsing/issue_85_type_hint.py: -------------------------------------------------------------------------------- 1 | class SimpleHttpTask(Task): 2 | url = None 3 | method = "GET" 4 | client: requests.Session = requests.Session() 5 | print('done') 6 | -------------------------------------------------------------------------------- /Research/parsing/issues_85_93_94_parsing/issue_93_subscript.py: -------------------------------------------------------------------------------- 1 | class Issue93: 2 | def method1(self): 3 | self.pages: List[SnapFileView2D] = list() 4 | print('done') 5 | 6 | -------------------------------------------------------------------------------- /Research/parsing/issues_85_93_94_parsing/issue_94_walrus.py: -------------------------------------------------------------------------------- 1 | # python 3.9 required to parse this 2 | class Issue94: 3 | def method1(self): 4 | if (pair := chairs.get(number, None)) is None: 5 | pass 6 | print('done') 7 | -------------------------------------------------------------------------------- /Research/parsing/issues_85_93_94_parsing/type_hint_example.py: -------------------------------------------------------------------------------- 1 | class Customer: 2 | def __init__(self, restaurant): 3 | self.restaurant: Restaurant = restaurant 4 | self.fred: Fred 5 | self.xx: Mary = None -------------------------------------------------------------------------------- /Research/plantuml/api_example1.txt: -------------------------------------------------------------------------------- 1 | test 2 | this is a test 3 | http://plantuml.com/plantuml/png/Aov9B2hXil98pSd9LoZFByf9iUOgBial0000 4 | 5 | -------------------------------------------------------------------------------- /Research/python advanced/decorator_dump_params1.py: -------------------------------------------------------------------------------- 1 | dodump = True # ANDY MOD 2 | 3 | 4 | def dump_args(func): 5 | "This decorator dumps out the arguments passed to a function before calling it" 6 | argnames = func.__code__.co_varnames[: func.__code__.co_argcount] 7 | fname = func.__name__ 8 | 9 | if not dodump: 10 | return func 11 | 12 | def echo_func(*args, **kwargs): 13 | print( 14 | fname, 15 | ":", 16 | ", ".join( 17 | "%s=%r" % entry for entry in list(zip(argnames, args)) + list(kwargs.items()) 18 | ), 19 | ) 20 | return func(*args, **kwargs) 21 | 22 | return echo_func 23 | 24 | 25 | @dump_args 26 | def f1(a, b, c): 27 | print(a + b + c) 28 | 29 | 30 | f1(1, 2, 3) 31 | -------------------------------------------------------------------------------- /Research/python advanced/decorator_function_call_counter1.py: -------------------------------------------------------------------------------- 1 | # from http://wiki.python.org/moin/PythonDecoratorLibrary 2 | 3 | 4 | class countcalls(object): 5 | "Decorator that keeps track of the number of times a function is called." 6 | 7 | __instances = {} 8 | 9 | def __init__(self, f): 10 | self.__f = f 11 | self.__numcalls = 0 12 | countcalls.__instances[f] = self 13 | 14 | def __call__(self, *args, **kwargs): 15 | self.__numcalls += 1 16 | return self.__f(*args, **kwargs) 17 | 18 | @staticmethod 19 | def count(f): 20 | "Return the number of times the function f was called." 21 | return countcalls.__instances[f].__numcalls 22 | 23 | @staticmethod 24 | def counts(): 25 | "Return a dict of {function: # of calls} for all registered functions." 26 | return dict([(f, countcalls.count(f)) for f in countcalls.__instances]) 27 | 28 | 29 | # ANDY EXAMPLE 30 | 31 | if __name__ == "__main__": 32 | 33 | @countcalls 34 | def andy1(): 35 | print("andy1 called") 36 | 37 | andy1() 38 | andy1() 39 | andy1() 40 | 41 | # same 42 | print(countcalls.counts()) 43 | print(andy1.counts()) 44 | 45 | # print countcalls.count(andy1) # this doesn't work - why? 46 | print(countcalls.counts()) 47 | print("done") 48 | -------------------------------------------------------------------------------- /Research/python advanced/decorator_function_call_counter2.py: -------------------------------------------------------------------------------- 1 | # from http://wiki.python.org/moin/PythonDecoratorLibrary 2 | 3 | # ANDY NOTE: Nice dict formatting 4 | 5 | 6 | class countcalls(object): 7 | "Decorator that keeps track of the number of times a function is called." 8 | 9 | __instances = {} 10 | 11 | def __init__(self, f): 12 | self.__f = f 13 | self.__numcalls = 0 14 | countcalls.__instances[f] = self 15 | 16 | def __call__(self, *args, **kwargs): 17 | self.__numcalls += 1 18 | return self.__f(*args, **kwargs) 19 | 20 | def count(self): 21 | "Return the number of times the function f was called." 22 | return countcalls.__instances[self.__f].__numcalls 23 | # return self.__numcalls # ANDY - THIS WORKS TOO!? SO WHY IS THE ABOVE COMPLICATED THING USED? 24 | 25 | @staticmethod 26 | def counts(): 27 | "Return a dict of {function: # of calls} for all registered functions." 28 | return dict( 29 | [(f.__name__, countcalls.__instances[f].__numcalls) for f in countcalls.__instances] 30 | ) 31 | 32 | 33 | if __name__ == "__main__": 34 | 35 | # example 36 | 37 | @countcalls 38 | def f(): 39 | print("f called") 40 | 41 | @countcalls 42 | def g(): 43 | print("g called") 44 | 45 | f() 46 | f() 47 | f() 48 | print(f.count()) # prints 3 49 | 50 | print(countcalls.counts()) # same as f.counts() or g.counts() 51 | print(f.counts()) 52 | 53 | g() 54 | print(g.count()) # prints 1 55 | 56 | print(countcalls.counts()) 57 | 58 | print("done") 59 | -------------------------------------------------------------------------------- /Research/python advanced/interfaces1.py: -------------------------------------------------------------------------------- 1 | # Interfaces 2 | # Fantastic article http://www.doughellmann.com/PyMOTW/abc/ 3 | # 4 | 5 | import abc 6 | 7 | 8 | class PluginBase(object, metaclass=abc.ABCMeta): 9 | @abc.abstractmethod 10 | def load(self, input): 11 | """Retrieve data from the input source and return an object.""" 12 | return 13 | 14 | @abc.abstractmethod 15 | def save(self, output, data): 16 | """Save the data object to the output.""" 17 | return 18 | 19 | 20 | class SubclassImplementation(PluginBase): 21 | def load(self, input): 22 | return input.read() 23 | 24 | def save(self, output, data): 25 | return output.write(data) 26 | 27 | 28 | # o = PluginBase() # Can't instantiate base class 29 | o = SubclassImplementation() 30 | print(o) 31 | 32 | 33 | class IncompleteImplementation(PluginBase): 34 | def save(self, output, data): 35 | return output.write(data) 36 | 37 | 38 | # o = IncompleteImplementation() # Can't instantiate Incomplete Implementation 39 | # print o 40 | 41 | print("done") 42 | -------------------------------------------------------------------------------- /Research/python advanced/interfaces2.py: -------------------------------------------------------------------------------- 1 | # Interfaces 2 | # Fantastic article http://www.doughellmann.com/PyMOTW/abc/ 3 | # 4 | 5 | import abc 6 | 7 | 8 | class IPersist(object, metaclass=abc.ABCMeta): 9 | @abc.abstractmethod 10 | def load(self, input): 11 | return 12 | 13 | @abc.abstractmethod 14 | def save(self, output, data): 15 | return 16 | 17 | 18 | class ISing(object, metaclass=abc.ABCMeta): 19 | @abc.abstractmethod 20 | def sing(self): 21 | return 22 | 23 | 24 | ##### 25 | 26 | 27 | class MyClass(IPersist, ISing): 28 | def load(self, input): 29 | return input.read() 30 | 31 | def save(self, output, data): 32 | return output.write(data) 33 | 34 | def sing(self): 35 | return 36 | 37 | 38 | o = MyClass() 39 | print(o) 40 | 41 | print("done") 42 | -------------------------------------------------------------------------------- /Research/python advanced/properties1.py: -------------------------------------------------------------------------------- 1 | # Properties 2 | 3 | # In python, you don't need unnecessary getter and setter. 4 | # You can get the same thing in a more beautiful way with property. 5 | # Initially, you can code 6 | 7 | 8 | class C(object): 9 | def __init__(self, x): 10 | self.x = x 11 | 12 | 13 | obj = C(5) 14 | print("x is currently", obj.x) 15 | obj.x = 6 # set 16 | print(obj.x) # get 17 | 18 | print("-----") 19 | 20 | # Later, you can change it to allow getter, setter 21 | class C(object): 22 | def __init__(self, x): 23 | self._x = x 24 | 25 | def get_x(self): 26 | return self._x 27 | 28 | def set_x(self, x): 29 | print("x is being set (old style setter)") 30 | self._x = x 31 | 32 | x = property(get_x, set_x) 33 | 34 | 35 | obj = C(5) 36 | print("x is currently", obj.x) 37 | obj.x = 6 # set 38 | print(obj.x) # get 39 | 40 | # You can use class C in almost the same way, but you 41 | # can add anything else you want to do to get_x, set_x. 42 | 43 | print("-----") 44 | 45 | # 46 | # new-style properties 47 | # 48 | 49 | 50 | class C(object): 51 | def __init__(self, x): 52 | self._x = x 53 | 54 | @property 55 | def x(self): 56 | return self._x 57 | 58 | @x.setter 59 | def x(self, value): 60 | print("x is being set (new style)") 61 | self._x = value 62 | 63 | 64 | c = C(5) 65 | print("x is currently", c.x) 66 | c.x = 6 67 | print(c.x) 68 | -------------------------------------------------------------------------------- /Research/run_research_guis.bat: -------------------------------------------------------------------------------- 1 | cd "wx form builder" 2 | python fbpyn1.py 3 | cd .. 4 | 5 | cd hexmvc\architecture3 6 | python AppMainConfigOo.py 7 | cd ..\.. 8 | 9 | cd "layout force spring" 10 | python gui.py 11 | cd .. 12 | -------------------------------------------------------------------------------- /Research/state chart editor/Editor.py: -------------------------------------------------------------------------------- 1 | # Editor.py 2 | from Statechart import Statechart 3 | from TopHandler import TopHandler 4 | from GUI import GUI 5 | 6 | 7 | class Editor: 8 | def __init__(self): 9 | self.topHandler = TopHandler() 10 | self.GUI = GUI(self.topHandler) 11 | self.topHandler.setGUI(self.GUI) 12 | self.statechart = Statechart(self.GUI.getStatechartHandler()) 13 | self.statechart.setCanvas(self.GUI.getCanvas()) 14 | self.topHandler.setStatechart(self.statechart) 15 | 16 | def start(self): 17 | self.GUI.mainloop() 18 | 19 | 20 | if __name__ == "__main__": 21 | editor = Editor() 22 | editor.start() 23 | -------------------------------------------------------------------------------- /Research/state chart editor/Globals.py: -------------------------------------------------------------------------------- 1 | # state minimum width 2 | MIN_WIDTH = 90 3 | # state minimum height 4 | MIN_HEIGHT = 50 5 | # state corner radius 6 | RADIUS = 14 7 | # final state radius 8 | FINAL_OUT_RADIUS = 17 9 | # final state inside radius (black dot) 10 | FINAL_IN_RADIUS = 10 11 | SEPARATOR_WIDTH = 5 12 | TRANSITION_WIDTH = 2 13 | TRANSITION_DOT = 3 14 | TRANSITION_LABEL_DY = 8 15 | SEPARATOR_PAD = 23 16 | SEPARATOR_BITMAP = "gray50" 17 | SELECTED_COLOR = "blue" 18 | SHADOW_COLOR = "gray" 19 | 20 | 21 | NO_HS = 0 22 | ONE_HS = 1 23 | DEEP_HS = 2 24 | -------------------------------------------------------------------------------- /Research/state chart editor/icon16win.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/state chart editor/icon16win.ico -------------------------------------------------------------------------------- /Research/state chart editor/junk.log: -------------------------------------------------------------------------------- 1 | MsSansSerif not found, using Courier. 2 | -------------------------------------------------------------------------------- /Research/state chart editor/junk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/state chart editor/junk.pdf -------------------------------------------------------------------------------- /Research/winerack ogl and floatcanvas/Moo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/winerack ogl and floatcanvas/Moo.jpg -------------------------------------------------------------------------------- /Research/wx doco/Custom CommandEvent in wxPython.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://stackoverflow.com/questions/640045/generate-a-custom-commandevent-in-wxpython 3 | -------------------------------------------------------------------------------- /Research/wx doco/ImageViewer0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # myscrolledwindow.py 4 | 5 | import wx 6 | 7 | 8 | class MyScrolledWindow(wx.Frame): 9 | def __init__(self, parent, id, title): 10 | wx.Frame.__init__(self, parent, id, title, size=(500, 400)) 11 | 12 | sw = wx.ScrolledWindow(self) 13 | bmp = wx.Image("moo.jpg", wx.BITMAP_TYPE_JPEG).ConvertToBitmap() 14 | wx.StaticBitmap(sw, -1, bmp) 15 | sw.SetScrollbars(20, 20, 55, 40) 16 | 17 | 18 | class MyApp(wx.App): 19 | def OnInit(self): 20 | frame = MyScrolledWindow(None, -1, "Aliens") 21 | frame.Show(True) 22 | frame.Centre() 23 | return True 24 | 25 | 26 | app = MyApp(0) 27 | app.MainLoop() 28 | -------------------------------------------------------------------------------- /Research/wx doco/ImageViewer0a.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import wx, os 4 | 5 | 6 | class TestFrame(wx.Frame): 7 | def __init__(self, *args, **kwargs): 8 | 9 | wx.Frame.__init__(self, *args, **kwargs) 10 | 11 | sw = wx.ScrolledWindow(self) 12 | 13 | bmp = wx.Image("moo.jpg", wx.BITMAP_TYPE_JPEG).ConvertToBitmap() 14 | wx.StaticBitmap(sw, -1, bmp) 15 | sw.SetScrollbars(20, 20, 55, 40) 16 | 17 | 18 | class App(wx.App): 19 | def OnInit(self): 20 | frame = TestFrame(None, title="Andy wxBitmap Test") 21 | frame.Show(True) 22 | frame.Centre() 23 | return True 24 | 25 | 26 | if __name__ == "__main__": 27 | app = App(0) 28 | app.MainLoop() 29 | 30 | """ 31 | You'll be better off not using a wx.StaticBitmap for this. (After all 32 | static means unchanging.) Instead catch the EVT_PAINT event and draw 33 | the bitmap yourself. Then you can do things like stretching it to fit 34 | the window, or whatever you want. Just convert it to a wx.Image, 35 | manipulate it, convert to a wx.Bitmap and draw it. 36 | """ 37 | -------------------------------------------------------------------------------- /Research/wx doco/ImageViewer4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import wx 4 | 5 | 6 | class TestApp(wx.App): 7 | def OnInit(self): 8 | self.MainFrame = wx.Frame(None, -1, "Test Frame") 9 | self.MainFrame.SetBackgroundColour(wx.WHITE) 10 | self.BMP = wx.Bitmap("../../outyuml.png", wx.BITMAP_TYPE_PNG) 11 | self.MainFrame.Bind(wx.EVT_PAINT, self.OnPaint) 12 | self.MainFrame.Show() 13 | return True 14 | 15 | def OnPaint(self, Event): 16 | DC = wx.PaintDC(self.MainFrame) 17 | DC.DrawBitmap(self.BMP, 0, 0) 18 | Event.Skip() 19 | 20 | 21 | App = TestApp(1) 22 | App.MainLoop() 23 | -------------------------------------------------------------------------------- /Research/wx doco/ImageViewer4scaled.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import wx 4 | 5 | 6 | class TestApp(wx.App): 7 | def OnInit(self): 8 | self.MainFrame = wx.Frame(None, -1, "Test Frame") 9 | self.MainFrame.SetBackgroundColour(wx.WHITE) 10 | 11 | self.sw = wx.ScrolledWindow(self.MainFrame) 12 | self.sw.SetScrollbars(20, 20, 55, 40) 13 | 14 | self.BMP = wx.Bitmap("../../outyuml.png", wx.BITMAP_TYPE_PNG) 15 | 16 | self.sw.Bind(wx.EVT_PAINT, self.OnPaint) 17 | 18 | # self.MainFrame.Bind(wx.EVT_PAINT, self.OnPaint) 19 | self.MainFrame.Show() 20 | return True 21 | 22 | def OnPaint(self, Event): 23 | DC = wx.PaintDC(self.sw, self.BMP, wx.BUFFER_VIRTUAL_AREA) 24 | # DC = wx.PaintDC(self.sw) 25 | DC.SetUserScale(2, 2) # ANDY 26 | DC.DrawBitmap(self.BMP, 0, 0) 27 | Event.Skip() 28 | 29 | 30 | App = TestApp(1) 31 | App.MainLoop() 32 | -------------------------------------------------------------------------------- /Research/wx doco/Images/Moo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/Moo.jpg -------------------------------------------------------------------------------- /Research/wx doco/Images/Physics-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/Physics-4.jpg -------------------------------------------------------------------------------- /Research/wx doco/Images/SPLASHSCREEN.BMP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/SPLASHSCREEN.BMP -------------------------------------------------------------------------------- /Research/wx doco/Images/SliderPuzzle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/SliderPuzzle.jpg -------------------------------------------------------------------------------- /Research/wx doco/Images/fish1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/fish1.png -------------------------------------------------------------------------------- /Research/wx doco/Images/img_uml01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/img_uml01.png -------------------------------------------------------------------------------- /Research/wx doco/Images/outyuml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/outyuml.png -------------------------------------------------------------------------------- /Research/wx doco/Images/outyuml_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/outyuml_big.png -------------------------------------------------------------------------------- /Research/wx doco/Images/pickle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/pickle.jpg -------------------------------------------------------------------------------- /Research/wx doco/Images/shader-ReflectiveBumpedVertexLit-0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/shader-ReflectiveBumpedVertexLit-0.jpg -------------------------------------------------------------------------------- /Research/wx doco/Images/w05_783sidebar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Images/w05_783sidebar.jpg -------------------------------------------------------------------------------- /Research/wx doco/LongRunning wx.gauge no while-loop.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://stackoverflow.com/questions/2052369/updating-the-wx-gauge-without-while-loop/2052462#2052462 3 | -------------------------------------------------------------------------------- /Research/wx doco/LongRunningTasks - wxPyWiki.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://wiki.wxpython.org/LongRunningTasks 3 | -------------------------------------------------------------------------------- /Research/wx doco/MessageBox - MessageDialog - wxPython-users - Google Groups.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://groups.google.com/group/wxPython-users/browse_thread/thread/81c7d3d590eef04a 3 | -------------------------------------------------------------------------------- /Research/wx doco/Moo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx doco/Moo.jpg -------------------------------------------------------------------------------- /Research/wx doco/Response from MessageDialog.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.java2s.com/Tutorial/Python/0380__wxPython/ResponsefromMessageDialog.htm 3 | -------------------------------------------------------------------------------- /Research/wx doco/aui library Advanced Generic Widgets v0.9.1 documentation.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://xoomer.virgilio.it/infinity77/AGW_Docs/aui_module.html#aui 3 | -------------------------------------------------------------------------------- /Research/wx doco/python - wxPython- Making a scrollable DC - Stack Overflow.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://stackoverflow.com/questions/677590/wxpython-making-a-scrollable-dc 3 | -------------------------------------------------------------------------------- /Research/wx doco/resize_scroll_01.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | 4 | class ScrollbarFrame(wx.Frame): 5 | def __init__(self): 6 | wx.Frame.__init__(self, None, -1, "Scrollbar Example", size=(300, 200)) 7 | self.scroll = wx.ScrolledWindow(self, -1) 8 | self.scroll.SetScrollbars(1, 1, 600, 400) 9 | self.button = wx.Button(self.scroll, -1, "Scroll Me", pos=(50, 20)) 10 | self.Bind(wx.EVT_BUTTON, self.OnClickTop, self.button) 11 | self.button2 = wx.Button(self.scroll, -1, "Scroll Back", pos=(500, 350)) 12 | self.Bind(wx.EVT_BUTTON, self.OnClickBottom, self.button2) 13 | 14 | self.button = wx.Button(self.scroll, -1, "Extend scroll area1", pos=(50, 120)) 15 | self.Bind(wx.EVT_BUTTON, self.OnClickExtend1, self.button) 16 | self.button = wx.Button(self.scroll, -1, "Shrink scroll area1", pos=(150, 120)) 17 | self.Bind(wx.EVT_BUTTON, self.OnClickShrink1, self.button) 18 | 19 | def OnClickTop(self, event): 20 | self.scroll.Scroll(600, 400) 21 | 22 | def OnClickBottom(self, event): 23 | self.scroll.Scroll(1, 1) 24 | 25 | def OnClickExtend1(self, event): 26 | self.scroll.SetScrollbars(1, 1, 1600, 1400) 27 | 28 | def OnClickShrink1(self, event): 29 | self.scroll.SetScrollbars(1, 1, 600, 400) 30 | 31 | 32 | app = wx.PySimpleApp() 33 | frame = ScrollbarFrame() 34 | frame.Show() 35 | app.MainLoop() 36 | -------------------------------------------------------------------------------- /Research/wx doco/scroll_window_in_action1.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | 4 | class ScrollbarFrame(wx.Frame): 5 | def __init__(self): 6 | wx.Frame.__init__(self, None, -1, "Scrollbar Example", size=(300, 200)) 7 | self.scroll = wx.ScrolledWindow(self, -1) 8 | print("GetVirtualSize()", self.GetVirtualSize()) 9 | self.scroll.SetScrollbars(1, 1, 600, 400) 10 | print("GetVirtualSize()", self.GetVirtualSize()) 11 | self.button = wx.Button(self.scroll, -1, "Scroll Me", pos=(50, 20)) 12 | self.Bind(wx.EVT_BUTTON, self.OnClickTop, self.button) 13 | self.button2 = wx.Button(self.scroll, -1, "Scroll Back", pos=(500, 350)) 14 | self.Bind(wx.EVT_BUTTON, self.OnClickBottom, self.button2) 15 | 16 | def OnClickTop(self, event): 17 | self.scroll.Scroll(600, 400) 18 | print("FRAME") 19 | print("GetVirtualSize()", self.GetVirtualSize()) 20 | print("GetSize()", self.GetSize()) 21 | print("ScrolledWindow ------ ") 22 | print("GetVirtualSize()", self.scroll.GetVirtualSize()) 23 | print("GetSize()", self.scroll.GetSize()) 24 | print("**********") 25 | 26 | def OnClickBottom(self, event): 27 | self.scroll.Scroll(1, 1) 28 | 29 | 30 | if __name__ == "__main__": 31 | app = wx.PySimpleApp() 32 | frame = ScrollbarFrame() 33 | frame.Show() 34 | app.MainLoop() 35 | -------------------------------------------------------------------------------- /Research/wx doco/somenotebook0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # notebook.py 4 | 5 | import wx 6 | import wx.lib.sheet as sheet 7 | 8 | 9 | class MySheet(sheet.CSheet): 10 | def __init__(self, parent): 11 | sheet.CSheet.__init__(self, parent) 12 | self.SetNumberRows(50) 13 | self.SetNumberCols(50) 14 | 15 | 16 | class Notebook(wx.Frame): 17 | def __init__(self, parent, id, title): 18 | wx.Frame.__init__(self, parent, id, title, size=(600, 500)) 19 | menubar = wx.MenuBar() 20 | file = wx.Menu() 21 | file.Append(101, "Quit", "") 22 | menubar.Append(file, "&File") 23 | self.SetMenuBar(menubar) 24 | 25 | wx.EVT_MENU(self, 101, self.OnQuit) 26 | 27 | nb = wx.Notebook(self, -1, style=wx.NB_BOTTOM) 28 | self.sheet1 = MySheet(nb) 29 | self.sheet2 = MySheet(nb) 30 | self.sheet3 = MySheet(nb) 31 | 32 | nb.AddPage(self.sheet1, "Sheet1") 33 | nb.AddPage(self.sheet2, "Sheet2") 34 | nb.AddPage(self.sheet3, "Sheet3") 35 | 36 | self.sheet1.SetFocus() 37 | self.StatusBar() 38 | self.Centre() 39 | self.Show() 40 | 41 | def StatusBar(self): 42 | self.statusbar = self.CreateStatusBar() 43 | 44 | def OnQuit(self, event): 45 | self.Close() 46 | 47 | 48 | app = wx.App() 49 | Notebook(None, -1, "notebook.py") 50 | app.MainLoop() 51 | -------------------------------------------------------------------------------- /Research/wx doco/somesimple1.py: -------------------------------------------------------------------------------- 1 | # simple 2 | 3 | import wx 4 | 5 | 6 | class Line(wx.Frame): 7 | def __init__(self, parent, id, title): 8 | wx.Frame.__init__(self, parent, id, title, size=(250, 150)) 9 | 10 | wx.FutureCall(1000, self.DrawLine) 11 | 12 | self.Centre() 13 | self.Show(True) 14 | 15 | def DrawLine(self): 16 | dc = wx.ClientDC(self) 17 | dc.DrawLine(50, 60, 190, 60) 18 | 19 | # dc.DrawArc(50, 50, 50, 10, 20, 20) 20 | # dc.DrawEllipticArc(10,10, 50, 20, 0, 180) 21 | 22 | points = [wx.Point(10, 10), wx.Point(15, 55), wx.Point(40, 30)] 23 | dc.DrawSpline(points) 24 | 25 | 26 | app = wx.App() 27 | Line(None, -1, "Line") 28 | app.MainLoop() 29 | -------------------------------------------------------------------------------- /Research/wx doco/wx Index.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.wxpython.org/docs/api/indices.html 3 | -------------------------------------------------------------------------------- /Research/wx doco/wx.MessageDialog.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.wxpython.org/docs/api/wx.MessageDialog-class.html 3 | -------------------------------------------------------------------------------- /Research/wx doco/wx.ScrolledWindow.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.wxpython.org/docs/api/wx.ScrolledWindow-class.html 3 | -------------------------------------------------------------------------------- /Research/wx doco/wx.Window.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.wxpython.org/docs/api/wx.Window-class.html 3 | -------------------------------------------------------------------------------- /Research/wx doco/wx.lib.ogl.Diagram.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.wxpython.org/docs/api/wx.lib.ogl.Diagram-class.html 3 | -------------------------------------------------------------------------------- /Research/wx doco/wx.lib.ogl.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.wxpython.org/docs/api/wx.lib.ogl-module.html 3 | -------------------------------------------------------------------------------- /Research/wx doco/wxOGL - wxPyWiki - MAIN EXAMPLES.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://wiki.wxpython.org/wxOGL 3 | -------------------------------------------------------------------------------- /Research/wx doco/wxPython dialogs.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://zetcode.com/wxpython/dialogs/ 3 | -------------------------------------------------------------------------------- /Research/wx doco/wxpython Overview Of GDI.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.itrascal.com/paila/GDI/OverviewOfGDI/tabid/106/Default.aspx 3 | -------------------------------------------------------------------------------- /Research/wx form builder/2019test1/run.sh: -------------------------------------------------------------------------------- 1 | pythonw test1.py 2 | -------------------------------------------------------------------------------- /Research/wx form builder/2019test1/toucan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/2019test1/toucan.png -------------------------------------------------------------------------------- /Research/wx form builder/Doco Custom Component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/Doco Custom Component.png -------------------------------------------------------------------------------- /Research/wx form builder/Doco ogl Custom Component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/Doco ogl Custom Component.png -------------------------------------------------------------------------------- /Research/wx form builder/fbogl1.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from fbogl1_gen import MyFrame2 3 | import wx.lib.ogl as ogl 4 | 5 | app = wx.App() 6 | ogl.OGLInitialize() 7 | frame = MyFrame2(None) 8 | frame.Show() 9 | frame.SetSize((400, 400)) 10 | 11 | frame.canvas.SetBackgroundColour("LIGHT BLUE") 12 | # Optional - add a shape 13 | shape = ogl.RectangleShape(60, 60) 14 | shape.SetX(50) 15 | shape.SetY(50) 16 | frame.canvas.AddShape(shape) 17 | frame.canvas.GetDiagram().ShowAll(True) 18 | 19 | app.MainLoop() 20 | -------------------------------------------------------------------------------- /Research/wx form builder/fbogl1_gen.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ########################################################################### 4 | ## Python code generated with wxFormBuilder (version Mar 22 2011) 5 | ## http://www.wxformbuilder.org/ 6 | ## 7 | ## PLEASE DO "NOT" EDIT THIS FILE! 8 | ########################################################################### 9 | 10 | import wx 11 | import wx.lib.ogl as ogl 12 | 13 | ########################################################################### 14 | ## Class MyFrame2 15 | ########################################################################### 16 | 17 | 18 | class MyFrame2(wx.Frame): 19 | def __init__(self, parent): 20 | wx.Frame.__init__( 21 | self, 22 | parent, 23 | id=wx.ID_ANY, 24 | title=wx.EmptyString, 25 | pos=wx.DefaultPosition, 26 | size=wx.Size(500, 300), 27 | style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, 28 | ) 29 | 30 | self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 31 | 32 | bSizer9 = wx.BoxSizer(wx.VERTICAL) 33 | 34 | self.canvas = ogl.ShapeCanvas(self) 35 | diagram = ogl.Diagram() 36 | self.canvas.SetDiagram(diagram) 37 | diagram.SetCanvas(self.canvas) 38 | bSizer9.Add(self.canvas, 1, wx.ALL | wx.EXPAND, 5) 39 | 40 | self.SetSizer(bSizer9) 41 | self.Layout() 42 | 43 | self.Centre(wx.BOTH) 44 | 45 | def __del__(self): 46 | pass 47 | -------------------------------------------------------------------------------- /Research/wx form builder/fbtest01.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from fbtest01_gen import * 3 | 4 | 5 | class MyFrame1A(MyFrame1): 6 | def OnButton1(self, event): 7 | print("button pushed") 8 | 9 | def OnHtml2(self, event): 10 | url = "http://www.wxpython.org/docs/api/wx.html.HtmlWindow-class.html" 11 | wx.CallAfter(frame.m_htmlWin1.LoadPage, url) 12 | 13 | def OnLoadHtml1(self, event): 14 | url = "http://help.websiteos.com/websiteos/example_of_a_simple_html_page.htm" 15 | wx.CallAfter(frame.m_htmlWin1.LoadPage, url) 16 | # frame.m_htmlWin1.LoadPage(url) 17 | 18 | 19 | app = wx.App() 20 | frame = MyFrame1A(None) 21 | frame.Show() 22 | frame.SetSize((400, 400)) 23 | 24 | 25 | app.MainLoop() 26 | -------------------------------------------------------------------------------- /Research/wx form builder/icons16/katomic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons16/katomic.png -------------------------------------------------------------------------------- /Research/wx form builder/icons16/kcmprocessor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons16/kcmprocessor.png -------------------------------------------------------------------------------- /Research/wx form builder/icons16/kcmscsi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons16/kcmscsi.png -------------------------------------------------------------------------------- /Research/wx form builder/icons16/kedit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons16/kedit.png -------------------------------------------------------------------------------- /Research/wx form builder/icons16/khangman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons16/khangman.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kaboodleloop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kaboodleloop.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kalarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kalarm.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kalzium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kalzium.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kcmmidi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kcmmidi.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kcmprocessor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kcmprocessor.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kcmscsi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kcmscsi.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kcontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kcontrol.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kedit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kedit.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/khangman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/khangman.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kmid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kmid.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kmoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kmoon.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kopete_offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kopete_offline.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/kreversi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/kreversi.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/package_development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/package_development.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/reload.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/roll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/roll.png -------------------------------------------------------------------------------- /Research/wx form builder/icons22/tool_timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons22/tool_timer.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kalzium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kalzium.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kcmmidi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kcmmidi.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kcmprocessor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kcmprocessor.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kcmscsi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kcmscsi.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kcontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kcontrol.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kedit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kedit.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/khangman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/khangman.png -------------------------------------------------------------------------------- /Research/wx form builder/icons32/kmoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/wx form builder/icons32/kmoon.png -------------------------------------------------------------------------------- /Research/wx form builder/some_fb1.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from some_fb2_gen import MyFrame1 3 | 4 | app = wx.App() 5 | frame = MyFrame1(None) 6 | frame.Show() 7 | app.MainLoop() 8 | -------------------------------------------------------------------------------- /Research/wx form builder/some_fb2_1.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from someStyledTextCtrl2 import runTest 3 | 4 | # Good demo http://zamestnanci.fai.utb.cz/~bliznak/screencast/wxfbtut1/wxFBTut1.html 5 | 6 | 7 | from some_fb2_gen import * 8 | 9 | 10 | class MyFrame3A(MyFrame3): 11 | def OnButton1(self, event): 12 | print("button pushed") 13 | 14 | def OnHi(self, event): 15 | print("hi") 16 | 17 | def OnSay(self, event): 18 | print("say") 19 | 20 | 21 | app = wx.App() 22 | 23 | # DEMO 3 24 | # frame = MyFrame3A(None) 25 | 26 | # DEMO 2 27 | frame = MyFrame2(None) 28 | p = runTest(frame, frame, None) 29 | frame.m_scintilla1 = p 30 | # frame.m_scintilla1.SetText(demoText + open(r'..\..\pynsource\printframework.py').read()) 31 | 32 | 33 | frame.Show() 34 | app.MainLoop() 35 | -------------------------------------------------------------------------------- /Research/wx form builder/some_fb2_2.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from some_fb2_gen import MyFrame2 3 | 4 | app = wx.App() 5 | frame = MyFrame2(None) 6 | frame.m_customControl1.SetText(open(r"..\..\pynsource\printframework.py").read()) 7 | frame.m_customControl1.EmptyUndoBuffer() 8 | frame.Show() 9 | app.MainLoop() 10 | -------------------------------------------------------------------------------- /Research/wx form builder/some_fb2_2_altered.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from some_fb2_gen_altered import MyFrame2 3 | 4 | app = wx.App() 5 | frame = MyFrame2(None) 6 | frame.m_scintilla1.SetText(open(r"..\..\pynsource\printframework.py").read()) 7 | frame.m_scintilla1.EmptyUndoBuffer() 8 | frame.Show() 9 | app.MainLoop() 10 | -------------------------------------------------------------------------------- /Research/wx form builder/some_fb2_3.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | # Good demo http://zamestnanci.fai.utb.cz/~bliznak/screencast/wxfbtut1/wxFBTut1.html 4 | 5 | 6 | from some_fb2_gen import * 7 | 8 | 9 | class MyFrame3A(MyFrame3): 10 | def OnButton1(self, event): 11 | print("button pushed") 12 | 13 | def OnHi(self, event): 14 | print("hi") 15 | 16 | def OnSay(self, event): 17 | print("say") 18 | 19 | 20 | app = wx.App() 21 | 22 | # DEMO 3 23 | frame = MyFrame3A(None) 24 | 25 | frame.Show() 26 | app.MainLoop() 27 | -------------------------------------------------------------------------------- /Research/wx form builder/splitwin01.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | 4 | class MyFrame(wx.Frame): 5 | def __init__(self, parent, id, title): 6 | wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(350, 300)) 7 | 8 | splitter = wx.SplitterWindow(self, -1) 9 | panel1 = wx.Panel(splitter, -1) 10 | wx.StaticText( 11 | panel1, 12 | -1, 13 | "Whether you think that you can, or that you can't, you are usually right." 14 | "\n\n Henry Ford", 15 | (100, 100), 16 | style=wx.ALIGN_CENTRE, 17 | ) 18 | panel1.SetBackgroundColour(wx.LIGHT_GREY) 19 | panel2 = wx.Panel(splitter, -1) 20 | panel2.SetBackgroundColour(wx.WHITE) 21 | splitter.SplitVertically(panel1, panel2) 22 | self.Centre() 23 | 24 | 25 | class MyApp(wx.App): 26 | def OnInit(self): 27 | frame = MyFrame(None, -1, "splitterwindow.py") 28 | frame.Show(True) 29 | self.SetTopWindow(frame) 30 | return True 31 | 32 | 33 | app = MyApp(0) 34 | app.MainLoop() 35 | -------------------------------------------------------------------------------- /Research/wxglade/test2/test2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # generated by wxGlade 0.9.0b5 on Mon Jan 14 10:35:25 2019 5 | # 6 | 7 | import wx 8 | 9 | 10 | 11 | 12 | class _308418605_MyMenuBar(wx.MenuBar): 13 | def __init__(self, *args, **kwds): 14 | wx.MenuBar.__init__(self, *args, **kwds) 15 | wxglade_tmp_menu = wx.Menu() 16 | wxglade_tmp_menu.Append(wx.NewId(), "item", "") 17 | wxglade_tmp_menu.Append(wx.NewId(), "item", "") 18 | self.Append(wxglade_tmp_menu, "item") 19 | self.--- = wx.Menu() 20 | self.Append(self.---, "---") 21 | wxglade_tmp_menu = wx.Menu() 22 | wxglade_tmp_menu_sub = wx.Menu() 23 | wxglade_tmp_menu_sub.Append(wx.NewId(), "item", "") 24 | wxglade_tmp_menu_sub.Append(wx.NewId(), "item", "") 25 | wxglade_tmp_menu.Append(wx.NewId(), "item", wxglade_tmp_menu_sub, "") 26 | wxglade_tmp_menu.Append(wx.NewId(), "item", "") 27 | self.Append(wxglade_tmp_menu, "item") 28 | 29 | self.__set_properties() 30 | self.__do_layout() 31 | 32 | def __set_properties(self): 33 | pass 34 | 35 | def __do_layout(self): 36 | pass 37 | 38 | 39 | class MyAppy(wx.App): 40 | def OnInit(self): 41 | self.frame = MyFrame(None, wx.ID_ANY, "") 42 | self.SetTopWindow(self.frame) 43 | self.frame.Show() 44 | return True 45 | 46 | if __name__ == "__main__": 47 | appy = MyAppy(0) 48 | appy.MainLoop() 49 | -------------------------------------------------------------------------------- /Research/yuml_python/chromium launch idea.txt: -------------------------------------------------------------------------------- 1 | Actually this is nicer than wget if i dont want to save the image: 2 | 3 | chromium-browser $(cat model.yuml.txt) 4 | 5 | Updated: 6 | 7 | command-line uses regexp to replace spaces and newlines with %20, so i can break up my text file: 8 | 9 | chromium-browser $(cat model.yuml.txt | sed 's/ /%20/g' | sed ':a;N;$!ba;s/\n/%20/g') 10 | 11 | chromium-browser $(cat model.yuml.txt | sed 's/ /%20/g' | tr -d '\n') 12 | 13 | evolving: 14 | 15 | (this now just deletes all spaces and newlines) (if i want a space, i have to manually use %20) 16 | 17 | chromium-browser $(cat model.yuml.txt | tr -d ' ' | tr -d '\n') -------------------------------------------------------------------------------- /Research/yuml_python/copypng.py: -------------------------------------------------------------------------------- 1 | # http://www.codeproject.com/KB/web-image/pnggammastrip.aspx 2 | 3 | import sys 4 | import urllib.request, urllib.parse, urllib.error 5 | import urllib.request, urllib.error, urllib.parse 6 | 7 | import pnglib 8 | 9 | inputFilename = sys.argv[1] 10 | outputFilename = sys.argv[2] 11 | 12 | data = file(inputFilename, "rb") 13 | 14 | outputFile = file(outputFilename, "wb") 15 | signature = pnglib.read_signature(data) 16 | outputFile.write(signature) 17 | 18 | for chunk in png.all_chunks(data): 19 | chunk.write(outputFile) 20 | 21 | 22 | outputFile.close() 23 | -------------------------------------------------------------------------------- /Research/yuml_python/create_yuml_class_diagram.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import urllib.request, urllib.error, urllib.parse 3 | 4 | import png 5 | 6 | 7 | def add_yuml_to_png(yuml, in_stream, out_stream): 8 | signature = png.read_signature(in_stream) 9 | out_stream.write(signature) 10 | 11 | for chunk in png.all_chunks(in_stream): 12 | if chunk.chunk_type == "IEND": 13 | break 14 | chunk.write(out_stream) 15 | 16 | itxt_chunk = png.iTXtChunk.create("yuml", yuml) 17 | itxt_chunk.write(out_stream) 18 | 19 | # write the IEND chunk 20 | chunk.write(out_stream) 21 | 22 | 23 | def create(yuml, output_filename): 24 | # baseUrl = 'http://yuml.me/diagram/scruffy/class/' 25 | baseUrl = "http://yuml.me/diagram/dir:lr;scruffy/class/" 26 | url = baseUrl + urllib.parse.quote(yuml) 27 | 28 | original_png = urllib.request.urlopen(url) 29 | output_file = file(output_filename, "wb") 30 | 31 | add_yuml_to_png(yuml, original_png, output_file) 32 | 33 | output_file.close() 34 | 35 | 36 | if __name__ == "__main__": 37 | import sys 38 | 39 | sys.exit(create(*sys.argv[1:3])) 40 | -------------------------------------------------------------------------------- /Research/yuml_python/example yuml1.txt: -------------------------------------------------------------------------------- 1 | # Cool UML Diagram 2 | [Customer]+1->*[Order] 3 | [Order]++1-items >*[LineItem] 4 | [Order]-0..1>[PaymentMethod] 5 | [Fred]-0..1>[MMaPS CMS] 6 | [Fred]-0..1>[MMaPS CMS2] 7 | [Fred]-0..1>[MMaPS CMS3] 8 | [MMaPS CMS3]->[thing 1] 9 | [MMaPS CMS3]->[thing 2] 10 | [MMaPS CMS3]->[thing 3] 11 | [thing 3]-[Customer|Forename;Surname;Email|Save()],[Customer]-[note: Value Object] 12 | [Customer]^[Uncool Customer] 13 | [Customer]^[Cool Customer|name;address|Do(),Do2()] -------------------------------------------------------------------------------- /Research/yuml_python/order.bat: -------------------------------------------------------------------------------- 1 | del order.png 2 | python create_yuml_class_diagram.py "[Customer]+1->*[Order], [Order]++1-items>*[LineItem], [Order]-0..1>[PaymentMethod], [Andy]>[Python]" yuml_order_example.png 3 | -------------------------------------------------------------------------------- /Research/yuml_python/outyuml2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/yuml_python/outyuml2.png -------------------------------------------------------------------------------- /Research/yuml_python/pynsource1.bat: -------------------------------------------------------------------------------- 1 | del yuml_pynsource1_example.png 2 | python create_yuml_class_diagram.py "[HandleDefs]^[HandleClassAttributes|attrslist;waitingfordot;waitingforsubsequentdot;waitingforvarname;waitingforequalsymbol;currvarname;lastcurrvarname;waitforappendopenbracket;nextvarnameisstatic;nextvarnameismany|__init__();On_newline();_Clearwaiting();JustGotASelfAttr();On_meat();_AddAttribute()],[AndyBasicParseEngine]^[HandleClasses|currclasslist;_currclass;nexttokenisclass;classlist;modulemethods;optionModuleAsClass;inbetweenClassAndFirstDef|__init__();On_deindent();_DeriveNestedClassName();PushCurrClass();PopCurrClass();GetCurrClassIndentLevel();GetCurrClass();_JustThenGotclass();On_newline();On_meat()],[object]^[AndyBasicParseEngine|meat;tokens;isfreshline;indentlevel|__init__();_ReadAllTokensFromFile();Parse();_ParseLoop();On_deindent();On_newline();On_meat();_Gotmeat();_Isblank();_Isnewline();_Ispadding()]" yuml_pynsource1_example.png 3 | -------------------------------------------------------------------------------- /Research/yuml_python/pynsource3.bat: -------------------------------------------------------------------------------- 1 | REM do it in three stages - doesn't seem to append actually. 2 | del yuml_pynsource3_example.png 3 | python create_yuml_class_diagram.py "[HandleDefs]^[HandleClassAttributes|attrslist;waitingfordot;waitingforsubsequentdot;waitingforvarname;waitingforequalsymbol;currvarname;lastcurrvarname;waitforappendopenbracket;nextvarnameisstatic;nextvarnameismany|__init__();On_newline();_Clearwaiting();JustGotASelfAttr();On_meat();_AddAttribute()]" yuml_pynsource3_example.png 4 | python create_yuml_class_diagram.py "[AndyBasicParseEngine]^[HandleClasses|currclasslist;_currclass;nexttokenisclass;classlist;modulemethods;optionModuleAsClass;inbetweenClassAndFirstDef|__init__();On_deindent();_DeriveNestedClassName();PushCurrClass();PopCurrClass();GetCurrClassIndentLevel();GetCurrClass();_JustThenGotclass();On_newline();On_meat()]" yuml_pynsource3_example.png 5 | python create_yuml_class_diagram.py "[object]^[AndyBasicParseEngine|meat;tokens;isfreshline;indentlevel|__init__();_ReadAllTokensFromFile();Parse();_ParseLoop();On_deindent();On_newline();On_meat();_Gotmeat();_Isblank();_Isnewline();_Ispadding()]" yuml_pynsource3_example.png 6 | -------------------------------------------------------------------------------- /Research/yuml_python/read_yuml_from_png.py: -------------------------------------------------------------------------------- 1 | import png 2 | 3 | 4 | def read(pngFilename): 5 | yuml = "<>" 6 | pngFile = file(pngFilename, "rb") 7 | png.read_signature(pngFile) 8 | for chunk in png.all_chunks(pngFile): 9 | if chunk.chunk_type == "iTXt": 10 | chunk = png.iTXtChunk(chunk) 11 | if chunk.keyword == "yuml": 12 | yuml = chunk.text 13 | break 14 | pngFile.close() 15 | return yuml 16 | 17 | 18 | if __name__ == "__main__": 19 | import sys 20 | 21 | sys.exit(read(sys.argv[1])) 22 | -------------------------------------------------------------------------------- /Research/yuml_python/write_end_of_png.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | print(repr(file(sys.argv[1], "rb").read()[-500:])) 4 | -------------------------------------------------------------------------------- /Research/yuml_python/yuml_order_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/yuml_python/yuml_order_example.png -------------------------------------------------------------------------------- /Research/yuml_python/yuml_pynsource1_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/yuml_python/yuml_pynsource1_example.png -------------------------------------------------------------------------------- /Research/yuml_python/yuml_pynsource2_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/yuml_python/yuml_pynsource2_example.png -------------------------------------------------------------------------------- /Research/yuml_python/yuml_pynsource3_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/Research/yuml_python/yuml_pynsource3_example.png -------------------------------------------------------------------------------- /bin/_buildmedia.sh: -------------------------------------------------------------------------------- 1 | python3 -m wx.tools.img2py src/media/pro.png src/media/images.py 2 | #python3 -m wx.tools.img2py src/media/pro_01.png src/media/images.py 3 | #python3 -m wx.tools.img2py -a src/media/pro_02.png src/media/images.py 4 | #python3 -m wx.tools.img2py -a src/media/iconfinder-pro.png src/media/images.py 5 | #python3 -m wx.tools.img2py -a src/media/pro_03.png src/media/images.py 6 | #python3 -m wx.tools.img2py -a src/media/pro_04.png src/media/images.py 7 | -------------------------------------------------------------------------------- /bin/_buildsamples.py: -------------------------------------------------------------------------------- 1 | """ 2 | Takes all the files in the samples directory and converts them into a 3 | dictionary resource, with the file contentes encoded in base64. 4 | """ 5 | 6 | import os, glob 7 | from base64 import b64encode 8 | import collections 9 | 10 | ORDERED = True 11 | 12 | samplesdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "src", "samples") 13 | allfiles = glob.glob(os.path.join(samplesdir, "*.pyns")) 14 | 15 | samples = {} 16 | for file in allfiles: 17 | with open(os.path.join(samplesdir, file), "r") as f: 18 | samples[os.path.basename(file)] = b64encode(f.read().encode("utf-8")) 19 | 20 | OUTFILE = os.path.join(samplesdir, "files_as_resource.py") 21 | 22 | if not ORDERED: 23 | with open(OUTFILE, "w") as f: 24 | f.write("sample_files_dict = ") 25 | f.write(repr(samples)) 26 | else: 27 | # od = collections.OrderedDict(samples.items()) 28 | od = collections.OrderedDict() 29 | for key in sorted(samples.keys()): 30 | od[key] = samples[key] 31 | 32 | with open(OUTFILE, "w") as f: 33 | f.write("from collections import OrderedDict\n") # allow file to be valid python 34 | f.write("sample_files_dict = ") 35 | f.write(repr(od)) 36 | 37 | print("done generating sample uml diagram file resource dictionary.") 38 | -------------------------------------------------------------------------------- /bin/blackall: -------------------------------------------------------------------------------- 1 | black -l 100 src bin/buildsamples.py 2 | 3 | -------------------------------------------------------------------------------- /bin/build-package: -------------------------------------------------------------------------------- 1 | python3 setup.py sdist 2 | #python3 setup.py sdist bdist_wheel 3 | 4 | echo Andy Tip: install in dev mode with 5 | echo " pip install -e ." 6 | echo uninstall with 7 | echo " pip uninstall pynsource" 8 | -------------------------------------------------------------------------------- /bin/build-snap: -------------------------------------------------------------------------------- 1 | snapcraft --use-lxd 2 | -------------------------------------------------------------------------------- /bin/build-snap-clean: -------------------------------------------------------------------------------- 1 | rm *.snap 2 | snapcraft clean --use-lxd 3 | snapcraft --use-lxd -------------------------------------------------------------------------------- /bin/build-snap-clean-python-stuff: -------------------------------------------------------------------------------- 1 | snapcraft clean build-the-python-stuff-please --use-lxd 2 | -------------------------------------------------------------------------------- /bin/build-snap-debug: -------------------------------------------------------------------------------- 1 | #snapcraft --use-lxd 2 | snapcraft --use-lxd --debug 3 | -------------------------------------------------------------------------------- /bin/buildmac: -------------------------------------------------------------------------------- 1 | ../ogl2/bin/buildmac.sh 2 | -------------------------------------------------------------------------------- /bin/buildwin.bat: -------------------------------------------------------------------------------- 1 | cmd /c ..\ogl2\bin\buildwin.bat -------------------------------------------------------------------------------- /bin/install-linux-18.04: -------------------------------------------------------------------------------- 1 | # Install script for installing Pynsource dependencies, run this from root of Pynsource project e.g. bin/install-linux-nn.nn 2 | echo for Ubuntu 18.04 3 | pip3 install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 wxPython 4 | pip3 install wxasync --no-dependencies 5 | pip3 install -r .requirement-extras/requirements-linux-common.txt 6 | sudo apt-get install git curl libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0 7 | -------------------------------------------------------------------------------- /bin/install-linux-20.04: -------------------------------------------------------------------------------- 1 | # Install script for installing Pynsource dependencies, run this from root of Pynsource project e.g. bin/install-linux-nn.nn 2 | echo for Ubuntu 20.04 3 | pip3 install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04 wxPython 4 | pip3 install wxasync --no-dependencies 5 | pip3 install -r .requirement-extras/requirements-linux-common.txt 6 | sudo apt-get install git curl libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0 7 | -------------------------------------------------------------------------------- /bin/install-linux-fedora-33: -------------------------------------------------------------------------------- 1 | # Install script for installing Pynsource dependencies, run this from root of Pynsource project e.g. bin/install-linux-nn.nn 2 | echo for Fedora 33 and wxPython for Fedora 31 (latest I could find) and Python 3.8 3 | pip3 install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/fedora-31 wxPython 4 | pip3 install wxasync --no-dependencies 5 | pip3 install -r .requirement-extras/requirements-linux-common.txt 6 | sudo dnf install SDL-devel 7 | 8 | -------------------------------------------------------------------------------- /bin/install-snap: -------------------------------------------------------------------------------- 1 | # sudo snap install --devmode --dangerous snap-py-simple_1.0_multi.snap 2 | sudo snap install --devmode --dangerous *.snap 3 | snap list 4 | -------------------------------------------------------------------------------- /bin/lxd-containers-ls: -------------------------------------------------------------------------------- 1 | lxc ls 2 | -------------------------------------------------------------------------------- /bin/lxd-shell: -------------------------------------------------------------------------------- 1 | echo you may need to 2 | echo lxc start snapcraft-pynsource 3 | lxc exec snapcraft-pynsource -- /bin/bash 4 | -------------------------------------------------------------------------------- /bin/pip-install-ogl2-alsm-rego: -------------------------------------------------------------------------------- 1 | pip install ../alsm-parsers/alsm/ 2 | pip install ../ogl2 3 | pip install ../pynsource-rego 4 | -------------------------------------------------------------------------------- /bin/pkill_python.command: -------------------------------------------------------------------------------- 1 | #pkill Python 2 | pkill Pynsource 3 | -------------------------------------------------------------------------------- /bin/publish-snap: -------------------------------------------------------------------------------- 1 | snapcraft upload *.snap --release edge 2 | -------------------------------------------------------------------------------- /bin/r: -------------------------------------------------------------------------------- 1 | ../ogl2/bin/r.sh 2 | -------------------------------------------------------------------------------- /bin/run: -------------------------------------------------------------------------------- 1 | cd src 2 | PYTHON=python3 3 | $PYTHON pynsource_gui.py 4 | -------------------------------------------------------------------------------- /bin/run-py37: -------------------------------------------------------------------------------- 1 | cd src 2 | PYTHON=/Users/andy/.pyenv/versions/3.7.5/bin/python 3 | $PYTHON pynsource-gui.py 4 | -------------------------------------------------------------------------------- /bin/run-py38: -------------------------------------------------------------------------------- 1 | cd src 2 | PYTHON=/Users/andy/.pyenv/versions/3.8.6/bin/python 3 | $PYTHON pynsource-gui.py 4 | -------------------------------------------------------------------------------- /bin/run-snap: -------------------------------------------------------------------------------- 1 | pynsource -------------------------------------------------------------------------------- /bin/run-snap-with-shell: -------------------------------------------------------------------------------- 1 | snap run --shell pynsource 2 | -------------------------------------------------------------------------------- /bin/run-win10.bat: -------------------------------------------------------------------------------- 1 | setlocal 2 | cd src 3 | python pynsource-gui.py 4 | endlocal 5 | -------------------------------------------------------------------------------- /bin/runpro: -------------------------------------------------------------------------------- 1 | # Mac 2 | echo "PRIVATE: This script is only used by the author Andy Bulka for development of the PRO version of pynsource - Macbook version." 3 | cd src 4 | PYTHON=python3 5 | PYTHONPATH="/Users/andy/Devel/ogl2/:/Users/andy/Devel/pynsource-rego/" $PYTHON pynsource_gui.py -------------------------------------------------------------------------------- /bin/runpro-imac: -------------------------------------------------------------------------------- 1 | # Mac 2 | echo "PRIVATE: This script is only used by the author Andy Bulka for development of the PRO version of pynsource - iMac version." 3 | cd src 4 | PYTHONPATH="/Volumes/SSD/Users/andy/Devel/ogl2/:/Volumes/SSD/Users/andy/Devel/pynsource-rego/" python pynsource-gui.py 5 | -------------------------------------------------------------------------------- /bin/runpro-linux: -------------------------------------------------------------------------------- 1 | # Linux 2 | echo "PRIVATE: This script is only used by the author Andy Bulka for development of the PRO version of pynsource." 3 | 4 | cd src 5 | 6 | #PYTHON=python 7 | PYTHON=python3 8 | # PYTHON=/usr/local/bin/python3 9 | # PYTHON=/usr/local/Cellar/python/3.7.0/bin/python3 10 | #PYTHON=/usr/local/Cellar/python/3.7.2/bin/python3 11 | 12 | PYTHONPATH="/home/andy/Devel/ogl2/:/home/andy/Devel/pynsource-rego/" $PYTHON pynsource-gui.py 13 | -------------------------------------------------------------------------------- /bin/runpro-py37: -------------------------------------------------------------------------------- 1 | # Mac, development - adjust to your environment 2 | echo "PRIVATE: This script is only used by the author Andy Bulka for development of the PRO version of pynsource - Macbook version." 3 | cd src 4 | PYTHON=/Users/andy/.pyenv/versions/3.7.5/bin/python 5 | PYTHONPATH="/Users/andy/Devel/ogl2/:/Users/andy/Devel/pynsource-rego/" $PYTHON pynsource-gui.py 6 | -------------------------------------------------------------------------------- /bin/runpro-py38: -------------------------------------------------------------------------------- 1 | # Mac, development - adjust to your environment 2 | echo "PRIVATE: This script is only used by the author Andy Bulka for development of the PRO version of pynsource - Macbook version." 3 | cd src 4 | PYTHON=/Users/andy/.pyenv/versions/3.8.6/bin/python 5 | PYTHONPATH="/Users/andy/Devel/ogl2/:/Users/andy/Devel/pynsource-rego/" $PYTHON pynsource-gui.py 6 | -------------------------------------------------------------------------------- /bin/runpro-win10.bat: -------------------------------------------------------------------------------- 1 | setlocal 2 | echo "PRIVATE: This script is only used by the author Andy Bulka for development of the PRO version of pynsource." 3 | cd src 4 | REM set PYTHONPATH=\Users\Andy\ogl2;\Users\Andy\pynsource-rego 5 | set PYTHONPATH=\Users\Andy\Devel\ogl2;\Users\Andy\Devel\pynsource-rego 6 | rem exit /b 7 | python pynsource-gui.py 8 | endlocal 9 | -------------------------------------------------------------------------------- /bin/snap-bash-multipass: -------------------------------------------------------------------------------- 1 | echo 2 | echo after getting the prompt, type 3 | echo 4 | echo sudo bash 5 | echo cd /root/prime 6 | echo 7 | echo 8 | multipass shell snapcraft-pynsource 9 | echo 10 | echo 11 | echo shutting the session or you will get snapcraft build errors 12 | echo 13 | multipass stop snapcraft-pynsource 14 | echo ok -------------------------------------------------------------------------------- /bin/snap-build-multipass: -------------------------------------------------------------------------------- 1 | time snapcraft --debug 2 | -------------------------------------------------------------------------------- /bin/snap-deploy: -------------------------------------------------------------------------------- 1 | snapcraft push *.snap 2 | echo look at the number returned e.g. 2 3 | echo then run 4 | echo snapcraft release pynsource 2 stable -------------------------------------------------------------------------------- /bin/snap-expand-extensions: -------------------------------------------------------------------------------- 1 | snapcraft expand-extensions 2 | -------------------------------------------------------------------------------- /bin/snap-install: -------------------------------------------------------------------------------- 1 | sudo snap install --devmode --dangerous *.snap 2 | -------------------------------------------------------------------------------- /bin/snap-ls: -------------------------------------------------------------------------------- 1 | unsquashfs -l *.snap|less 2 | -------------------------------------------------------------------------------- /bin/snap-stopvm-multipass: -------------------------------------------------------------------------------- 1 | echo shutting the session or you will get snapcraft build errors 2 | echo 3 | multipass stop snapcraft-pynsource 4 | echo ok -------------------------------------------------------------------------------- /bin/snap-tree: -------------------------------------------------------------------------------- 1 | tree /snap/pynsource/current 2 | -------------------------------------------------------------------------------- /bin/testall: -------------------------------------------------------------------------------- 1 | # cd src 2 | # bin/testall 3 | 4 | mkdir -p src/tests/logs 5 | 6 | # avoid wx by setting the TRAVIS env var, which happens automatically on travis and 7 | # is set explicitly in .github/workflows/pythonapp.yml 8 | export TRAVIS=1 9 | 10 | # pick a version of python to run the tests with, useful when testing 3.8 parsing 11 | # cos just python3 may not pick up the right version, even if pyenv local is set ok 12 | PYTHON=python3 13 | #PYTHON=/Users/andy/.pyenv/versions/3.8.6/bin/python 14 | #PYTHON=/Users/andy/.pyenv/versions/3.7.5/bin/python 15 | 16 | $PYTHON --version 17 | $PYTHON -m unittest discover -v -s src 18 | -------------------------------------------------------------------------------- /bin/testall-win10.bat: -------------------------------------------------------------------------------- 1 | cd src 2 | REM mkdir -p tests/logs 3 | if not exist "tests/logs" mkdir "tests/logs" 4 | 5 | REM avoid wx by setting the TRAVIS env var, which happens automatically on travis and 6 | REM is set explicitly in .github/workflows/pythonapp.yml 7 | set TRAVIS=1 8 | call python -m unittest discover -v -s tests 9 | if %ERRORLEVEL% neq 0 goto ProcessError 10 | 11 | :ProcessError 12 | cd .. -------------------------------------------------------------------------------- /bin/testone: -------------------------------------------------------------------------------- 1 | #cd src 2 | #python -m unittest tests.test_parse_bugs_incoming.TestIncomingBugs.test_issue_subscript_issue_93 3 | #python -m unittest tests.test_parse_type_annotations.TestTypeHintsOnFunctionArguments 4 | 5 | python -m unittest discover -v -s src -k TestTypeHintsOnFunctionArguments 6 | -------------------------------------------------------------------------------- /bin/uninstall-snap: -------------------------------------------------------------------------------- 1 | sudo snap remove pynsource 2 | snap list 3 | -------------------------------------------------------------------------------- /bin/viewconfig: -------------------------------------------------------------------------------- 1 | echo /Users/Andy/Library/Preferences/Pynsource/pynsource.ini 2 | less /Users/Andy/Library/Preferences/Pynsource/pynsource.ini 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # linux users please use the script bin/install-linux-* and not this file 2 | configobj 3 | requests 4 | typed_ast 5 | astpretty 6 | termcolor 7 | beautifultable 8 | appdirs 9 | 10 | # wheel needed when running pip install ../alsm-parsers/alsm/ 11 | # also needed for installing pydbg which is a rust based print debugger thing 12 | wheel 13 | 14 | pydbg 15 | aiohttp 16 | async_lru 17 | 18 | Pillow 19 | # py2app - uses fcntl module which is not available on Windows - https://stackoverflow.com/questions/73272911/lux-api-package-installation-python 20 | click 21 | pytest 22 | coverage 23 | pytest-cov 24 | 25 | wxpython 26 | wxasync 27 | -------------------------------------------------------------------------------- /snap/gui/pynsource.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Pynsource 3 | GenericName=UML application 4 | Comment=Pynsource UML reverse engineer Python source into diagrams 5 | Exec=pynsource 6 | Icon=${SNAP}/meta/gui/pynsource.png 7 | Terminal=false 8 | Type=Application 9 | Categories=Development; 10 | StartupNotify=true 11 | -------------------------------------------------------------------------------- /snap/gui/pynsource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/snap/gui/pynsource.png -------------------------------------------------------------------------------- /snap/local/andy-diagnostics/report_snap_env.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | try: 3 | import wx 4 | except: 5 | print("can't import wx") 6 | else: 7 | print("import wx succeeded OK") 8 | 9 | print("sys.path") 10 | print(sys.path) 11 | print() 12 | 13 | print("\n".join(sys.path)) 14 | print() 15 | 16 | print("os.getcwd()") 17 | print(os.getcwd()) 18 | print() 19 | 20 | print("os.listdir()") 21 | print(os.listdir()) 22 | print() 23 | 24 | -------------------------------------------------------------------------------- /src/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = 3 | . 4 | omit = 5 | tests/* 6 | */__init__.py 7 | 8 | -------------------------------------------------------------------------------- /src/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/app/__init__.py -------------------------------------------------------------------------------- /src/app/cmds/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["deletion", "insertion"] 2 | -------------------------------------------------------------------------------- /src/app/cmds/base_cmd.py: -------------------------------------------------------------------------------- 1 | from common.command_pattern import Command 2 | 3 | 4 | class CmdBase(Command): 5 | """ Base command """ 6 | 7 | def execute(self): 8 | raise Exception("virtual, not implemented") 9 | 10 | def undo(self): 11 | raise Exception("virtual, not implemented") 12 | 13 | def redo(self): 14 | """ redoes the command. Usually as simple as re executing it. """ 15 | self.execute() 16 | -------------------------------------------------------------------------------- /src/app/cmds/deletion.py: -------------------------------------------------------------------------------- 1 | from .base_cmd import CmdBase 2 | 3 | # Cannot multi-select nodes at present. 4 | 5 | 6 | class CmdNodeDeleteBase(CmdBase): 7 | def delete_shape(self, shape): 8 | displaymodel = self.context.displaymodel 9 | gui = self.context.umlcanvas 10 | 11 | # Currently images are not nodes, just shapes, so skip deleting the node 12 | if shape.GetShape().__class__.__name__ != "BitmapShapeResizable": 13 | displaymodel.delete_node_or_edge_for_shape(shape) 14 | 15 | gui.delete_shape_view(shape) 16 | 17 | self.context.umlcanvas.extra_refresh() 18 | self.context.umlcanvas.Refresh() # needed for ogltwo 19 | # self.context.wxapp.RefreshAsciiUmlTab() 20 | 21 | 22 | class CmdNodeDelete(CmdNodeDeleteBase): 23 | """ Delete specific shape/node. """ 24 | 25 | def __init__(self, shape): 26 | self.shape = shape 27 | 28 | def execute(self): 29 | """ Delete specific shape/node. """ 30 | self.delete_shape(self.shape) 31 | 32 | 33 | class CmdNodeDeleteSelected(CmdNodeDeleteBase): 34 | """ Delete selected node """ 35 | 36 | def execute(self): 37 | """ Delete selected node. """ 38 | selected = [s for s in self.context.umlcanvas.GetDiagram().GetShapeList() if s.Selected()] 39 | if selected: 40 | shape = selected[0] 41 | self.delete_shape(shape) 42 | -------------------------------------------------------------------------------- /src/app/cmds/selection.py: -------------------------------------------------------------------------------- 1 | from .base_cmd import CmdBase 2 | import wx 3 | from gui.settings import PRO_EDITION 4 | 5 | class CmdDeselectAllShapes(CmdBase): 6 | def execute(self): 7 | if PRO_EDITION: 8 | self.context.umlcanvas.deselect() 9 | return 10 | 11 | selected = [s for s in self.context.umlcanvas.GetDiagram().GetShapeList() if s.Selected()] 12 | if selected: 13 | assert len(selected) == 1 14 | s = selected[0] 15 | canvas = s.GetCanvas() 16 | 17 | dc = wx.ClientDC(canvas) 18 | canvas.PrepareDC(dc) 19 | s.Select(False, dc) 20 | canvas.Refresh(False) # Need this or else Control points ('handles') leave blank holes 21 | 22 | def undo(self): # override 23 | """ Docstring """ 24 | # not implemented 25 | -------------------------------------------------------------------------------- /src/app/settings.py: -------------------------------------------------------------------------------- 1 | import wx.lib.newevent 2 | 3 | ASYNC = True 4 | 5 | RefreshPlantUmlEvent, EVT_REFRESH_PLANTUML_EVENT = wx.lib.newevent.NewEvent() 6 | CancelRefreshPlantUmlEvent, EVT_CANCEL_REFRESH_PLANTUML_EVENT = wx.lib.newevent.NewEvent() 7 | -------------------------------------------------------------------------------- /src/ascii_uml/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/ascii_uml/__init__.py -------------------------------------------------------------------------------- /src/bin/covergui: -------------------------------------------------------------------------------- 1 | coverage erase 2 | coverage run pynsource_gui.py 3 | coverage html 4 | open htmlcov/index.html 5 | 6 | -------------------------------------------------------------------------------- /src/bin/covertests: -------------------------------------------------------------------------------- 1 | pytest --cov=. tests/ 2 | coverage html 3 | open htmlcov/index.html 4 | -------------------------------------------------------------------------------- /src/bin/testcli: -------------------------------------------------------------------------------- 1 | #J=tests/testing-generate-java 2 | #D=tests/testing-generate-delphi 3 | #python pynsource.py -j $J/java-out $J/python-in/*.py 4 | #python pynsource.py -d $D/delphi-out $D/python-in/*.py 5 | 6 | python3 pynsource-cli.py --prop-decorator --graph gui/uml_canvas.py layout/blackboard.py view/*.py 7 | -------------------------------------------------------------------------------- /src/bin/testsingle: -------------------------------------------------------------------------------- 1 | python3 -m unittest tests.test_graph_nodes.TestCase_A.test_8_multiple_inhertitance_render -v 2 | -------------------------------------------------------------------------------- /src/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/common/__init__.py -------------------------------------------------------------------------------- /src/common/add_line_numbers.py: -------------------------------------------------------------------------------- 1 | def add_line_numbers(s): 2 | result = "" 3 | for (number, line) in enumerate(s.split("\n")): 4 | result += "%3d %s\n" % (number + 1, line) 5 | return result 6 | -------------------------------------------------------------------------------- /src/common/url_to_data.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import aiohttp 3 | from async_lru import alru_cache 4 | 5 | @alru_cache(maxsize=32) 6 | async def url_to_data(url): 7 | 8 | # await asyncio.sleep(5) 9 | 10 | timeout = aiohttp.ClientTimeout(total=60) 11 | async with aiohttp.ClientSession(timeout=timeout) as session: 12 | async with session.get(url) as response: 13 | return await response.read(), response.status 14 | -------------------------------------------------------------------------------- /src/dialogs/DialogChooseFromList_run.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import random 3 | from .DialogChooseFromList import MyDialogChooseFromList 4 | 5 | test_data = ["test a", "test aa", "test aab", "test ab", "test abc", "test abcc", "test abcd"] 6 | 7 | 8 | class MyDialog(MyDialogChooseFromList): 9 | def SetMyData(self, data): 10 | self.data = data 11 | self.m_listBox1.InsertItems(data, 0) 12 | 13 | def OnListDoubleClick(self, event): 14 | print(self.GetChosenItem()) 15 | # self.Destroy() 16 | self.Close() 17 | 18 | def GetChosenItem(self): 19 | index = self.m_listBox1.GetSelection() 20 | return self.data[index] 21 | 22 | 23 | class TestApp(wx.Frame): 24 | def __init__(self, *args, **kwargs): 25 | super(TestApp, self).__init__(*args, **kwargs) 26 | self.InitUI() 27 | 28 | def InitUI(self): 29 | self.SetSize((300, 200)) 30 | self.SetTitle("Andy's Custom dialog tester") 31 | self.Centre() 32 | self.Show(True) 33 | self.MAIN() 34 | 35 | def MAIN(self): 36 | dialog = MyDialog(None) 37 | dialog.m_staticTextInstruction.Value = "Please Choose:" 38 | dialog.SetMyData(test_data) 39 | 40 | if dialog.ShowModal() == wx.ID_OK: 41 | print(dialog.GetChosenItem()) 42 | # wx.MessageBox("Got the following\n%s\n%s\n%s" % (id, attrs, methods)) 43 | 44 | dialog.Destroy() 45 | 46 | 47 | def main(): 48 | ex = wx.App() 49 | TestApp(None) 50 | ex.MainLoop() 51 | 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /src/dialogs/DialogRego_run.py: -------------------------------------------------------------------------------- 1 | import wx 2 | from DialogRego import RegoDialog 3 | 4 | 5 | class TestApp(wx.Frame): 6 | def __init__(self, *args, **kwargs): 7 | super(TestApp, self).__init__(*args, **kwargs) 8 | self.InitUI() 9 | 10 | def InitUI(self): 11 | self.SetSize((300, 200)) 12 | self.SetTitle("Andy's Custom dialog tester") 13 | self.Centre() 14 | self.Show(True) 15 | self.MAIN() 16 | 17 | def MAIN(self): 18 | dialog = RegoDialog(None) 19 | dialog.m_textCtrl_name.Value = "" 20 | dialog.m_textCtrl_serial.Value = "" 21 | 22 | if dialog.ShowModal() == wx.ID_OK: 23 | name = dialog.m_textCtrl_name.Value 24 | serial = dialog.m_textCtrl_serial.Value 25 | 26 | wx.MessageBox(f"Got the following\n{name}\n{serial}") 27 | dialog.Destroy() 28 | 29 | 30 | def main(): 31 | ex = wx.App() 32 | TestApp(None) 33 | ex.MainLoop() 34 | 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /src/dialogs/DialogUmlNodeEdit_run.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import random 3 | from .DialogUmlNodeEdit import DialogUmlNodeEdit 4 | 5 | 6 | class TestApp(wx.Frame): 7 | def __init__(self, *args, **kwargs): 8 | super(TestApp, self).__init__(*args, **kwargs) 9 | self.InitUI() 10 | 11 | def InitUI(self): 12 | self.SetSize((300, 200)) 13 | self.SetTitle("Andy's Custom dialog tester") 14 | self.Centre() 15 | self.Show(True) 16 | self.MAIN() 17 | 18 | def MAIN(self): 19 | id = "D" + str(random.randint(1, 99)) 20 | dialog = DialogUmlNodeEdit(None) 21 | dialog.txtClassName.Value = id 22 | dialog.txtAttrs.Value = "aa\nbb\nccc" 23 | 24 | if dialog.ShowModal() == wx.ID_OK: 25 | id = dialog.txtClassName.Value 26 | attrs = dialog.txtAttrs.Value.split("\n") 27 | methods = dialog.txtMethods.Value.split("\n") 28 | 29 | wx.MessageBox("Got the following\n%s\n%s\n%s" % (id, attrs, methods)) 30 | dialog.Destroy() 31 | 32 | 33 | def main(): 34 | ex = wx.App() 35 | TestApp(None) 36 | ex.MainLoop() 37 | 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /src/dialogs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/__init__.py -------------------------------------------------------------------------------- /src/dialogs/help-images/cytoscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/cytoscape.png -------------------------------------------------------------------------------- /src/dialogs/help-images/gituml.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/gituml.jpg -------------------------------------------------------------------------------- /src/dialogs/help-images/help-ascii.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/help-ascii.jpg -------------------------------------------------------------------------------- /src/dialogs/help-images/help-colour.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/help-colour.jpg -------------------------------------------------------------------------------- /src/dialogs/help-images/help01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/help01.jpg -------------------------------------------------------------------------------- /src/dialogs/help-images/plantuml01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/plantuml01.jpg -------------------------------------------------------------------------------- /src/dialogs/help-images/pro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/dialogs/help-images/pro.jpg -------------------------------------------------------------------------------- /src/gui/__init__.py: -------------------------------------------------------------------------------- 1 | # just to make a package.... 2 | 3 | # although... 4 | 5 | # pynsource maybe shouldn't be treated as a package 6 | # (and nor installed by the root ..\setup.py) as a package into \PythonXX\Lib\site-packages\pynsource 7 | # Currently its more a utility script 8 | # though maybe I can tweak it a bit so its drivable like a more hard core package 9 | # in the future. 10 | -------------------------------------------------------------------------------- /src/gui/node_edit_multi_purpose.py: -------------------------------------------------------------------------------- 1 | from gui.uml_shapes import CommentShape 2 | from typing import List, Set, Dict, Tuple, Optional 3 | 4 | 5 | def node_edit_multi_purpose(shape, app): 6 | """ 7 | Edit a uml class node or a comment node 8 | 9 | Main menu calls this from pynsourcegui or 10 | Or uml shape handler (above) calls this when right click on a shape 11 | 12 | Args: 13 | shape: 14 | app: 15 | 16 | Returns: - 17 | 18 | """ 19 | # node is a regular node, its the node.shape that is different for a comment 20 | from gui.uml_shapes import DividedShape 21 | 22 | if isinstance(shape, DividedShape): 23 | app.run.CmdEditUmlClass(shape) 24 | elif isinstance(shape, CommentShape): 25 | app.run.CmdEditComment(shape) 26 | else: 27 | print("Unknown Shape", shape) 28 | -------------------------------------------------------------------------------- /src/gui/settings_wx.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | if "wxMac" in wx.PlatformInfo: 4 | DEFAULT_COMMENT_FONT_SIZE = 14 5 | DEFAULT_CLASS_HEADING_FONT_SIZE = 14 6 | DEFAULT_CLASS_ATTRS_METHS_FONT_SIZE = 10 7 | DEFAULT_ASCII_UML_FONT_SIZE = 14 8 | elif "wxGTK" in wx.PlatformInfo: 9 | DEFAULT_COMMENT_FONT_SIZE = 10 10 | DEFAULT_CLASS_HEADING_FONT_SIZE = 12 11 | DEFAULT_CLASS_ATTRS_METHS_FONT_SIZE = 9 12 | DEFAULT_ASCII_UML_FONT_SIZE = 10 13 | else: # windows 14 | DEFAULT_COMMENT_FONT_SIZE = 10 15 | DEFAULT_CLASS_HEADING_FONT_SIZE = 12 16 | DEFAULT_CLASS_ATTRS_METHS_FONT_SIZE = 10 17 | DEFAULT_ASCII_UML_FONT_SIZE = 10 18 | -------------------------------------------------------------------------------- /src/gui/wx_log.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | 4 | class Log: 5 | def WriteText(self, text): 6 | if text[-1:] == "\n": 7 | text = text[:-1] 8 | wx.LogMessage(text) 9 | 10 | write = WriteText 11 | -------------------------------------------------------------------------------- /src/layout/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/layout/__init__.py -------------------------------------------------------------------------------- /src/layout/animation.py: -------------------------------------------------------------------------------- 1 | # animated easing algorithm 2 | # Adapted from http://www.hesido.com/web.php?page=javascriptanimation 3 | 4 | import math 5 | 6 | 7 | def easeInOut(minValue, maxValue, totalSteps, actualStep, powr): 8 | delta = maxValue - minValue 9 | stepp = minValue + (math.pow(((1.0 / totalSteps) * actualStep), powr) * delta) 10 | return math.ceil(stepp) 11 | 12 | 13 | def doValChangeMem(startval, endval, steps, intervals_failsafe=200, powr=0.35): 14 | result = [] 15 | actStep = 0 16 | for i in range(intervals_failsafe): 17 | val = easeInOut(startval, endval, steps, actStep, powr) 18 | result.append(int(val)) 19 | actStep += 1 20 | if actStep > steps: 21 | break 22 | return result 23 | 24 | 25 | def GeneratePoints(point1, point2, steps=8): 26 | X, Y = 0, 1 27 | xs = doValChangeMem(startval=point1[X], endval=point2[X], steps=steps) 28 | ys = doValChangeMem(startval=point1[Y], endval=point2[Y], steps=steps) 29 | return list(zip(xs, ys)) 30 | 31 | 32 | if __name__ == "__main__": 33 | print(GeneratePoints((0, 0), (10, 10))) 34 | print(GeneratePoints((10, 0), (100, 10))) 35 | 36 | print("Done") 37 | -------------------------------------------------------------------------------- /src/layout/line_intersection.py: -------------------------------------------------------------------------------- 1 | # line_intersection 2 | 3 | 4 | def FindLineIntersection(start1, end1, start2, end2): # all are point tuples 5 | # Adapted from http://stackoverflow.com/questions/1119451/how-to-tell-if-a-line-intersects-a-polygon-in-c 6 | 7 | X, Y = 0, 1 8 | start1, end1, start2, end2 = ( 9 | (float(start1[X]), float(start1[Y])), 10 | (float(end1[X]), float(end1[Y])), 11 | (float(start2[X]), float(start2[Y])), 12 | (float(end2[X]), float(end2[Y])), 13 | ) 14 | 15 | denom = ((end1[X] - start1[X]) * (end2[Y] - start2[Y])) - ( 16 | (end1[Y] - start1[Y]) * (end2[X] - start2[X]) 17 | ) 18 | 19 | # AB & CD are parallel 20 | if denom == 0: 21 | return None 22 | 23 | numer = ((start1[Y] - start2[Y]) * (end2[X] - start2[X])) - ( 24 | (start1[X] - start2[X]) * (end2[Y] - start2[Y]) 25 | ) 26 | r = numer / denom 27 | numer2 = ((start1[Y] - start2[Y]) * (end1[X] - start1[X])) - ( 28 | (start1[X] - start2[X]) * (end1[Y] - start1[Y]) 29 | ) 30 | s = numer2 / denom 31 | if (r < 0 or r > 1) or (s < 0 or s > 1): 32 | return None 33 | 34 | # Find intersection point 35 | result = [0, 0] 36 | result[0] = start1[X] + (r * (end1[X] - start1[X])) 37 | result[1] = start1[Y] + (r * (end1[Y] - start1[Y])) 38 | 39 | return result 40 | -------------------------------------------------------------------------------- /src/layout/permutations.py: -------------------------------------------------------------------------------- 1 | # permutations 2 | 3 | 4 | def getpermutations(lzt): 5 | result = [] 6 | for i in range(0, len(lzt)): 7 | for j in range(i + 1, len(lzt)): 8 | result.append((lzt[i], lzt[j])) 9 | return result 10 | 11 | 12 | if __name__ == "__main__": 13 | print(getpermutations(["a"])) 14 | print(getpermutations(["a", "b"])) 15 | print(getpermutations(["a", "b", "c", "d"])) 16 | print(getpermutations(["a", "b", "c", "d", "e"])) 17 | -------------------------------------------------------------------------------- /src/media/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/media/about.png -------------------------------------------------------------------------------- /src/media/pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/media/pro.png -------------------------------------------------------------------------------- /src/media/pynsource.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/media/pynsource.ico -------------------------------------------------------------------------------- /src/media/pynsource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/media/pynsource.png -------------------------------------------------------------------------------- /src/ogl/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | The Object Graphics Library provides for simple drawing and manipulation 3 | of 2D objects. 4 | """ 5 | 6 | from .basic import * 7 | from .diagram import * 8 | from .canvas import * 9 | from .lines import * 10 | from .bmpshape import * 11 | from .divided import * 12 | from .composit import * 13 | from .drawn import * 14 | -------------------------------------------------------------------------------- /src/parsing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/parsing/__init__.py -------------------------------------------------------------------------------- /src/parsing/alsm_set_module.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | import re 3 | 4 | 5 | def get_source_code_sample(filename): 6 | with open(filename) as f: 7 | source_code = f.read(40) # just 12 chars 8 | source_code = re.sub( 9 | "\s+", " ", source_code 10 | ).strip() # get rid of newlines and multiple spaces 11 | source_code += " ..." 12 | return source_code 13 | -------------------------------------------------------------------------------- /src/parsing/api.py: -------------------------------------------------------------------------------- 1 | from parsing.core_parser_old import PynsourcePythonParser 2 | from parsing.core_parser_ast import parse 3 | from common.logwriter import LogWriterNull 4 | 5 | 6 | def old_parser(filename, options={}): 7 | p = PynsourcePythonParser() 8 | p.optionModuleAsClass = options.get("optionModuleAsClass", False) 9 | p.Parse(filename) 10 | return p, "" 11 | 12 | 13 | def new_parser(filename, log=None, options={}): 14 | if not log: 15 | log = LogWriterNull() 16 | pmodel, debuginfo = parse(filename, log, options) 17 | return pmodel, debuginfo 18 | -------------------------------------------------------------------------------- /src/samples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/samples/__init__.py -------------------------------------------------------------------------------- /src/samples/composition relationship.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.2 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin. Comments are saved.'} 3 | {'type':'umlshape', 'id':'Editor', 'x':36, 'y':19, 'width':70, 'height':104, 'attrs': 'topHandler|GUI|statechart', 'meths': '__init__|start'} 4 | {'type':'umlshape', 'id':'TopHandler', 'x':221, 'y':72, 'width':94, 'height':24, 'attrs': '', 'meths': ''} 5 | {'type':'umlshape', 'id':'GUI', 'x':185, 'y':20, 'width':35, 'height':24, 'attrs': '', 'meths': ''} 6 | {'type':'umlshape', 'id':'Statechart', 'x':189, 'y':126, 'width':94, 'height':24, 'attrs': '', 'meths': ''} 7 | {'type':'comment', 'id':'C8309', 'x':353, 'y':19, 'width':339, 'height':47, 'comment': 'VGhlIEVkaXRvciBjbGFzcyBoYXMgdGhyZWUgYXR0cmlidXRlcwp3aGljaCBwb2ludCB0byB0aHJlZSBvdGhlciBjbGFzc2VzLg=='} 8 | {'type':'edge', 'id':'TopHandler_to_Editor', 'source':'TopHandler', 'target':'Editor', 'uml_edge_type': 'composition'} 9 | {'type':'edge', 'id':'GUI_to_Editor', 'source':'GUI', 'target':'Editor', 'uml_edge_type': 'composition'} 10 | {'type':'edge', 'id':'Statechart_to_Editor', 'source':'Statechart', 'target':'Editor', 'uml_edge_type': 'composition'} 11 | -------------------------------------------------------------------------------- /src/samples/nice diagram with comment.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.2 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin. Comments are saved.'} 3 | {'type':'umlshape', 'id':'CmdLinePythonToAsciiArt', 'x':11, 'y':126, 'width':203, 'height':104, 'attrs': 'p', 'meths': '_GenerateAuxilliaryClasses|_CreateParser|_Process|ExportTo'} 4 | {'type':'umlshape', 'id':'PySourceAsText', 'x':288, 'y':119, 'width':202, 'height':114, 'attrs': '', 'meths': '__init__|_DumpAttribute|_DumpCompositeExtraFooter|_DumpClassNameAndGeneralisations|_DumpMethods|_Line|_DumpClassFooter'} 5 | {'type':'umlshape', 'id':'CmdLineGenerator', 'x':40, 'y':15, 'width':144, 'height':24, 'attrs': '', 'meths': ''} 6 | {'type':'umlshape', 'id':'ReportGenerator', 'x':301, 'y':14, 'width':136, 'height':24, 'attrs': '', 'meths': ''} 7 | {'type':'comment', 'id':'C6267', 'x':547, 'y':31, 'width':350, 'height':132, 'comment': 'VHdvIGdlbmVyYWxpc2F0aW9uIHJlbGF0aW9uc2hpcHMKYW5kIG9uZSBjb21wb3NpdGlvbiByZWxhdGlvbnNoaXAuCgpZb3UgY2FuIHJpZ2h0IGNsaWNrIG9uIGxpbmVzIHRvIGNoYW5nZQp0aGVpciB0eXBlIGFuZCB0aGVpciBkaXJlY3Rpb24uCgpUcnkgdGhlICJSIiBzaG9ydGN1dCB3aGlsc3QgYSBsaW5lIGlzIApzZWxlY3RlZCwgdG8gcmV2ZXJzZSB0aGUgbGluZSBkaXJlY3Rpb24h'} 8 | {'type':'edge', 'id':'CmdLinePythonToAsciiArt_to_CmdLineGenerator', 'source':'CmdLinePythonToAsciiArt', 'target':'CmdLineGenerator', 'uml_edge_type': 'generalisation'} 9 | {'type':'edge', 'id':'PySourceAsText_to_ReportGenerator', 'source':'PySourceAsText', 'target':'ReportGenerator', 'uml_edge_type': 'generalisation'} 10 | {'type':'edge', 'id':'PySourceAsText_to_CmdLinePythonToAsciiArt', 'source':'PySourceAsText', 'target':'CmdLinePythonToAsciiArt', 'uml_edge_type': 'composition'} 11 | -------------------------------------------------------------------------------- /src/samples/simple inheritance.pyns: -------------------------------------------------------------------------------- 1 | # PynSource Version 1.2 2 | {'type':'meta', 'info1':'Lorem ipsum dolor sit amet, consectetur adipiscing elit is latin. Comments are saved.'} 3 | {'type':'umlshape', 'id':'MyPrintout', 'x':21, 'y':164, 'width':136, 'height':174, 'attrs': 'canvas|log', 'meths': '__init__|OnBeginDocument|OnEndDocument|OnBeginPrinting|OnEndPrinting|OnPreparePrinting|HasPage|GetPageInfo|OnPrintPage|IncreasePrintAreaSize'} 4 | {'type':'umlshape', 'id':'wx', 'x':74, 'y':30, 'width':27, 'height':24, 'attrs': '', 'meths': ''} 5 | {'type':'comment', 'id':'C7818', 'x':276, 'y':83, 'width':387, 'height':75, 'comment': 'd3ggaXMgdGhlIGJhc2UgY2xhc3Mgb2YgTXlQcmludG91dC4KTm90ZSB0aGlzIGluaGVyaXRhbmNlIHJlbGF0aW9uc2hpcCBpcyBkcmF3bgp3aXRoIGEgc3RhbmRhcmQgVU1MIGxpbmUgc3R5bGUu'} 6 | {'type':'edge', 'id':'MyPrintout_to_wx', 'source':'MyPrintout', 'target':'wx', 'uml_edge_type': 'generalisation'} 7 | {'type':'edge', 'id':'MyPrintout_to_C7818', 'source':'MyPrintout', 'target':'C7818', 'uml_edge_type': 'association'} 8 | {'type':'edge', 'id':'wx_to_C7818', 'source':'wx', 'target':'C7818', 'uml_edge_type': 'association'} 9 | -------------------------------------------------------------------------------- /src/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/tests/__init__.py -------------------------------------------------------------------------------- /src/tests/misc manually run scripts/run_pynsource_asciiart.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM generate an asciiart uml diagram 3 | REM @echo on 4 | python ..\..\src\pynsource.py -a ..\python-in\testmodule01.py > output\outasciiart.txt 5 | @echo off 6 | echo. 7 | echo Note the command line ascii UML generation is an early alpha. 8 | echo The pyNsourceGui produces far superior ascii UML generation 9 | echo. 10 | echo Copy your asci art UML into e.g Java Ascii Versatile Editor http://www.jave.de/ 11 | notepad output\outasciiart.txt -------------------------------------------------------------------------------- /src/tests/misc manually run scripts/run_pynsource_yuml.bat: -------------------------------------------------------------------------------- 1 | REM generate a yuml diagram 2 | python ..\..\src\pynsource.py -y output\outyuml.png ..\python-in\testmodule01.py 3 | explorer output\outyuml.png -------------------------------------------------------------------------------- /src/tests/python-in/p2.py: -------------------------------------------------------------------------------- 1 | # example of a python2 syntax file 2 | class Py2: 3 | def aa(self): 4 | print "hi" 5 | -------------------------------------------------------------------------------- /src/tests/python-in/p3.py: -------------------------------------------------------------------------------- 1 | # example of a python3 syntax file 2 | class Py3: 3 | async def aaaa3(self): 4 | print("hi", end=" ") 5 | -------------------------------------------------------------------------------- /src/tests/python-in/sort_attrs_example.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest: 2 | def __init__(self): 3 | self.z = 1 4 | self.a = 1 5 | def aa(self): pass 6 | def zz(self): pass 7 | def bb(self): pass -------------------------------------------------------------------------------- /src/tests/python-in/testmodule01.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest: 2 | def __init__(self): 3 | self.a = 10 # class attribute 4 | self.b = Blah() # class attribute COMPOSITE 5 | self.a.c = 20 # skip 6 | self.__class__.d = 30 # static class attribute 7 | self.e.append(10) # class attribute (list/vector) 8 | self.e2.append("10") # class attribute (list/vector) 9 | self.f.append(Blah()) # class attribute (list/vector) COMPOSITE 10 | 11 | def IsInBattle(self): 12 | if not self.tileinfo: 13 | return 0 14 | return self.tileinfo.battletriggered 15 | 16 | def DoA(self): 17 | pass 18 | 19 | 20 | class ParseMeTest2(ParseMeTest): 21 | def DoB(self): 22 | self._secretinfo = 2 23 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule02.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest: 2 | def __init__(self): 3 | self.timejoinedbattle = None 4 | # self.attacking = None # Neither attacking or defending 5 | self.fightingvalue = None 6 | self.damagepointsincurred = None 7 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule03.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest: 2 | def __init__(self): 3 | self.a = None 4 | self.b = None 5 | 6 | 7 | x = 20 8 | 9 | 10 | class ParseMeTest2: 11 | pass 12 | 13 | 14 | def y(): 15 | pass 16 | 17 | 18 | class ParseMeTest3: 19 | pass 20 | 21 | 22 | if __name__ == "__main__": 23 | y() 24 | 25 | 26 | class ParseMeTest4: 27 | pass 28 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule04.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest: 2 | a = 100 3 | b = [1, 2, 3] 4 | 5 | def __init__(self): 6 | self.c = [] 7 | self.d = [1, 2, 3] 8 | self.e = (1, 2, 3) 9 | self.f = 1 * 10 10 | 11 | 12 | x = [1, 2] 13 | y = [] 14 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule05.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest: 2 | a = 100 3 | 4 | class A: 5 | pass 6 | 7 | def __init__(self): 8 | self.b = [] 9 | 10 | class B: 11 | ba = 99 12 | 13 | class C: 14 | def __init__(self): 15 | self.cc = 88 16 | 17 | def Hi(self): 18 | pass 19 | 20 | 21 | class D: 22 | pass 23 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule06.py: -------------------------------------------------------------------------------- 1 | import utilcc 2 | from observer import Observable 3 | from event import eventfactory 4 | from editorweather import WeatherEditor 5 | from editorflags import FlagEditor 6 | from editorturns import TurnEditor 7 | import copy 8 | import pprint, undo 9 | 10 | 11 | class ParseMeTest(undo.UndoItem): 12 | def __init__(self, scenario): 13 | self.scenario = scenario 14 | self.flagsdict = None 15 | self.pointsdict = None 16 | self.weatherdict = None 17 | 18 | # Perhaps these should be in oobeditor? or perhaps weathereditor should be in resolverweather. 19 | self.flageditor = FlagEditor(gamestatusstate=self) 20 | self.weathereditor = WeatherEditor(gamestatusstate=self) 21 | self.turnseditor = TurnEditor(gamestatusstate=self) 22 | 23 | self.SetFlagsFromMemento(self.scenario.flagsinfochunk) 24 | 25 | def SetFlagsFromMemento(self, memento): 26 | if memento: 27 | self.flagsdict = eval(memento) 28 | else: 29 | self.flagsdict = {} 30 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule07.py: -------------------------------------------------------------------------------- 1 | class ParseMeTest(undo.UndoItem): 2 | 3 | DEFAULT_ELEVATION = 30 4 | 5 | def __init__(self, map): 6 | self.map = map 7 | 8 | def PlaceTile(self, coord, terrainbmp): 9 | self.EnsureGraphicsSubDictAllocated(coord) 10 | newterraintype = self.bmpUtils.BmpToTerrainType(terrainbmp) 11 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule08_multiple_inheritance.py: -------------------------------------------------------------------------------- 1 | class Fred(Mary, Sam): 2 | pass 3 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule09_intense.py: -------------------------------------------------------------------------------- 1 | import wx 2 | 3 | 4 | class Torture1: 5 | def PrepTests(self): 6 | self.a = UmlCanvas(panel, Log(), self.frame) 7 | self.b.append(UmlCanvas(panel, Log(), self.frame)) 8 | 9 | def Tricky(self): 10 | self.log = Log() 11 | self.frame = wx.Frame() 12 | self.notebook = wx.Notebook(self.frame, -1) 13 | self.umlcanvas = UmlCanvas(panel, Log(), self.frame) 14 | self.umlcanvas = UmlCanvas(panel, Log(), self.frame) 15 | self.umlcanvas = UmlCanvas(panel, Log(), self.frame) 16 | self.umlcanvas = UmlCanvas(panel, Log(), self.frame) 17 | self.umlcanvas = UmlCanvas(self.notebook, Log(), self.frame) 18 | self.umlcanvas = UmlCanvas(self.frame, Log(), self.frame) 19 | self.multiText = wx.TextCtrl 20 | self.app = App(context) 21 | self.user_config_file = os.path.join(config_dir, PYNSOURCE_CONFIG_FILE) 22 | self.config = ConfigObj(self.user_config_file) # doco at 23 | self.popupmenu = wx.Menu() 24 | self.next_menu_id = ( 25 | wx.NewId() 26 | ) # ---- yike how to tell if LIBRARY call is class or function !! 27 | self.printData = wx.PrintData() 28 | self.printData = wx.PrintData() 29 | self.box = wx.BoxSizer(wx.VERTICAL) 30 | 31 | # trickier cases 32 | self.canvas = self.umlcanvas.GetDiagram().GetCanvas() 33 | self.curr.append(" " * self.curr_width) 34 | 35 | 36 | a = Torture1() 37 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule10_old_cant_parse.py: -------------------------------------------------------------------------------- 1 | class Torture1: 2 | def PrepTests(self): 3 | self.a = UmlCanvas(panel, Log(), self.frame) 4 | self.b.append(UmlCanvas(panel, Log(), self.frame)) 5 | 6 | # def Tricky(self): 7 | # self.log = Log() 8 | # from self.frame = wx.Frame ? should pick up more? 9 | # self.notebook = wx.Notebook 10 | # self.umlcanvas = UmlCanvas(panel, Log(), self.frame) 11 | # self.umlcanvas = UmlCanvas(self.notebook, Log(), self.frame) 12 | # self.umlcanvas = UmlCanvas(self.frame, Log(), self.frame) 13 | # self.multiText = wx.TextCtrl 14 | # self.app = App(context) 15 | # self.user_config_file = os.path.join(config_dir, PYNSOURCE_CONFIG_FILE) 16 | # self.config = ConfigObj(self.user_config_file) # doco at 17 | # self.popupmenu = wx.Menu() # Create a menu 18 | # self.next_menu_id = wx.NewId() ---- yike how to tell if LIBRARY call is class or function !! 19 | # self.printData = wx.PrintData() 20 | # self.printData = wx.PrintData() 21 | # self.box = wx.BoxSizer(wx.VERTICAL) 22 | # self.canvas = self.umlcanvas.GetDiagram().GetCanvas() 23 | 24 | 25 | a = Torture1() 26 | -------------------------------------------------------------------------------- /src/tests/python-in/testmodule11_incoming_bugs.py: -------------------------------------------------------------------------------- 1 | class Incoming1: 2 | def HandlePowerOperator(self): 3 | x = 10 ** 2 4 | print(x) 5 | 6 | 7 | a = Incoming1() 8 | a.HandlePowerOperator() 9 | -------------------------------------------------------------------------------- /src/tests/readme-tests.md: -------------------------------------------------------------------------------- 1 | Here are some vscode JSON launch configs for the latest mid-2021 tests 2 | 3 | ```json 4 | { 5 | "name": "test PYTHON parsing edge cases - test_issue_typehint_optional", 6 | "type": "python", 7 | "request": "launch", 8 | "cwd": "${workspaceRoot}/src", 9 | "module": "unittest", 10 | "args": [ 11 | "tests.test_parse_bugs_incoming.TestIncomingBugs.test_issue_typehint_optional", 12 | ], 13 | }, 14 | { 15 | "name": "test_issue_subscript_issue_93", 16 | "type": "python", 17 | "request": "launch", 18 | "cwd": "${workspaceRoot}/src", 19 | "module": "unittest", 20 | "args": [ 21 | "tests.test_parse_bugs_incoming.TestIncomingBugs.test_issue_subscript_issue_93", 22 | ], 23 | }, 24 | { 25 | "name": "test_issue_walrus_issue_94", 26 | "type": "python", 27 | "request": "launch", 28 | "cwd": "${workspaceRoot}/src", 29 | "module": "unittest", 30 | "args": [ 31 | "tests.test_parse_bugs_incoming.TestIncomingBugs.test_issue_walrus_issue_94", 32 | ], 33 | }, 34 | { 35 | "name": "test_issue_class_type_annotation_85", 36 | "type": "python", 37 | "request": "launch", 38 | "cwd": "${workspaceRoot}/src", 39 | "module": "unittest", 40 | "args": [ 41 | "tests.test_parse_bugs_incoming.TestIncomingBugs.test_issue_class_type_annotation_85", 42 | ], 43 | }, 44 | ``` 45 | -------------------------------------------------------------------------------- /src/tests/settings.py: -------------------------------------------------------------------------------- 1 | PYTHON_CODE_EXAMPLES_TO_PARSE = "src/tests/python-in/" 2 | -------------------------------------------------------------------------------- /src/tests/test_ast_quickparse.py: -------------------------------------------------------------------------------- 1 | # import unittest 2 | # import sys 3 | # import re 4 | # from parsing.quick_parse import REGEX_FOR_METHODS 5 | # 6 | # # python -m unittest tests.test_ast_quickparse 7 | # 8 | # class TestQuickParse(unittest.TestCase): 9 | # 10 | # def setUp(self): 11 | # self.regex = r'^\s*def (.*?)\(.*\):' # the ? turns off greedy 12 | # 13 | # def test_regex1(self): 14 | # source = "def fred(): pass" 15 | # defs = re.findall(REGEX_FOR_METHODS, source, re.MULTILINE) 16 | # self.assertEqual(defs, ['fred']) 17 | # 18 | # def test_regex2(self): 19 | # source = " def fred(): pass" 20 | # defs = re.findall(REGEX_FOR_METHODS, source, re.MULTILINE) 21 | # self.assertEqual(defs, ['fred']) 22 | # 23 | # def test_regex3(self): 24 | # source = " def fred(param1): pass" 25 | # defs = re.findall(REGEX_FOR_METHODS, source, re.MULTILINE) 26 | # self.assertEqual(defs, ['fred']) 27 | # 28 | # def test_regex3(self): 29 | # source = " def fred(timepos, modernyear=2001, waryear=int(DEFAULT_WARDATE_USFORMAT[2]), month=int(DEFAULT_WARDATE_USFORMAT[0]), day=int(DEFAULT_WARDATE_USFORMAT[1]), hour=6):" 30 | # defs = re.findall(REGEX_FOR_METHODS, source, re.MULTILINE) 31 | # self.assertEqual(defs, ['fred']) 32 | # 33 | -------------------------------------------------------------------------------- /src/tests/test_java_delphi_gen.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from parsing.api import new_parser, old_parser 3 | 4 | # python -m unittest tests.test_java_delphi_gen 5 | 6 | 7 | class TestJavaDelphiGen(unittest.TestCase): 8 | def test_1(self): 9 | in_filename = "src/tests/testing-generate-java/python-in/utilcc.py" 10 | 11 | p, debuginfo = old_parser(in_filename) 12 | pmodel_old = p.pmodel 13 | 14 | pmodel_new, debuginfo = new_parser(in_filename) 15 | 16 | # print pmodel_old.modulemethods 17 | # print pmodel_new.modulemethods 18 | 19 | old = set(pmodel_old.modulemethods) 20 | new = set(pmodel_new.modulemethods) 21 | 22 | any_changes = old ^ new 23 | 24 | differences_expected = set(["safeconvert", "PopFoldersTillFind"]) 25 | 26 | # no_changes = set() 27 | # self.assertSetEqual(any_changes, no_changes, any_changes) 28 | 29 | # Nested methods are not picked up by the new ast parser 30 | self.assertSetEqual(any_changes, differences_expected, any_changes) 31 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/EventPlayAPI.pas: -------------------------------------------------------------------------------- 1 | 2 | (* 3 | ModuleMethods = ['suite', 'main'] 4 | *) 5 | 6 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 7 | 8 | unit unit_EventPlayAPI; 9 | 10 | interface 11 | 12 | uses 13 | unit_PlayAPI; 14 | 15 | type 16 | 17 | EventPlayAPI = class(PlayAPI) 18 | public 19 | procedure GetCurrentValue(); virtual; 20 | procedure GetMaxValue(); virtual; 21 | procedure JumpToValue(); virtual; 22 | procedure _DeriveOtherPlayheadPositionsFrom(); virtual; 23 | procedure _TimeOfEventAt(); virtual; 24 | procedure _SetOtherPlayheadsTo(); virtual; 25 | procedure SynchroniseOtherPlayheads(); virtual; 26 | end; 27 | 28 | 29 | implementation 30 | 31 | procedure EventPlayAPI.GetCurrentValue(); 32 | begin 33 | end; 34 | 35 | procedure EventPlayAPI.GetMaxValue(); 36 | begin 37 | end; 38 | 39 | procedure EventPlayAPI.JumpToValue(); 40 | begin 41 | end; 42 | 43 | procedure EventPlayAPI._DeriveOtherPlayheadPositionsFrom(); 44 | begin 45 | end; 46 | 47 | procedure EventPlayAPI._TimeOfEventAt(); 48 | begin 49 | end; 50 | 51 | procedure EventPlayAPI._SetOtherPlayheadsTo(); 52 | begin 53 | end; 54 | 55 | procedure EventPlayAPI.SynchroniseOtherPlayheads(); 56 | begin 57 | end; 58 | 59 | 60 | end. 61 | 62 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/PlayheadMediator.pas: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | unit unit_PlayheadMediator; 4 | 5 | interface 6 | 7 | uses 8 | unit_Playhead, unit_TurnPlayAPI, unit_TimePlayAPI, unit_EventPlayAPI; 9 | 10 | type 11 | 12 | PlayheadMediator = class 13 | public 14 | turnMgr : Variant; 15 | story : Variant; 16 | eventPlayhead : Playhead; 17 | timePlayhead : Playhead; 18 | turnPlayhead : Playhead; 19 | byEvent : EventPlayAPI; 20 | byTime : TimePlayAPI; 21 | byTurn : TurnPlayAPI; 22 | 23 | constructor Create; 24 | procedure Clear(); virtual; 25 | procedure IsEmpty(); virtual; 26 | end; 27 | 28 | 29 | implementation 30 | 31 | constructor PlayheadMediator.Create; 32 | begin 33 | eventPlayhead := Playhead.Create(); 34 | timePlayhead := Playhead.Create(); 35 | turnPlayhead := Playhead.Create(); 36 | byEvent := EventPlayAPI.Create(); 37 | byTime := TimePlayAPI.Create(); 38 | byTurn := TurnPlayAPI.Create(); 39 | end; 40 | 41 | procedure PlayheadMediator.Clear(); 42 | begin 43 | end; 44 | 45 | procedure PlayheadMediator.IsEmpty(); 46 | begin 47 | end; 48 | 49 | 50 | end. 51 | 52 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/TestCase02.pas: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | unit unit_TestCase02; 4 | 5 | interface 6 | 7 | uses 8 | unit_TestCase, unit_PlayheadMediator; 9 | 10 | type 11 | 12 | TestCase02 = class(TestCase) 13 | public 14 | _goto : PlayheadMediator; 15 | 16 | procedure setUp(); virtual; 17 | procedure CalcAmountOfTimeInStoryline(); virtual; 18 | procedure EnsureSanity(); virtual; 19 | procedure check01(); virtual; 20 | end; 21 | 22 | 23 | implementation 24 | 25 | procedure TestCase02.setUp(); 26 | begin 27 | end; 28 | 29 | procedure TestCase02.CalcAmountOfTimeInStoryline(); 30 | begin 31 | end; 32 | 33 | procedure TestCase02.EnsureSanity(); 34 | begin 35 | end; 36 | 37 | procedure TestCase02.check01(); 38 | begin 39 | end; 40 | 41 | 42 | end. 43 | 44 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/TimePlayAPI.pas: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | unit unit_TimePlayAPI; 4 | 5 | interface 6 | 7 | uses 8 | unit_PlayAPI; 9 | 10 | type 11 | 12 | TimePlayAPI = class(PlayAPI) 13 | public 14 | procedure GetCurrentValue(); virtual; 15 | procedure GetMaxValue(); virtual; 16 | procedure JumpToValue(); virtual; 17 | procedure _DeriveOtherPlayheadPositionsFrom(); virtual; 18 | procedure _SetOtherPlayheadsTo(); virtual; 19 | procedure SynchroniseOtherPlayheads(); virtual; 20 | end; 21 | 22 | 23 | implementation 24 | 25 | procedure TimePlayAPI.GetCurrentValue(); 26 | begin 27 | end; 28 | 29 | procedure TimePlayAPI.GetMaxValue(); 30 | begin 31 | end; 32 | 33 | procedure TimePlayAPI.JumpToValue(); 34 | begin 35 | end; 36 | 37 | procedure TimePlayAPI._DeriveOtherPlayheadPositionsFrom(); 38 | begin 39 | end; 40 | 41 | procedure TimePlayAPI._SetOtherPlayheadsTo(); 42 | begin 43 | end; 44 | 45 | procedure TimePlayAPI.SynchroniseOtherPlayheads(); 46 | begin 47 | end; 48 | 49 | 50 | end. 51 | 52 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/TurnPlayAPI.pas: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | unit unit_TurnPlayAPI; 4 | 5 | interface 6 | 7 | uses 8 | unit_PlayAPI; 9 | 10 | type 11 | 12 | TurnPlayAPI = class(PlayAPI) 13 | public 14 | procedure GetCurrentValue(); virtual; 15 | procedure GetMaxValue(); virtual; 16 | procedure JumpToValue(); virtual; 17 | procedure _DeriveOtherPlayheadPositionsFrom(); virtual; 18 | procedure _SetOtherPlayheadsTo(); virtual; 19 | procedure SynchroniseOtherPlayheads(); virtual; 20 | end; 21 | 22 | 23 | implementation 24 | 25 | procedure TurnPlayAPI.GetCurrentValue(); 26 | begin 27 | end; 28 | 29 | procedure TurnPlayAPI.GetMaxValue(); 30 | begin 31 | end; 32 | 33 | procedure TurnPlayAPI.JumpToValue(); 34 | begin 35 | end; 36 | 37 | procedure TurnPlayAPI._DeriveOtherPlayheadPositionsFrom(); 38 | begin 39 | end; 40 | 41 | procedure TurnPlayAPI._SetOtherPlayheadsTo(); 42 | begin 43 | end; 44 | 45 | procedure TurnPlayAPI.SynchroniseOtherPlayheads(); 46 | begin 47 | end; 48 | 49 | 50 | end. 51 | 52 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/UniqueList.pas: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | unit unit_UniqueList; 4 | 5 | interface 6 | 7 | uses 8 | unit_list; 9 | 10 | type 11 | 12 | UniqueList = class(list) 13 | public 14 | procedure append(); virtual; 15 | procedure __add__(); virtual; 16 | procedure __iadd__(); virtual; 17 | end; 18 | 19 | 20 | implementation 21 | 22 | procedure UniqueList.append(); 23 | begin 24 | end; 25 | 26 | procedure UniqueList.__add__(); 27 | begin 28 | end; 29 | 30 | procedure UniqueList.__iadd__(); 31 | begin 32 | end; 33 | 34 | 35 | end. 36 | 37 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/unit_dict.pas: -------------------------------------------------------------------------------- 1 | 2 | unit unit_dict; 3 | 4 | interface 5 | 6 | type 7 | 8 | dict = class 9 | public 10 | end; 11 | 12 | implementation 13 | 14 | end. 15 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/unit_list.pas: -------------------------------------------------------------------------------- 1 | 2 | unit unit_list; 3 | 4 | interface 5 | 6 | type 7 | 8 | list = class 9 | public 10 | end; 11 | 12 | implementation 13 | 14 | end. 15 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/delphi-out/unit_unittest.pas: -------------------------------------------------------------------------------- 1 | 2 | unit unit_unittest; 3 | 4 | interface 5 | 6 | type 7 | 8 | unittest = class 9 | public 10 | end; 11 | 12 | implementation 13 | 14 | end. 15 | -------------------------------------------------------------------------------- /src/tests/testing-generate-delphi/run.bat: -------------------------------------------------------------------------------- 1 | python ..\..\pynsource\pynsource.py -d delphi-out python-in\*.py 2 | pause -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-ide-import-results/ea-JavaImportProj01.eap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/tests/testing-generate-java/java-ide-import-results/ea-JavaImportProj01.eap -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-ide-import-results/ea-enterprisearchitect-uml.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/tests/testing-generate-java/java-ide-import-results/ea-enterprisearchitect-uml.pdf -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-ide-import-results/ea-enterprisearchitect01.emf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/tests/testing-generate-java/java-ide-import-results/ea-enterprisearchitect01.emf -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-ide-import-results/ess-pic01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/tests/testing-generate-java/java-ide-import-results/ess-pic01.png -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-ide-import-results/ess-pic01.wmf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/tests/testing-generate-java/java-ide-import-results/ess-pic01.wmf -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/EventPlayAPI.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | ModuleMethods = ['suite', 'main'] 4 | */ 5 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 6 | 7 | public class EventPlayAPI extends PlayAPI { 8 | public void GetCurrentValue() { 9 | } 10 | public void GetMaxValue() { 11 | } 12 | public void JumpToValue() { 13 | } 14 | public void _DeriveOtherPlayheadPositionsFrom() { 15 | } 16 | public void _TimeOfEventAt() { 17 | } 18 | public void _SetOtherPlayheadsTo() { 19 | } 20 | public void SynchroniseOtherPlayheads() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/PlayAPI.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class PlayAPI { 4 | public variant mediator; 5 | public variant playhead; 6 | public variant turnMgr; 7 | public void __init__() { 8 | } 9 | public void IsEmpty() { 10 | } 11 | public void IsMoreToPlay() { 12 | } 13 | public void Start() { 14 | } 15 | public void Endd() { 16 | } 17 | public void Next() { 18 | } 19 | public void Previous() { 20 | } 21 | public void _GetCurrentPosition() { 22 | } 23 | public void GetCurrentValue() { 24 | } 25 | public void _GetMaxPosition() { 26 | } 27 | public void GetMaxValue() { 28 | } 29 | public void _JumpToPosition() { 30 | } 31 | public void JumpToValue() { 32 | } 33 | public void NotifyOfInsert() { 34 | } 35 | public void NotifyPositionNowValid() { 36 | } 37 | public void SynchroniseOtherPlayheads() { 38 | } 39 | public void _FindLastEventWithTimeElseMostRecentEventLessthanTime() { 40 | } 41 | public void _FindLastEventWithTimeElseMostRecentEventLessthanTime_ORI() { 42 | } 43 | public void _EnsureMaxTimeCorrespondsToMaxTurn() { 44 | } 45 | public void _GetPositionToSyncTo() { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/Playhead.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | ModuleMethods = ['suite', 'main'] 4 | */ 5 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 6 | 7 | public class Playhead { 8 | public variant Position; 9 | public variant MaxPosition; 10 | public void __init__() { 11 | } 12 | public void Clear() { 13 | } 14 | public void _ClipPositionToMax() { 15 | } 16 | public void _SetMaxItems() { 17 | } 18 | public void IsEmpty() { 19 | } 20 | public void IsMoreToPlay() { 21 | } 22 | public void NotifyPositionNowValid() { 23 | } 24 | public void NotifyOfInsert() { 25 | } 26 | public void GoStart() { 27 | } 28 | public void GoEnd() { 29 | } 30 | public void Go() { 31 | } 32 | public void GoNext() { 33 | } 34 | public void GoPrevious() { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/PlayheadMediator.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class PlayheadMediator { 4 | public variant turnMgr; 5 | public variant story; 6 | public Playhead eventPlayhead = new Playhead(); 7 | public Playhead timePlayhead = new Playhead(); 8 | public Playhead turnPlayhead = new Playhead(); 9 | public EventPlayAPI byEvent = new EventPlayAPI(); 10 | public TimePlayAPI byTime = new TimePlayAPI(); 11 | public TurnPlayAPI byTurn = new TurnPlayAPI(); 12 | public void __init__() { 13 | } 14 | public void Clear() { 15 | } 16 | public void IsEmpty() { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/TestCase01.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class TestCase01 extends TestCase { 4 | public PlayheadMediator _goto = new PlayheadMediator(); 5 | public void setUp() { 6 | } 7 | public void checkInit() { 8 | } 9 | public void checkStartNoItemsNormal() { 10 | } 11 | public void checkStartNoItemsAndGoPreviousNormal() { 12 | } 13 | public void checkStartOneItemNormal() { 14 | } 15 | public void checkBasicMovementSynch01Normal() { 16 | } 17 | public void checkBasicMovementSynch02Normal() { 18 | } 19 | public void checkMaxValue() { 20 | } 21 | public void checkJumpToAndValidateCurrentValueNormal() { 22 | } 23 | public void checkIsEmptyNormal() { 24 | } 25 | public void checkByTimeAndEventPositioningNormal() { 26 | } 27 | public void checkByTurnPositioningNormal() { 28 | } 29 | public void checkByTimeAndEventPositioningNormal02() { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/TestCase02.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class TestCase02 extends TestCase { 4 | public PlayheadMediator _goto = new PlayheadMediator(); 5 | public void setUp() { 6 | } 7 | public void CalcAmountOfTimeInStoryline() { 8 | } 9 | public void EnsureSanity() { 10 | } 11 | public void check01() { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/TimePlayAPI.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class TimePlayAPI extends PlayAPI { 4 | public void GetCurrentValue() { 5 | } 6 | public void GetMaxValue() { 7 | } 8 | public void JumpToValue() { 9 | } 10 | public void _DeriveOtherPlayheadPositionsFrom() { 11 | } 12 | public void _SetOtherPlayheadsTo() { 13 | } 14 | public void SynchroniseOtherPlayheads() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/TurnPlayAPI.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class TurnPlayAPI extends PlayAPI { 4 | public void GetCurrentValue() { 5 | } 6 | public void GetMaxValue() { 7 | } 8 | public void JumpToValue() { 9 | } 10 | public void _DeriveOtherPlayheadPositionsFrom() { 11 | } 12 | public void _SetOtherPlayheadsTo() { 13 | } 14 | public void SynchroniseOtherPlayheads() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/UniqueList.java: -------------------------------------------------------------------------------- 1 | // Generated by PyNSource http://www.andypatterns.com/index.php/products/pynsource/ 2 | 3 | public class UniqueList extends list { 4 | public void append() { 5 | } 6 | public void __add__() { 7 | } 8 | public void __iadd__() { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/dict.java: -------------------------------------------------------------------------------- 1 | 2 | public class dict { 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/list.java: -------------------------------------------------------------------------------- 1 | 2 | public class list { 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/object.java: -------------------------------------------------------------------------------- 1 | 2 | public class object { 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/unittest.java: -------------------------------------------------------------------------------- 1 | 2 | public class unittest { 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/java-out/variant.java: -------------------------------------------------------------------------------- 1 | 2 | public class variant { 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/testing-generate-java/run.bat: -------------------------------------------------------------------------------- 1 | python ..\..\pynsource\pynsource.py -j java-out python-in\*.py 2 | pause -------------------------------------------------------------------------------- /src/view/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abulka/pynsource/979436525c57fdaeaa832e960985e0406e123587/src/view/__init__.py -------------------------------------------------------------------------------- /tbump.toml: -------------------------------------------------------------------------------- 1 | # Uncomment this if your project is hosted on GitHub: 2 | # github_url = "https://github.com///" 3 | 4 | [version] 5 | current = "1.84" 6 | 7 | # Make sure this matches current_version before 8 | # using tbump 9 | regex = ''' 10 | (?P\d+) 11 | \. 12 | (?P\d+) 13 | ''' 14 | 15 | [git] 16 | message_template = "Bump to {new_version}" 17 | tag_template = "version-{new_version}" 18 | 19 | # For each file to patch, add a [[file]] config 20 | # section containing the path of the file, relative to the 21 | # tbump.toml location. 22 | #[[file]] 23 | #src = "README.md" 24 | [[file]] 25 | src = "DOWNLOADS.md" 26 | 27 | # the search is not needed, but play it safe 28 | [[file]] 29 | src = "src/gui/settings.py" 30 | search = 'APP_VERSION = {current_version}' 31 | 32 | [[file]] 33 | src = ".requirement-extras/buildwin_github-actions.iss" 34 | search = 'AppVersion={current_version}' 35 | [[file]] 36 | src = ".requirement-extras/buildwin_github-actions.iss" 37 | search = 'VersionInfoVersion={current_version}' 38 | [[file]] 39 | src = ".requirement-extras/buildwin_github-actions.iss" 40 | search = 'OutputBaseFilename=pynsource-win-{current_version}-setup' 41 | 42 | # You can specify a list of commands to 43 | # run after the files have been patched 44 | # and before the git commit is made 45 | 46 | # [[before_commit]] 47 | # name = "check changelog" 48 | # cmd = "grep -q {new_version} Changelog.rst" 49 | 50 | # Or run some commands after the git tag and the branch 51 | # have been pushed: 52 | # [[after_push]] 53 | # name = "publish" 54 | # cmd = "./publish.sh" 55 | --------------------------------------------------------------------------------