meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7020__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerk40t/__init__.py +1 -1
- meerk40t/balormk/balor_params.py +167 -167
- meerk40t/balormk/clone_loader.py +457 -457
- meerk40t/balormk/controller.py +1566 -1512
- meerk40t/balormk/cylindermod.py +64 -0
- meerk40t/balormk/device.py +966 -1959
- meerk40t/balormk/driver.py +778 -591
- meerk40t/balormk/galvo_commands.py +1194 -0
- meerk40t/balormk/gui/balorconfig.py +237 -111
- meerk40t/balormk/gui/balorcontroller.py +191 -184
- meerk40t/balormk/gui/baloroperationproperties.py +116 -115
- meerk40t/balormk/gui/corscene.py +845 -0
- meerk40t/balormk/gui/gui.py +179 -147
- meerk40t/balormk/livelightjob.py +466 -382
- meerk40t/balormk/mock_connection.py +131 -109
- meerk40t/balormk/plugin.py +133 -135
- meerk40t/balormk/usb_connection.py +306 -301
- meerk40t/camera/__init__.py +1 -1
- meerk40t/camera/camera.py +514 -397
- meerk40t/camera/gui/camerapanel.py +1241 -1095
- meerk40t/camera/gui/gui.py +58 -58
- meerk40t/camera/plugin.py +441 -399
- meerk40t/ch341/__init__.py +27 -27
- meerk40t/ch341/ch341device.py +628 -628
- meerk40t/ch341/libusb.py +595 -589
- meerk40t/ch341/mock.py +171 -171
- meerk40t/ch341/windriver.py +157 -157
- meerk40t/constants.py +13 -0
- meerk40t/core/__init__.py +1 -1
- meerk40t/core/bindalias.py +550 -539
- meerk40t/core/core.py +47 -47
- meerk40t/core/cutcode/cubiccut.py +73 -73
- meerk40t/core/cutcode/cutcode.py +315 -312
- meerk40t/core/cutcode/cutgroup.py +141 -137
- meerk40t/core/cutcode/cutobject.py +192 -185
- meerk40t/core/cutcode/dwellcut.py +37 -37
- meerk40t/core/cutcode/gotocut.py +29 -29
- meerk40t/core/cutcode/homecut.py +29 -29
- meerk40t/core/cutcode/inputcut.py +34 -34
- meerk40t/core/cutcode/linecut.py +33 -33
- meerk40t/core/cutcode/outputcut.py +34 -34
- meerk40t/core/cutcode/plotcut.py +335 -335
- meerk40t/core/cutcode/quadcut.py +61 -61
- meerk40t/core/cutcode/rastercut.py +168 -148
- meerk40t/core/cutcode/waitcut.py +34 -34
- meerk40t/core/cutplan.py +1843 -1316
- meerk40t/core/drivers.py +330 -329
- meerk40t/core/elements/align.py +801 -669
- meerk40t/core/elements/branches.py +1858 -1507
- meerk40t/core/elements/clipboard.py +229 -219
- meerk40t/core/elements/element_treeops.py +4595 -2837
- meerk40t/core/elements/element_types.py +125 -105
- meerk40t/core/elements/elements.py +4315 -3617
- meerk40t/core/elements/files.py +117 -64
- meerk40t/core/elements/geometry.py +473 -224
- meerk40t/core/elements/grid.py +467 -316
- meerk40t/core/elements/materials.py +158 -94
- meerk40t/core/elements/notes.py +50 -38
- meerk40t/core/elements/offset_clpr.py +934 -912
- meerk40t/core/elements/offset_mk.py +963 -955
- meerk40t/core/elements/penbox.py +339 -267
- meerk40t/core/elements/placements.py +300 -83
- meerk40t/core/elements/render.py +785 -687
- meerk40t/core/elements/shapes.py +2618 -2092
- meerk40t/core/elements/testcases.py +105 -0
- meerk40t/core/elements/trace.py +651 -563
- meerk40t/core/elements/tree_commands.py +415 -409
- meerk40t/core/elements/undo_redo.py +116 -58
- meerk40t/core/elements/wordlist.py +319 -200
- meerk40t/core/exceptions.py +9 -9
- meerk40t/core/laserjob.py +220 -220
- meerk40t/core/logging.py +63 -63
- meerk40t/core/node/blobnode.py +83 -86
- meerk40t/core/node/bootstrap.py +105 -103
- meerk40t/core/node/branch_elems.py +40 -31
- meerk40t/core/node/branch_ops.py +45 -38
- meerk40t/core/node/branch_regmark.py +48 -41
- meerk40t/core/node/cutnode.py +29 -32
- meerk40t/core/node/effect_hatch.py +375 -257
- meerk40t/core/node/effect_warp.py +398 -0
- meerk40t/core/node/effect_wobble.py +441 -309
- meerk40t/core/node/elem_ellipse.py +404 -309
- meerk40t/core/node/elem_image.py +1082 -801
- meerk40t/core/node/elem_line.py +358 -292
- meerk40t/core/node/elem_path.py +259 -201
- meerk40t/core/node/elem_point.py +129 -102
- meerk40t/core/node/elem_polyline.py +310 -246
- meerk40t/core/node/elem_rect.py +376 -286
- meerk40t/core/node/elem_text.py +445 -418
- meerk40t/core/node/filenode.py +59 -40
- meerk40t/core/node/groupnode.py +138 -74
- meerk40t/core/node/image_processed.py +777 -766
- meerk40t/core/node/image_raster.py +156 -113
- meerk40t/core/node/layernode.py +31 -31
- meerk40t/core/node/mixins.py +135 -107
- meerk40t/core/node/node.py +1427 -1304
- meerk40t/core/node/nutils.py +117 -114
- meerk40t/core/node/op_cut.py +463 -335
- meerk40t/core/node/op_dots.py +296 -251
- meerk40t/core/node/op_engrave.py +414 -311
- meerk40t/core/node/op_image.py +755 -369
- meerk40t/core/node/op_raster.py +787 -522
- meerk40t/core/node/place_current.py +37 -40
- meerk40t/core/node/place_point.py +329 -126
- meerk40t/core/node/refnode.py +58 -47
- meerk40t/core/node/rootnode.py +225 -219
- meerk40t/core/node/util_console.py +48 -48
- meerk40t/core/node/util_goto.py +84 -65
- meerk40t/core/node/util_home.py +61 -61
- meerk40t/core/node/util_input.py +102 -102
- meerk40t/core/node/util_output.py +102 -102
- meerk40t/core/node/util_wait.py +65 -65
- meerk40t/core/parameters.py +709 -707
- meerk40t/core/planner.py +875 -785
- meerk40t/core/plotplanner.py +656 -652
- meerk40t/core/space.py +120 -113
- meerk40t/core/spoolers.py +706 -705
- meerk40t/core/svg_io.py +1836 -1549
- meerk40t/core/treeop.py +534 -445
- meerk40t/core/undos.py +278 -124
- meerk40t/core/units.py +784 -680
- meerk40t/core/view.py +393 -322
- meerk40t/core/webhelp.py +62 -62
- meerk40t/core/wordlist.py +513 -504
- meerk40t/cylinder/cylinder.py +247 -0
- meerk40t/cylinder/gui/cylindersettings.py +41 -0
- meerk40t/cylinder/gui/gui.py +24 -0
- meerk40t/device/__init__.py +1 -1
- meerk40t/device/basedevice.py +322 -123
- meerk40t/device/devicechoices.py +50 -0
- meerk40t/device/dummydevice.py +163 -128
- meerk40t/device/gui/defaultactions.py +618 -602
- meerk40t/device/gui/effectspanel.py +114 -0
- meerk40t/device/gui/formatterpanel.py +253 -290
- meerk40t/device/gui/warningpanel.py +337 -260
- meerk40t/device/mixins.py +13 -13
- meerk40t/dxf/__init__.py +1 -1
- meerk40t/dxf/dxf_io.py +766 -554
- meerk40t/dxf/plugin.py +47 -35
- meerk40t/external_plugins.py +79 -79
- meerk40t/external_plugins_build.py +28 -28
- meerk40t/extra/cag.py +112 -116
- meerk40t/extra/coolant.py +403 -0
- meerk40t/extra/encode_detect.py +204 -0
- meerk40t/extra/ezd.py +1165 -1165
- meerk40t/extra/hershey.py +834 -340
- meerk40t/extra/imageactions.py +322 -316
- meerk40t/extra/inkscape.py +628 -622
- meerk40t/extra/lbrn.py +424 -424
- meerk40t/extra/outerworld.py +283 -0
- meerk40t/extra/param_functions.py +1542 -1556
- meerk40t/extra/potrace.py +257 -253
- meerk40t/extra/serial_exchange.py +118 -0
- meerk40t/extra/updater.py +602 -453
- meerk40t/extra/vectrace.py +147 -146
- meerk40t/extra/winsleep.py +83 -83
- meerk40t/extra/xcs_reader.py +597 -0
- meerk40t/fill/fills.py +781 -335
- meerk40t/fill/patternfill.py +1061 -1061
- meerk40t/fill/patterns.py +614 -567
- meerk40t/grbl/control.py +87 -87
- meerk40t/grbl/controller.py +990 -903
- meerk40t/grbl/device.py +1084 -768
- meerk40t/grbl/driver.py +989 -771
- meerk40t/grbl/emulator.py +532 -497
- meerk40t/grbl/gcodejob.py +783 -767
- meerk40t/grbl/gui/grblconfiguration.py +373 -298
- meerk40t/grbl/gui/grblcontroller.py +485 -271
- meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
- meerk40t/grbl/gui/grbloperationconfig.py +105 -0
- meerk40t/grbl/gui/gui.py +147 -116
- meerk40t/grbl/interpreter.py +44 -44
- meerk40t/grbl/loader.py +22 -22
- meerk40t/grbl/mock_connection.py +56 -56
- meerk40t/grbl/plugin.py +294 -264
- meerk40t/grbl/serial_connection.py +93 -88
- meerk40t/grbl/tcp_connection.py +81 -79
- meerk40t/grbl/ws_connection.py +112 -0
- meerk40t/gui/__init__.py +1 -1
- meerk40t/gui/about.py +2042 -296
- meerk40t/gui/alignment.py +1644 -1608
- meerk40t/gui/autoexec.py +199 -0
- meerk40t/gui/basicops.py +791 -670
- meerk40t/gui/bufferview.py +77 -71
- meerk40t/gui/busy.py +232 -133
- meerk40t/gui/choicepropertypanel.py +1662 -1469
- meerk40t/gui/consolepanel.py +706 -542
- meerk40t/gui/devicepanel.py +687 -581
- meerk40t/gui/dialogoptions.py +110 -107
- meerk40t/gui/executejob.py +316 -306
- meerk40t/gui/fonts.py +90 -90
- meerk40t/gui/functionwrapper.py +252 -0
- meerk40t/gui/gui_mixins.py +729 -0
- meerk40t/gui/guicolors.py +205 -182
- meerk40t/gui/help_assets/help_assets.py +218 -201
- meerk40t/gui/helper.py +154 -0
- meerk40t/gui/hersheymanager.py +1440 -846
- meerk40t/gui/icons.py +3422 -2747
- meerk40t/gui/imagesplitter.py +555 -508
- meerk40t/gui/keymap.py +354 -344
- meerk40t/gui/laserpanel.py +897 -806
- meerk40t/gui/laserrender.py +1470 -1232
- meerk40t/gui/lasertoolpanel.py +805 -793
- meerk40t/gui/magnetoptions.py +436 -0
- meerk40t/gui/materialmanager.py +2944 -0
- meerk40t/gui/materialtest.py +1722 -1694
- meerk40t/gui/mkdebug.py +646 -359
- meerk40t/gui/mwindow.py +163 -140
- meerk40t/gui/navigationpanels.py +2605 -2467
- meerk40t/gui/notes.py +143 -142
- meerk40t/gui/opassignment.py +414 -410
- meerk40t/gui/operation_info.py +310 -299
- meerk40t/gui/plugin.py +500 -328
- meerk40t/gui/position.py +714 -669
- meerk40t/gui/preferences.py +901 -650
- meerk40t/gui/propertypanels/attributes.py +1461 -1131
- meerk40t/gui/propertypanels/blobproperty.py +117 -114
- meerk40t/gui/propertypanels/consoleproperty.py +83 -80
- meerk40t/gui/propertypanels/gotoproperty.py +77 -0
- meerk40t/gui/propertypanels/groupproperties.py +223 -217
- meerk40t/gui/propertypanels/hatchproperty.py +489 -469
- meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
- meerk40t/gui/propertypanels/inputproperty.py +59 -58
- meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
- meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
- meerk40t/gui/propertypanels/outputproperty.py +59 -58
- meerk40t/gui/propertypanels/pathproperty.py +389 -380
- meerk40t/gui/propertypanels/placementproperty.py +1214 -383
- meerk40t/gui/propertypanels/pointproperty.py +140 -136
- meerk40t/gui/propertypanels/propertywindow.py +313 -181
- meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
- meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
- meerk40t/gui/propertypanels/textproperty.py +770 -755
- meerk40t/gui/propertypanels/waitproperty.py +56 -55
- meerk40t/gui/propertypanels/warpproperty.py +121 -0
- meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
- meerk40t/gui/ribbon.py +2471 -2210
- meerk40t/gui/scene/scene.py +1100 -1051
- meerk40t/gui/scene/sceneconst.py +22 -22
- meerk40t/gui/scene/scenepanel.py +439 -349
- meerk40t/gui/scene/scenespacewidget.py +365 -365
- meerk40t/gui/scene/widget.py +518 -505
- meerk40t/gui/scenewidgets/affinemover.py +215 -215
- meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
- meerk40t/gui/scenewidgets/bedwidget.py +120 -97
- meerk40t/gui/scenewidgets/elementswidget.py +137 -107
- meerk40t/gui/scenewidgets/gridwidget.py +785 -745
- meerk40t/gui/scenewidgets/guidewidget.py +765 -765
- meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
- meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
- meerk40t/gui/scenewidgets/nodeselector.py +28 -28
- meerk40t/gui/scenewidgets/rectselectwidget.py +592 -346
- meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
- meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
- meerk40t/gui/scenewidgets/selectionwidget.py +2958 -2756
- meerk40t/gui/simpleui.py +362 -333
- meerk40t/gui/simulation.py +2451 -2094
- meerk40t/gui/snapoptions.py +208 -203
- meerk40t/gui/spoolerpanel.py +1227 -1180
- meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
- meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
- meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
- meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
- meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
- meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
- meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
- meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
- meerk40t/gui/themes.py +200 -78
- meerk40t/gui/tips.py +590 -0
- meerk40t/gui/toolwidgets/circlebrush.py +35 -35
- meerk40t/gui/toolwidgets/toolcircle.py +248 -242
- meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
- meerk40t/gui/toolwidgets/tooldraw.py +97 -90
- meerk40t/gui/toolwidgets/toolellipse.py +219 -212
- meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
- meerk40t/gui/toolwidgets/toolline.py +39 -144
- meerk40t/gui/toolwidgets/toollinetext.py +79 -236
- meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
- meerk40t/gui/toolwidgets/toolmeasure.py +163 -216
- meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
- meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
- meerk40t/gui/toolwidgets/toolparameter.py +754 -668
- meerk40t/gui/toolwidgets/toolplacement.py +108 -108
- meerk40t/gui/toolwidgets/toolpoint.py +68 -59
- meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
- meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
- meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
- meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
- meerk40t/gui/toolwidgets/toolrect.py +211 -207
- meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
- meerk40t/gui/toolwidgets/toolribbon.py +598 -113
- meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
- meerk40t/gui/toolwidgets/tooltext.py +98 -89
- meerk40t/gui/toolwidgets/toolvector.py +213 -204
- meerk40t/gui/toolwidgets/toolwidget.py +39 -39
- meerk40t/gui/usbconnect.py +98 -91
- meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
- meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
- meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
- meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
- meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
- meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
- meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
- meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
- meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
- meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
- meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
- meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
- meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
- meerk40t/gui/wordlisteditor.py +985 -931
- meerk40t/gui/wxmeerk40t.py +1447 -1169
- meerk40t/gui/wxmmain.py +5644 -4112
- meerk40t/gui/wxmribbon.py +1591 -1076
- meerk40t/gui/wxmscene.py +1631 -1453
- meerk40t/gui/wxmtree.py +2416 -2089
- meerk40t/gui/wxutils.py +1769 -1099
- meerk40t/gui/zmatrix.py +102 -102
- meerk40t/image/__init__.py +1 -1
- meerk40t/image/dither.py +429 -0
- meerk40t/image/imagetools.py +2793 -2269
- meerk40t/internal_plugins.py +150 -130
- meerk40t/kernel/__init__.py +63 -12
- meerk40t/kernel/channel.py +259 -212
- meerk40t/kernel/context.py +538 -538
- meerk40t/kernel/exceptions.py +41 -41
- meerk40t/kernel/functions.py +463 -414
- meerk40t/kernel/jobs.py +100 -100
- meerk40t/kernel/kernel.py +3828 -3571
- meerk40t/kernel/lifecycles.py +71 -71
- meerk40t/kernel/module.py +49 -49
- meerk40t/kernel/service.py +147 -147
- meerk40t/kernel/settings.py +383 -343
- meerk40t/lihuiyu/controller.py +883 -876
- meerk40t/lihuiyu/device.py +1181 -1069
- meerk40t/lihuiyu/driver.py +1466 -1372
- meerk40t/lihuiyu/gui/gui.py +127 -106
- meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
- meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
- meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
- meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
- meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
- meerk40t/lihuiyu/interpreter.py +53 -53
- meerk40t/lihuiyu/laserspeed.py +450 -450
- meerk40t/lihuiyu/loader.py +90 -90
- meerk40t/lihuiyu/parser.py +404 -404
- meerk40t/lihuiyu/plugin.py +101 -102
- meerk40t/lihuiyu/tcp_connection.py +111 -109
- meerk40t/main.py +231 -165
- meerk40t/moshi/builder.py +788 -781
- meerk40t/moshi/controller.py +505 -499
- meerk40t/moshi/device.py +495 -442
- meerk40t/moshi/driver.py +862 -696
- meerk40t/moshi/gui/gui.py +78 -76
- meerk40t/moshi/gui/moshicontrollergui.py +538 -522
- meerk40t/moshi/gui/moshidrivergui.py +87 -75
- meerk40t/moshi/plugin.py +43 -43
- meerk40t/network/console_server.py +140 -57
- meerk40t/network/kernelserver.py +10 -9
- meerk40t/network/tcp_server.py +142 -140
- meerk40t/network/udp_server.py +103 -77
- meerk40t/network/web_server.py +404 -0
- meerk40t/newly/controller.py +1158 -1144
- meerk40t/newly/device.py +874 -732
- meerk40t/newly/driver.py +540 -412
- meerk40t/newly/gui/gui.py +219 -188
- meerk40t/newly/gui/newlyconfig.py +116 -101
- meerk40t/newly/gui/newlycontroller.py +193 -186
- meerk40t/newly/gui/operationproperties.py +51 -51
- meerk40t/newly/mock_connection.py +82 -82
- meerk40t/newly/newly_params.py +56 -56
- meerk40t/newly/plugin.py +1214 -1246
- meerk40t/newly/usb_connection.py +322 -322
- meerk40t/rotary/gui/gui.py +52 -46
- meerk40t/rotary/gui/rotarysettings.py +240 -232
- meerk40t/rotary/rotary.py +202 -98
- meerk40t/ruida/control.py +291 -91
- meerk40t/ruida/controller.py +138 -1088
- meerk40t/ruida/device.py +676 -231
- meerk40t/ruida/driver.py +534 -472
- meerk40t/ruida/emulator.py +1494 -1491
- meerk40t/ruida/exceptions.py +4 -4
- meerk40t/ruida/gui/gui.py +71 -76
- meerk40t/ruida/gui/ruidaconfig.py +239 -72
- meerk40t/ruida/gui/ruidacontroller.py +187 -184
- meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
- meerk40t/ruida/loader.py +54 -52
- meerk40t/ruida/mock_connection.py +57 -109
- meerk40t/ruida/plugin.py +124 -87
- meerk40t/ruida/rdjob.py +2084 -945
- meerk40t/ruida/serial_connection.py +116 -0
- meerk40t/ruida/tcp_connection.py +146 -0
- meerk40t/ruida/udp_connection.py +73 -0
- meerk40t/svgelements.py +9671 -9669
- meerk40t/tools/driver_to_path.py +584 -579
- meerk40t/tools/geomstr.py +5583 -4680
- meerk40t/tools/jhfparser.py +357 -292
- meerk40t/tools/kerftest.py +904 -890
- meerk40t/tools/livinghinges.py +1168 -1033
- meerk40t/tools/pathtools.py +987 -949
- meerk40t/tools/pmatrix.py +234 -0
- meerk40t/tools/pointfinder.py +942 -942
- meerk40t/tools/polybool.py +941 -940
- meerk40t/tools/rasterplotter.py +1660 -547
- meerk40t/tools/shxparser.py +1047 -901
- meerk40t/tools/ttfparser.py +726 -446
- meerk40t/tools/zinglplotter.py +595 -593
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/LICENSE +21 -21
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/METADATA +150 -139
- meerk40t-0.9.7020.dist-info/RECORD +446 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/WHEEL +1 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/top_level.txt +0 -1
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/zip-safe +1 -1
- meerk40t/balormk/elementlightjob.py +0 -159
- meerk40t-0.9.3001.dist-info/RECORD +0 -437
- test/bootstrap.py +0 -63
- test/test_cli.py +0 -12
- test/test_core_cutcode.py +0 -418
- test/test_core_elements.py +0 -144
- test/test_core_plotplanner.py +0 -397
- test/test_core_viewports.py +0 -312
- test/test_drivers_grbl.py +0 -108
- test/test_drivers_lihuiyu.py +0 -443
- test/test_drivers_newly.py +0 -113
- test/test_element_degenerate_points.py +0 -43
- test/test_elements_classify.py +0 -97
- test/test_elements_penbox.py +0 -22
- test/test_file_svg.py +0 -176
- test/test_fill.py +0 -155
- test/test_geomstr.py +0 -1523
- test/test_geomstr_nodes.py +0 -18
- test/test_imagetools_actualize.py +0 -306
- test/test_imagetools_wizard.py +0 -258
- test/test_kernel.py +0 -200
- test/test_laser_speeds.py +0 -3303
- test/test_length.py +0 -57
- test/test_lifecycle.py +0 -66
- test/test_operations.py +0 -251
- test/test_operations_hatch.py +0 -57
- test/test_ruida.py +0 -19
- test/test_spooler.py +0 -22
- test/test_tools_rasterplotter.py +0 -29
- test/test_wobble.py +0 -133
- test/test_zingl.py +0 -124
- {test → meerk40t/cylinder}/__init__.py +0 -0
- /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
- {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/entry_points.txt +0 -0
meerk40t/core/wordlist.py
CHANGED
@@ -1,504 +1,513 @@
|
|
1
|
-
"""
|
2
|
-
Base wordlist class that holds some wordlist logic. Most of the interactions with wordlists are done in the
|
3
|
-
elements service.
|
4
|
-
"""
|
5
|
-
|
6
|
-
import csv
|
7
|
-
import json
|
8
|
-
import os
|
9
|
-
import re
|
10
|
-
from copy import copy
|
11
|
-
from datetime import datetime
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# index
|
29
|
-
|
30
|
-
|
31
|
-
"
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"
|
35
|
-
"
|
36
|
-
"
|
37
|
-
"
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"
|
48
|
-
|
49
|
-
|
50
|
-
self.
|
51
|
-
self.
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
self.
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
#
|
135
|
-
# Index
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
if
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
self.content
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
#
|
206
|
-
|
207
|
-
#
|
208
|
-
#
|
209
|
-
# autoincrement =
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
#
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
if
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
self.
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
self.
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
for skey in
|
390
|
-
self.
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
1
|
+
"""
|
2
|
+
Base wordlist class that holds some wordlist logic. Most of the interactions with wordlists are done in the
|
3
|
+
elements service.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import csv
|
7
|
+
import json
|
8
|
+
import os
|
9
|
+
import re
|
10
|
+
from copy import copy
|
11
|
+
from datetime import datetime
|
12
|
+
from ..extra.encode_detect import EncodingDetectFile
|
13
|
+
|
14
|
+
|
15
|
+
class Wordlist:
|
16
|
+
"""
|
17
|
+
The Wordlist class provides some logic to hold, update and maintain a set of
|
18
|
+
variables for text-fields (and later on for other stuff) to allow for
|
19
|
+
on-the-fly recalculation / repopulation
|
20
|
+
"""
|
21
|
+
|
22
|
+
def __init__(self, versionstr, directory=None):
|
23
|
+
# The content-dictionary contains an array per entry
|
24
|
+
# index 0 indicates the type:
|
25
|
+
# 0 (static) text entry
|
26
|
+
# 1 text entry array coming from a csv file
|
27
|
+
# 2 is a numeric counter
|
28
|
+
# index 1 indicates the position of the current array (always 2 for type 0 and 2)
|
29
|
+
# index 2 and onwards contain the actual data
|
30
|
+
self.content = {
|
31
|
+
"version": [0, 2, versionstr],
|
32
|
+
"date": [0, 2, self.wordlist_datestr()],
|
33
|
+
"time": [0, 2, self.wordlist_timestr()],
|
34
|
+
"op_device": [0, 2, "<device>"],
|
35
|
+
"op_speed": [0, 2, "<speed>"],
|
36
|
+
"op_power": [0, 2, "<power>"],
|
37
|
+
"op_passes": [0, 2, "<passes>"],
|
38
|
+
"op_dpi": [0, 2, "<dpi>"],
|
39
|
+
}
|
40
|
+
self.prohibited = (
|
41
|
+
"version",
|
42
|
+
"date",
|
43
|
+
"time",
|
44
|
+
"op_device",
|
45
|
+
"op_speed",
|
46
|
+
"op_power",
|
47
|
+
"op_passes",
|
48
|
+
"op_dpi",
|
49
|
+
)
|
50
|
+
self._stack = list()
|
51
|
+
self.transaction_open = False
|
52
|
+
self.content_backup = {}
|
53
|
+
if directory is None:
|
54
|
+
directory = os.getcwd()
|
55
|
+
self.default_filename = os.path.join(directory, "wordlist.json")
|
56
|
+
self.load_data(self.default_filename)
|
57
|
+
|
58
|
+
def add(self, key, value, wtype=None):
|
59
|
+
self.add_value(key, value, wtype)
|
60
|
+
|
61
|
+
def fetch(self, key):
|
62
|
+
result = self.fetch_value(key, None)
|
63
|
+
return result
|
64
|
+
|
65
|
+
def fetch_value(self, skey, idx):
|
66
|
+
skey = skey.lower()
|
67
|
+
result = None
|
68
|
+
try:
|
69
|
+
wordlist = self.content[skey]
|
70
|
+
except KeyError:
|
71
|
+
return None
|
72
|
+
if skey == "date":
|
73
|
+
return self.wordlist_datestr(None)
|
74
|
+
elif skey == "time":
|
75
|
+
return self.wordlist_timestr(None)
|
76
|
+
# print (f"Retrieve {wordlist} for {skey}")
|
77
|
+
if idx is None: # Default
|
78
|
+
idx = wordlist[1]
|
79
|
+
|
80
|
+
if idx <= len(wordlist):
|
81
|
+
try:
|
82
|
+
result = wordlist[idx]
|
83
|
+
except IndexError:
|
84
|
+
result = None
|
85
|
+
return result
|
86
|
+
|
87
|
+
def add_value(self, skey, value, wtype=None):
|
88
|
+
skey = skey.lower()
|
89
|
+
if skey not in self.content:
|
90
|
+
if wtype is None:
|
91
|
+
wtype = 0
|
92
|
+
self.content[skey] = [
|
93
|
+
wtype,
|
94
|
+
2,
|
95
|
+
] # incomplete, as it will be appended right after this
|
96
|
+
self.content[skey].append(value)
|
97
|
+
|
98
|
+
def delete_value(self, skey, idx):
|
99
|
+
skey = skey.lower()
|
100
|
+
if not skey in self.content:
|
101
|
+
return
|
102
|
+
if idx is None or idx < 0:
|
103
|
+
return
|
104
|
+
|
105
|
+
# Zerobased outside + 2 inside
|
106
|
+
idx += 2
|
107
|
+
if idx >= len(self.content[skey]):
|
108
|
+
return
|
109
|
+
self.content[skey].pop(idx)
|
110
|
+
|
111
|
+
def move_all_indices(self, delta):
|
112
|
+
for wkey in self.content:
|
113
|
+
wordlist = self.content[wkey]
|
114
|
+
if wkey in self.prohibited:
|
115
|
+
continue
|
116
|
+
if wordlist[0] in (0, 1): # Text or csv
|
117
|
+
last_index = len(wordlist) - 1
|
118
|
+
# Zero-based outside, +2 inside
|
119
|
+
newidx = min(wordlist[1] + delta, last_index)
|
120
|
+
if newidx < 2:
|
121
|
+
newidx = 2
|
122
|
+
wordlist[1] = newidx
|
123
|
+
elif wordlist[0] == 2: # Counter-type
|
124
|
+
value = wordlist[2]
|
125
|
+
try:
|
126
|
+
value = int(value) + delta
|
127
|
+
except ValueError:
|
128
|
+
value = 0
|
129
|
+
if value < 0:
|
130
|
+
value = 0
|
131
|
+
wordlist[2] = value
|
132
|
+
|
133
|
+
def set_value(self, skey, value, idx=None, wtype=None):
|
134
|
+
# Special treatment:
|
135
|
+
# Index = None - use current
|
136
|
+
# Index < 0 append
|
137
|
+
skey = skey.lower()
|
138
|
+
if not skey in self.content:
|
139
|
+
# hasn't been there, so establish it
|
140
|
+
if wtype is None:
|
141
|
+
wtype = 0
|
142
|
+
self.content[skey] = [wtype, 2, value]
|
143
|
+
else:
|
144
|
+
if idx is None:
|
145
|
+
# use current position
|
146
|
+
idx = self.content[skey][1]
|
147
|
+
try:
|
148
|
+
idx = int(idx)
|
149
|
+
except ValueError:
|
150
|
+
idx = 0
|
151
|
+
elif idx < 0:
|
152
|
+
# append
|
153
|
+
self.content[skey].append(value)
|
154
|
+
else: # Zerobased outside + 2 inside
|
155
|
+
idx += 2
|
156
|
+
|
157
|
+
if idx >= len(self.content[skey]):
|
158
|
+
idx = len(self.content[skey]) - 1
|
159
|
+
self.content[skey][idx] = value
|
160
|
+
|
161
|
+
def set_index(self, skey, idx, wtype=None):
|
162
|
+
skey = skey.lower()
|
163
|
+
|
164
|
+
if isinstance(idx, str):
|
165
|
+
relative = idx.startswith("+") or idx.startswith("-")
|
166
|
+
index = int(idx)
|
167
|
+
else:
|
168
|
+
relative = False
|
169
|
+
index = idx
|
170
|
+
wordlists = []
|
171
|
+
|
172
|
+
if skey == "@all": # Set it for all fields from a csv file
|
173
|
+
wordlists.extend(self.content)
|
174
|
+
else:
|
175
|
+
wordlists.extend(list(skey.split(",")))
|
176
|
+
for wkey in wordlists:
|
177
|
+
if wkey not in self.content:
|
178
|
+
continue
|
179
|
+
wordlist = self.content[wkey]
|
180
|
+
if (
|
181
|
+
wordlist[0] in (0, 1) and wkey not in self.prohibited
|
182
|
+
): # Variable Wordlist type.
|
183
|
+
last_index = len(wordlist) - 1
|
184
|
+
# Zero-based outside, +2 inside
|
185
|
+
if relative:
|
186
|
+
self.content[wkey][1] = min(wordlist[1] + index, last_index)
|
187
|
+
else:
|
188
|
+
self.content[wkey][1] = min(index + 2, last_index)
|
189
|
+
|
190
|
+
def reset(self, skey=None):
|
191
|
+
# Resets position
|
192
|
+
skey = skey.lower()
|
193
|
+
if skey is None:
|
194
|
+
for skey in self.content:
|
195
|
+
self.content[skey][1] = 2
|
196
|
+
else:
|
197
|
+
self.content[skey][1] = 2
|
198
|
+
|
199
|
+
def translate(self, pattern, increment=True):
|
200
|
+
if pattern is None:
|
201
|
+
return ""
|
202
|
+
result = str(pattern)
|
203
|
+
brackets = re.compile(r"\{[^}]+\}")
|
204
|
+
for bracketed_key in brackets.findall(result):
|
205
|
+
# print(f"Key found: {bracketed_key}")
|
206
|
+
key = bracketed_key[1:-1].lower().strip()
|
207
|
+
# Let's check whether we have a modifier at the end: #<num>
|
208
|
+
# if key.endswith("++"):
|
209
|
+
# autoincrement = True
|
210
|
+
# key = key[:-2].strip()
|
211
|
+
# else:
|
212
|
+
# autoincrement = False
|
213
|
+
autoincrement = False
|
214
|
+
|
215
|
+
reset = False
|
216
|
+
relative = 0
|
217
|
+
pos = key.find("#")
|
218
|
+
if pos > 0: # Needs to be after first character
|
219
|
+
# Process offset modification.
|
220
|
+
index_string = key[pos + 1 :]
|
221
|
+
key = key[:pos].strip()
|
222
|
+
|
223
|
+
if not index_string.startswith("+") and not index_string.startswith(
|
224
|
+
"-"
|
225
|
+
):
|
226
|
+
# We have a #<index> value without + or -, specific index value from 0
|
227
|
+
reset = True
|
228
|
+
try:
|
229
|
+
# This covers +x, -x, x
|
230
|
+
relative = int(index_string)
|
231
|
+
except ValueError:
|
232
|
+
relative = 0
|
233
|
+
|
234
|
+
# And now date and time...
|
235
|
+
if key == "date":
|
236
|
+
# Do we have a format str?
|
237
|
+
sformat = None
|
238
|
+
if key in self.content:
|
239
|
+
value = self.fetch_value(key, 2)
|
240
|
+
if value is not None and isinstance(value, str) and len(value) > 0:
|
241
|
+
if "%" in value:
|
242
|
+
# Seems to be a format string, so let's try it...
|
243
|
+
sformat = value
|
244
|
+
value = self.wordlist_datestr(sformat)
|
245
|
+
elif key == "time":
|
246
|
+
# Do we have a format str?
|
247
|
+
sformat = None
|
248
|
+
if key in self.content:
|
249
|
+
value = self.fetch_value(key, 2)
|
250
|
+
if value is not None and isinstance(value, str) and len(value) > 0:
|
251
|
+
if "%" in value:
|
252
|
+
# Seems to be a format string, so let's try it...
|
253
|
+
sformat = value
|
254
|
+
value = self.wordlist_timestr(sformat)
|
255
|
+
elif key.startswith("date@"):
|
256
|
+
# Original cASEs, vkey is already lowered...
|
257
|
+
sformat = bracketed_key[6:-1]
|
258
|
+
value = self.wordlist_datestr(sformat)
|
259
|
+
elif key.startswith("time@"):
|
260
|
+
# Original cASEs, vkey is already lowered...
|
261
|
+
sformat = bracketed_key[6:-1]
|
262
|
+
value = self.wordlist_timestr(sformat)
|
263
|
+
else:
|
264
|
+
# Must be a wordlist type.
|
265
|
+
if key not in self.content:
|
266
|
+
# This is not a wordlist name.
|
267
|
+
continue
|
268
|
+
wordlist = self.content[key]
|
269
|
+
|
270
|
+
if wordlist[0] == 2: # Counter-type
|
271
|
+
# Counter index is the value.
|
272
|
+
value = wordlist[2] if not reset else 0
|
273
|
+
try:
|
274
|
+
value = int(value)
|
275
|
+
except ValueError:
|
276
|
+
value = 0
|
277
|
+
value += relative
|
278
|
+
if autoincrement and increment:
|
279
|
+
# autoincrement of counter means value + 1
|
280
|
+
wordlist[2] = value + 1
|
281
|
+
else:
|
282
|
+
# This is a variable wordlist.
|
283
|
+
current_index = wordlist[1] if not reset else 2 # 2 as 2 based
|
284
|
+
current_index += relative
|
285
|
+
value = self.fetch_value(key, current_index)
|
286
|
+
if autoincrement and increment:
|
287
|
+
# Index set to current index + 1
|
288
|
+
wordlist[1] = current_index + 1
|
289
|
+
|
290
|
+
if value is not None:
|
291
|
+
result = result.replace(bracketed_key, str(value))
|
292
|
+
|
293
|
+
return result
|
294
|
+
|
295
|
+
@staticmethod
|
296
|
+
def wordlist_datestr(format=None):
|
297
|
+
time = datetime.now()
|
298
|
+
if format is None:
|
299
|
+
format = "%x"
|
300
|
+
try:
|
301
|
+
result = time.strftime(format)
|
302
|
+
except:
|
303
|
+
result = "invalid"
|
304
|
+
return result
|
305
|
+
|
306
|
+
@staticmethod
|
307
|
+
def wordlist_timestr(format=None):
|
308
|
+
time = datetime.now()
|
309
|
+
if format is None:
|
310
|
+
format = "%X"
|
311
|
+
try:
|
312
|
+
result = time.strftime(format)
|
313
|
+
except ValueError:
|
314
|
+
result = "invalid"
|
315
|
+
return result
|
316
|
+
|
317
|
+
def get_variable_list(self):
|
318
|
+
choices = []
|
319
|
+
for skey in self.content:
|
320
|
+
value = self.fetch(skey)
|
321
|
+
choices.append(f"{skey} ({value})")
|
322
|
+
return choices
|
323
|
+
|
324
|
+
def begin_transaction(self):
|
325
|
+
# We want to store all our values
|
326
|
+
if not self.transaction_open:
|
327
|
+
self.content_backup = {}
|
328
|
+
for key in self.content:
|
329
|
+
item = copy(self.content[key])
|
330
|
+
self.content_backup[key] = item
|
331
|
+
self.transaction_open = True
|
332
|
+
|
333
|
+
def rollback_transaction(self):
|
334
|
+
if self.transaction_open:
|
335
|
+
self.content = {}
|
336
|
+
for key in self.content_backup:
|
337
|
+
item = copy(self.content_backup[key])
|
338
|
+
self.content[key] = item
|
339
|
+
self.transaction_open = False
|
340
|
+
self.content_backup = {}
|
341
|
+
|
342
|
+
def commit_transaction(self):
|
343
|
+
if self.transaction_open:
|
344
|
+
self.transaction_open = False
|
345
|
+
self.content_backup = {}
|
346
|
+
|
347
|
+
def load_data(self, filename):
|
348
|
+
if filename is None:
|
349
|
+
filename = self.default_filename
|
350
|
+
try:
|
351
|
+
with open(filename) as f:
|
352
|
+
self.content = json.load(f)
|
353
|
+
except (json.JSONDecodeError, PermissionError, OSError, FileNotFoundError):
|
354
|
+
pass
|
355
|
+
self.transaction_open = False
|
356
|
+
|
357
|
+
def save_data(self, filename):
|
358
|
+
if filename is None:
|
359
|
+
filename = self.default_filename
|
360
|
+
with open(filename, "w") as f:
|
361
|
+
json.dump(self.content, f)
|
362
|
+
self.transaction_open = False
|
363
|
+
|
364
|
+
def delete(self, skey):
|
365
|
+
try:
|
366
|
+
self.content.pop(skey)
|
367
|
+
except KeyError:
|
368
|
+
pass
|
369
|
+
|
370
|
+
def rename_key(self, oldkey, newkey):
|
371
|
+
oldkey = oldkey.lower()
|
372
|
+
newkey = newkey.lower()
|
373
|
+
if oldkey in self.prohibited:
|
374
|
+
return False
|
375
|
+
if oldkey == newkey:
|
376
|
+
return True
|
377
|
+
if newkey in self.content:
|
378
|
+
return False
|
379
|
+
try:
|
380
|
+
self.content[newkey] = self.content[oldkey]
|
381
|
+
self.delete(oldkey)
|
382
|
+
except:
|
383
|
+
return False
|
384
|
+
return True
|
385
|
+
|
386
|
+
def empty_csv(self):
|
387
|
+
# remove all traces of the previous csv file
|
388
|
+
names = []
|
389
|
+
for skey in self.content:
|
390
|
+
if self.content[skey][0] == 1: # csv
|
391
|
+
names.append(skey)
|
392
|
+
for skey in names:
|
393
|
+
self.delete(skey)
|
394
|
+
|
395
|
+
def load_csv_file(self, filename, force_header=None):
|
396
|
+
self.empty_csv()
|
397
|
+
headers = []
|
398
|
+
decoder = EncodingDetectFile()
|
399
|
+
result = decoder.load(filename)
|
400
|
+
if result:
|
401
|
+
encoding, bom_marker, file_content = result
|
402
|
+
|
403
|
+
try:
|
404
|
+
with open(filename, newline="", encoding=encoding) as csvfile:
|
405
|
+
buffer = csvfile.read(1024)
|
406
|
+
if force_header is None:
|
407
|
+
has_header = csv.Sniffer().has_header(buffer)
|
408
|
+
else:
|
409
|
+
has_header = force_header
|
410
|
+
# print (f"Header={has_header}, Force={force_header}")
|
411
|
+
dialect = csv.Sniffer().sniff(buffer)
|
412
|
+
csvfile.seek(0)
|
413
|
+
reader = csv.reader(csvfile, dialect)
|
414
|
+
headers = next(reader)
|
415
|
+
if not has_header:
|
416
|
+
# Use Line as Data and set some default names
|
417
|
+
for idx, entry in enumerate(headers):
|
418
|
+
skey = f"Column_{idx + 1}"
|
419
|
+
self.set_value(skey=skey, value=entry, idx=-1, wtype=1)
|
420
|
+
headers[idx] = skey.lower()
|
421
|
+
ct = 1
|
422
|
+
else:
|
423
|
+
ct = 0
|
424
|
+
for row in reader:
|
425
|
+
for idx, entry in enumerate(row):
|
426
|
+
skey = headers[idx].lower()
|
427
|
+
if skey.startswith("\\ufeff"):
|
428
|
+
skey = skey[7:]
|
429
|
+
# Append...
|
430
|
+
self.set_value(skey=skey, value=entry, idx=-1, wtype=1)
|
431
|
+
ct += 1
|
432
|
+
except (csv.Error, PermissionError, OSError, FileNotFoundError) as e:
|
433
|
+
ct = 0
|
434
|
+
headers = []
|
435
|
+
colcount = len(headers)
|
436
|
+
return ct, colcount, headers
|
437
|
+
|
438
|
+
def wordlist_delta(self, orgtext, increase):
|
439
|
+
newtext = str(orgtext)
|
440
|
+
toreplace = []
|
441
|
+
# list of tuples, (index found, old, new )
|
442
|
+
# Let's gather the {} first...
|
443
|
+
brackets = re.compile(r"\{[^}]+\}")
|
444
|
+
for bracketed_key in brackets.findall(str(orgtext)):
|
445
|
+
key = bracketed_key[1:-1].lower().strip()
|
446
|
+
relative = 0
|
447
|
+
pos = key.find("#")
|
448
|
+
if pos > 0:
|
449
|
+
# Needs to be after first character
|
450
|
+
# Process offset modification.
|
451
|
+
index_string = key[pos + 1 :]
|
452
|
+
key = key[:pos].strip()
|
453
|
+
|
454
|
+
if not index_string.startswith("+") and not index_string.startswith(
|
455
|
+
"-"
|
456
|
+
):
|
457
|
+
# We have a #<index> value without + or -, specific index value from 0
|
458
|
+
# no need to do something
|
459
|
+
continue
|
460
|
+
try:
|
461
|
+
# This covers +x, -x, x
|
462
|
+
relative = int(index_string)
|
463
|
+
except ValueError:
|
464
|
+
relative = 0
|
465
|
+
else:
|
466
|
+
# it's the unmodified key...
|
467
|
+
if key.startswith("time@"):
|
468
|
+
key = "time"
|
469
|
+
elif key.startswith("date@"):
|
470
|
+
key = "date"
|
471
|
+
if key not in self.content:
|
472
|
+
continue
|
473
|
+
if key in self.prohibited:
|
474
|
+
continue
|
475
|
+
newindex = relative + increase
|
476
|
+
if newindex > 0:
|
477
|
+
newpattern = f"{{{key}#+{newindex}}}"
|
478
|
+
elif newindex < 0:
|
479
|
+
newpattern = f"{{{key}#{newindex}}}"
|
480
|
+
else:
|
481
|
+
# 0
|
482
|
+
newpattern = f"{{{key}}}"
|
483
|
+
if newpattern != bracketed_key:
|
484
|
+
item = [relative, bracketed_key, newpattern]
|
485
|
+
toreplace.append(item)
|
486
|
+
|
487
|
+
# Then sort the list according to the direction,
|
488
|
+
# as we don't want to replace the same pattern again and again
|
489
|
+
if increase >= 0:
|
490
|
+
toreplace.sort(key=lambda n: n[0])
|
491
|
+
else:
|
492
|
+
toreplace.sort(reverse=True, key=lambda n: n[0])
|
493
|
+
for item in toreplace:
|
494
|
+
newtext = newtext.replace(item[1], item[2])
|
495
|
+
return newtext
|
496
|
+
|
497
|
+
def push(self):
|
498
|
+
"""Stores the current content on the stack"""
|
499
|
+
copied_content = {}
|
500
|
+
for key, entry in self.content.items():
|
501
|
+
copied_content[key] = copy(entry)
|
502
|
+
self._stack.append(copied_content)
|
503
|
+
# print (f"push was called, when name was: '{self.content['name']}'")
|
504
|
+
|
505
|
+
def pop(self):
|
506
|
+
"""Restores the last added stack entry"""
|
507
|
+
if len(self._stack) > 0:
|
508
|
+
copied_content = self._stack[-1]
|
509
|
+
self._stack.pop(-1)
|
510
|
+
self.content = {}
|
511
|
+
for key, entry in copied_content.items():
|
512
|
+
self.content[key] = copy(entry)
|
513
|
+
# print (f"pop was called, name now '{self.content['name']}'")
|