├── .gitignore ├── LICENSE ├── Pipfile ├── Pipfile.lock ├── README.md ├── hera.dist-info ├── INSTALLER └── METADATA ├── hera ├── __init__.py ├── __main__.py └── app.py ├── icons ├── Hera.icns └── JupyterDoc.icns └── pyproject.toml /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # OSX useful to ignore 7 | *.DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Thumbnails 12 | ._* 13 | 14 | # Files that might appear in the root of a volume 15 | .DocumentRevisions-V100 16 | .fseventsd 17 | .Spotlight-V100 18 | .TemporaryItems 19 | .Trashes 20 | .VolumeIcon.icns 21 | .com.apple.timemachine.donotpresent 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | # C extensions 31 | *.so 32 | 33 | # Distribution / packaging 34 | .Python 35 | env/ 36 | build/ 37 | develop-eggs/ 38 | dist/ 39 | downloads/ 40 | eggs/ 41 | .eggs/ 42 | lib/ 43 | lib64/ 44 | parts/ 45 | sdist/ 46 | var/ 47 | *.egg-info/ 48 | .installed.cfg 49 | *.egg 50 | 51 | # IntelliJ Idea family of suites 52 | .idea 53 | *.iml 54 | ## File-based project format: 55 | *.ipr 56 | *.iws 57 | ## mpeltonen/sbt-idea plugin 58 | .idea_modules/ 59 | 60 | # Briefcase build directories 61 | iOS/ 62 | macOS/ 63 | windows/ 64 | android/ 65 | linux/ 66 | django/ 67 | 68 | .ipynb_checkpoints/ 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2018, Philip James 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | jupyter = "*" 8 | toga = "==0.3.0.dev19" 9 | briefcase = "*" 10 | cookiecutter = "*" 11 | pathlib = "*" 12 | 13 | [dev-packages] 14 | 15 | [requires] 16 | python_version = "3.7" 17 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "e532c662784ca37df2c8356892463f76feb30a5b36550b7debd56b0e02a4ba12" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.7" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "appnope": { 20 | "hashes": [ 21 | "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", 22 | "sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71" 23 | ], 24 | "markers": "sys_platform == 'darwin'", 25 | "version": "==0.1.0" 26 | }, 27 | "arrow": { 28 | "hashes": [ 29 | "sha256:5390e464e2c5f76971b60ffa7ee29c598c7501a294bc9f5e6dadcb251a5d027b", 30 | "sha256:70729bcc831da496ca3cb4b7e89472c8e2d27d398908155e0796179f6d2d41ee" 31 | ], 32 | "version": "==0.15.5" 33 | }, 34 | "attrs": { 35 | "hashes": [ 36 | "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", 37 | "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" 38 | ], 39 | "version": "==19.3.0" 40 | }, 41 | "backcall": { 42 | "hashes": [ 43 | "sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4", 44 | "sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2" 45 | ], 46 | "version": "==0.1.0" 47 | }, 48 | "binaryornot": { 49 | "hashes": [ 50 | "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061", 51 | "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4" 52 | ], 53 | "version": "==0.4.4" 54 | }, 55 | "biplist": { 56 | "hashes": [ 57 | "sha256:4c0549764c5fe50b28042ec21aa2e14fe1a2224e239a1dae77d9e7f3932aa4c6" 58 | ], 59 | "version": "==1.0.3" 60 | }, 61 | "bleach": { 62 | "hashes": [ 63 | "sha256:cc8da25076a1fe56c3ac63671e2194458e0c4d9c7becfd52ca251650d517903c", 64 | "sha256:e78e426105ac07026ba098f04de8abe9b6e3e98b5befbf89b51a5ef0a4292b03" 65 | ], 66 | "version": "==3.1.4" 67 | }, 68 | "briefcase": { 69 | "hashes": [ 70 | "sha256:380cbb0a4e70b7eeb7039d290c604c6a51ec4fccc5a2193be3831fcba503bd66", 71 | "sha256:38f18a32332798207554c747ad0c46de181b40a322c7968f9684a3b65c7c9e03" 72 | ], 73 | "index": "pypi", 74 | "version": "==0.3.0" 75 | }, 76 | "certifi": { 77 | "hashes": [ 78 | "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", 79 | "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" 80 | ], 81 | "version": "==2020.4.5.1" 82 | }, 83 | "chardet": { 84 | "hashes": [ 85 | "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", 86 | "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" 87 | ], 88 | "version": "==3.0.4" 89 | }, 90 | "click": { 91 | "hashes": [ 92 | "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", 93 | "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" 94 | ], 95 | "version": "==7.1.1" 96 | }, 97 | "cookiecutter": { 98 | "hashes": [ 99 | "sha256:430eb882d028afb6102c084bab6cf41f6559a77ce9b18dc6802e3bc0cc5f4a30", 100 | "sha256:efb6b2d4780feda8908a873e38f0e61778c23f6a2ea58215723bcceb5b515dac" 101 | ], 102 | "index": "pypi", 103 | "version": "==1.7.2" 104 | }, 105 | "decorator": { 106 | "hashes": [ 107 | "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760", 108 | "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7" 109 | ], 110 | "version": "==4.4.2" 111 | }, 112 | "defusedxml": { 113 | "hashes": [ 114 | "sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93", 115 | "sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5" 116 | ], 117 | "version": "==0.6.0" 118 | }, 119 | "dmgbuild": { 120 | "hashes": [ 121 | "sha256:2004a3a304bd29ac541af990a2b1d531b82c49f9465dbbf33e5b30efc48b620d" 122 | ], 123 | "markers": "sys_platform == 'darwin'", 124 | "version": "==1.3.3" 125 | }, 126 | "ds-store": { 127 | "hashes": [ 128 | "sha256:f569659cfd66b21273c5a2405d5e1e0f54fddebf627130329f01404f271a074c" 129 | ], 130 | "version": "==1.1.2" 131 | }, 132 | "entrypoints": { 133 | "hashes": [ 134 | "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", 135 | "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" 136 | ], 137 | "version": "==0.3" 138 | }, 139 | "gitdb": { 140 | "hashes": [ 141 | "sha256:6f0ecd46f99bb4874e5678d628c3a198e2b4ef38daea2756a2bfd8df7dd5c1a5", 142 | "sha256:ba1132c0912e8c917aa8aa990bee26315064c7b7f171ceaaac0afeb1dc656c6a" 143 | ], 144 | "version": "==4.0.4" 145 | }, 146 | "gitpython": { 147 | "hashes": [ 148 | "sha256:6d4f10e2aaad1864bb0f17ec06a2c2831534140e5883c350d58b4e85189dab74", 149 | "sha256:71b8dad7409efbdae4930f2b0b646aaeccce292484ffa0bc74f1195582578b3d" 150 | ], 151 | "version": "==3.1.1" 152 | }, 153 | "idna": { 154 | "hashes": [ 155 | "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", 156 | "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" 157 | ], 158 | "version": "==2.9" 159 | }, 160 | "importlib-metadata": { 161 | "hashes": [ 162 | "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", 163 | "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" 164 | ], 165 | "markers": "python_version < '3.8'", 166 | "version": "==1.6.0" 167 | }, 168 | "ipykernel": { 169 | "hashes": [ 170 | "sha256:003c9c1ab6ff87d11f531fee2b9ca59affab19676fc6b2c21da329aef6e73499", 171 | "sha256:2937373c356fa5b634edb175c5ea0e4b25de8008f7c194f2d49cfbd1f9c970a8" 172 | ], 173 | "version": "==5.2.1" 174 | }, 175 | "ipython": { 176 | "hashes": [ 177 | "sha256:ca478e52ae1f88da0102360e57e528b92f3ae4316aabac80a2cd7f7ab2efb48a", 178 | "sha256:eb8d075de37f678424527b5ef6ea23f7b80240ca031c2dd6de5879d687a65333" 179 | ], 180 | "markers": "python_version >= '3.3'", 181 | "version": "==7.13.0" 182 | }, 183 | "ipython-genutils": { 184 | "hashes": [ 185 | "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", 186 | "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" 187 | ], 188 | "version": "==0.2.0" 189 | }, 190 | "ipywidgets": { 191 | "hashes": [ 192 | "sha256:13ffeca438e0c0f91ae583dc22f50379b9d6b28390ac7be8b757140e9a771516", 193 | "sha256:e945f6e02854a74994c596d9db83444a1850c01648f1574adf144fbbabe05c97" 194 | ], 195 | "version": "==7.5.1" 196 | }, 197 | "jedi": { 198 | "hashes": [ 199 | "sha256:cd60c93b71944d628ccac47df9a60fec53150de53d42dc10a7fc4b5ba6aae798", 200 | "sha256:df40c97641cb943661d2db4c33c2e1ff75d491189423249e989bcea4464f3030" 201 | ], 202 | "version": "==0.17.0" 203 | }, 204 | "jinja2": { 205 | "hashes": [ 206 | "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0", 207 | "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035" 208 | ], 209 | "version": "==2.11.2" 210 | }, 211 | "jinja2-time": { 212 | "hashes": [ 213 | "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40", 214 | "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa" 215 | ], 216 | "version": "==0.2.0" 217 | }, 218 | "jsonschema": { 219 | "hashes": [ 220 | "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", 221 | "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" 222 | ], 223 | "version": "==3.2.0" 224 | }, 225 | "jupyter": { 226 | "hashes": [ 227 | "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7", 228 | "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78", 229 | "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f" 230 | ], 231 | "index": "pypi", 232 | "version": "==1.0.0" 233 | }, 234 | "jupyter-client": { 235 | "hashes": [ 236 | "sha256:3a32fa4d0b16d1c626b30c3002a62dfd86d6863ed39eaba3f537fade197bb756", 237 | "sha256:cde8e83aab3ec1c614f221ae54713a9a46d3bf28292609d2db1b439bef5a8c8e" 238 | ], 239 | "version": "==6.1.3" 240 | }, 241 | "jupyter-console": { 242 | "hashes": [ 243 | "sha256:6f6ead433b0534909df789ea64f0a14cdf9b6b2360757756f08182be4b9e431b", 244 | "sha256:b392155112ec86a329df03b225749a0fa903aa80811e8eda55796a40b5e470d8" 245 | ], 246 | "version": "==6.1.0" 247 | }, 248 | "jupyter-core": { 249 | "hashes": [ 250 | "sha256:394fd5dd787e7c8861741880bdf8a00ce39f95de5d18e579c74b882522219e7e", 251 | "sha256:a4ee613c060fe5697d913416fc9d553599c05e4492d58fac1192c9a6844abb21" 252 | ], 253 | "version": "==4.6.3" 254 | }, 255 | "mac-alias": { 256 | "hashes": [ 257 | "sha256:c485e3eb9d600208cc0aa906282f0d575a535395306289bcdb4096599189e223" 258 | ], 259 | "version": "==2.0.7" 260 | }, 261 | "markupsafe": { 262 | "hashes": [ 263 | "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", 264 | "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", 265 | "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", 266 | "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", 267 | "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", 268 | "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", 269 | "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", 270 | "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", 271 | "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", 272 | "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", 273 | "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", 274 | "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", 275 | "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", 276 | "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", 277 | "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", 278 | "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", 279 | "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", 280 | "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", 281 | "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", 282 | "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", 283 | "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", 284 | "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", 285 | "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", 286 | "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", 287 | "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", 288 | "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", 289 | "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", 290 | "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", 291 | "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", 292 | "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", 293 | "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", 294 | "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", 295 | "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" 296 | ], 297 | "version": "==1.1.1" 298 | }, 299 | "mistune": { 300 | "hashes": [ 301 | "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", 302 | "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4" 303 | ], 304 | "version": "==0.8.4" 305 | }, 306 | "nbconvert": { 307 | "hashes": [ 308 | "sha256:21fb48e700b43e82ba0e3142421a659d7739b65568cc832a13976a77be16b523", 309 | "sha256:f0d6ec03875f96df45aa13e21fd9b8450c42d7e1830418cccc008c0df725fcee" 310 | ], 311 | "version": "==5.6.1" 312 | }, 313 | "nbformat": { 314 | "hashes": [ 315 | "sha256:049af048ed76b95c3c44043620c17e56bc001329e07f83fec4f177f0e3d7b757", 316 | "sha256:276343c78a9660ab2a63c28cc33da5f7c58c092b3f3a40b6017ae2ce6689320d" 317 | ], 318 | "version": "==5.0.6" 319 | }, 320 | "notebook": { 321 | "hashes": [ 322 | "sha256:3edc616c684214292994a3af05eaea4cc043f6b4247d830f3a2f209fa7639a80", 323 | "sha256:47a9092975c9e7965ada00b9a20f0cf637d001db60d241d479f53c0be117ad48" 324 | ], 325 | "version": "==6.0.3" 326 | }, 327 | "pandocfilters": { 328 | "hashes": [ 329 | "sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9" 330 | ], 331 | "version": "==1.4.2" 332 | }, 333 | "parso": { 334 | "hashes": [ 335 | "sha256:158c140fc04112dc45bca311633ae5033c2c2a7b732fa33d0955bad8152a8dd0", 336 | "sha256:908e9fae2144a076d72ae4e25539143d40b8e3eafbaeae03c1bfe226f4cdf12c" 337 | ], 338 | "version": "==0.7.0" 339 | }, 340 | "pathlib": { 341 | "hashes": [ 342 | "sha256:6940718dfc3eff4258203ad5021090933e5c04707d5ca8cc9e73c94a7894ea9f" 343 | ], 344 | "index": "pypi", 345 | "version": "==1.0.1" 346 | }, 347 | "pexpect": { 348 | "hashes": [ 349 | "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", 350 | "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" 351 | ], 352 | "markers": "sys_platform != 'win32'", 353 | "version": "==4.8.0" 354 | }, 355 | "pickleshare": { 356 | "hashes": [ 357 | "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", 358 | "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" 359 | ], 360 | "version": "==0.7.5" 361 | }, 362 | "poyo": { 363 | "hashes": [ 364 | "sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a", 365 | "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd" 366 | ], 367 | "version": "==0.5.0" 368 | }, 369 | "prometheus-client": { 370 | "hashes": [ 371 | "sha256:71cd24a2b3eb335cb800c7159f423df1bd4dcd5171b234be15e3f31ec9f622da" 372 | ], 373 | "version": "==0.7.1" 374 | }, 375 | "prompt-toolkit": { 376 | "hashes": [ 377 | "sha256:563d1a4140b63ff9dd587bda9557cffb2fe73650205ab6f4383092fb882e7dc8", 378 | "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04" 379 | ], 380 | "version": "==3.0.5" 381 | }, 382 | "ptyprocess": { 383 | "hashes": [ 384 | "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", 385 | "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" 386 | ], 387 | "markers": "os_name != 'nt'", 388 | "version": "==0.6.0" 389 | }, 390 | "pygments": { 391 | "hashes": [ 392 | "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44", 393 | "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324" 394 | ], 395 | "version": "==2.6.1" 396 | }, 397 | "pyrsistent": { 398 | "hashes": [ 399 | "sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3" 400 | ], 401 | "version": "==0.16.0" 402 | }, 403 | "python-dateutil": { 404 | "hashes": [ 405 | "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", 406 | "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" 407 | ], 408 | "version": "==2.8.1" 409 | }, 410 | "python-slugify": { 411 | "hashes": [ 412 | "sha256:a8fc3433821140e8f409a9831d13ae5deccd0b033d4744d94b31fea141bdd84c" 413 | ], 414 | "version": "==4.0.0" 415 | }, 416 | "pyzmq": { 417 | "hashes": [ 418 | "sha256:0bbc1728fe4314b4ca46249c33873a390559edac7c217ec7001b5e0c34a8fb7f", 419 | "sha256:1e076ad5bd3638a18c376544d32e0af986ca10d43d4ce5a5d889a8649f0d0a3d", 420 | "sha256:242d949eb6b10197cda1d1cec377deab1d5324983d77e0d0bf9dc5eb6d71a6b4", 421 | "sha256:26f4ae420977d2a8792d7c2d7bda43128b037b5eeb21c81951a94054ad8b8843", 422 | "sha256:32234c21c5e0a767c754181c8112092b3ddd2e2a36c3f76fc231ced817aeee47", 423 | "sha256:3f12ce1e9cc9c31497bd82b207e8e86ccda9eebd8c9f95053aae46d15ccd2196", 424 | "sha256:4557d5e036e6d85715b4b9fdb482081398da1d43dc580d03db642b91605b409f", 425 | "sha256:4f562dab21c03c7aa061f63b147a595dbe1006bf4f03213272fc9f7d5baec791", 426 | "sha256:5e071b834051e9ecb224915398f474bfad802c2fff883f118ff5363ca4ae3edf", 427 | "sha256:5e1f65e576ab07aed83f444e201d86deb01cd27dcf3f37c727bc8729246a60a8", 428 | "sha256:5f10a31f288bf055be76c57710807a8f0efdb2b82be6c2a2b8f9a61f33a40cea", 429 | "sha256:6aaaf90b420dc40d9a0e1996b82c6a0ff91d9680bebe2135e67c9e6d197c0a53", 430 | "sha256:75238d3c16cab96947705d5709187a49ebb844f54354cdf0814d195dd4c045de", 431 | "sha256:7f7e7b24b1d392bb5947ba91c981e7d1a43293113642e0d8870706c8e70cdc71", 432 | "sha256:84b91153102c4bcf5d0f57d1a66a0f03c31e9e6525a5f656f52fc615a675c748", 433 | "sha256:944f6bb5c63140d76494467444fd92bebd8674236837480a3c75b01fe17df1ab", 434 | "sha256:a1f957c20c9f51d43903881399b078cddcf710d34a2950e88bce4e494dcaa4d1", 435 | "sha256:a49fd42a29c1cc1aa9f461c5f2f5e0303adba7c945138b35ee7f4ab675b9f754", 436 | "sha256:a99ae601b4f6917985e9bb071549e30b6f93c72f5060853e197bdc4b7d357e5f", 437 | "sha256:ad48865a29efa8a0cecf266432ea7bc34e319954e55cf104be0319c177e6c8f5", 438 | "sha256:b08e425cf93b4e018ab21dc8fdbc25d7d0502a23cc4fea2380010cf8cf11e462", 439 | "sha256:bb10361293d96aa92be6261fa4d15476bca56203b3a11c62c61bd14df0ef89ba", 440 | "sha256:bd1a769d65257a7a12e2613070ca8155ee348aa9183f2aadf1c8b8552a5510f5", 441 | "sha256:cb3b7156ef6b1a119e68fbe3a54e0a0c40ecacc6b7838d57dd708c90b62a06dc", 442 | "sha256:e8e4efb52ec2df8d046395ca4c84ae0056cf507b2f713ec803c65a8102d010de", 443 | "sha256:f37c29da2a5b0c5e31e6f8aab885625ea76c807082f70b2d334d3fd573c3100a", 444 | "sha256:f4d558bc5668d2345773a9ff8c39e2462dafcb1f6772a2e582fbced389ce527f", 445 | "sha256:f5b6d015587a1d6f582ba03b226a9ddb1dfb09878b3be04ef48b01b7d4eb6b2a" 446 | ], 447 | "version": "==19.0.0" 448 | }, 449 | "qtconsole": { 450 | "hashes": [ 451 | "sha256:8f5ae5571f0e921db9f2d12613ed667c350ee22c7db598d9bbbe143e8533f932", 452 | "sha256:e7882df6e95ec710b5893ec3a7ebfd54e410e63d801e4bbf8c785d74758c2329" 453 | ], 454 | "version": "==4.7.3" 455 | }, 456 | "qtpy": { 457 | "hashes": [ 458 | "sha256:2db72c44b55d0fe1407be8fba35c838ad0d6d3bb81f23007886dc1fc0f459c8d", 459 | "sha256:fa0b8363b363e89b2a6f49eddc162a04c0699ae95e109a6be3bb145a913190ea" 460 | ], 461 | "version": "==1.9.0" 462 | }, 463 | "requests": { 464 | "hashes": [ 465 | "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee", 466 | "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6" 467 | ], 468 | "version": "==2.23.0" 469 | }, 470 | "rubicon-objc": { 471 | "hashes": [ 472 | "sha256:4d74732edca4059e22cdaf04806c22f8535ef2de2bc16fe085c3748fd757b5a1", 473 | "sha256:51d19a274f438e004e8a4c39b2e4067d287e79eff80bde582f6b00855e25b345" 474 | ], 475 | "version": "==0.3.1" 476 | }, 477 | "send2trash": { 478 | "hashes": [ 479 | "sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2", 480 | "sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b" 481 | ], 482 | "version": "==1.5.0" 483 | }, 484 | "six": { 485 | "hashes": [ 486 | "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", 487 | "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" 488 | ], 489 | "version": "==1.14.0" 490 | }, 491 | "smmap": { 492 | "hashes": [ 493 | "sha256:52ea78b3e708d2c2b0cfe93b6fc3fbeec53db913345c26be6ed84c11ed8bebc1", 494 | "sha256:b46d3fc69ba5f367df96d91f8271e8ad667a198d5a28e215a6c3d9acd133a911" 495 | ], 496 | "version": "==3.0.2" 497 | }, 498 | "terminado": { 499 | "hashes": [ 500 | "sha256:4804a774f802306a7d9af7322193c5390f1da0abb429e082a10ef1d46e6fb2c2", 501 | "sha256:a43dcb3e353bc680dd0783b1d9c3fc28d529f190bc54ba9a229f72fe6e7a54d7" 502 | ], 503 | "version": "==0.8.3" 504 | }, 505 | "testpath": { 506 | "hashes": [ 507 | "sha256:60e0a3261c149755f4399a1fff7d37523179a70fdc3abdf78de9fc2604aeec7e", 508 | "sha256:bfcf9411ef4bf3db7579063e0546938b1edda3d69f4e1fb8756991f5951f85d4" 509 | ], 510 | "version": "==0.4.4" 511 | }, 512 | "text-unidecode": { 513 | "hashes": [ 514 | "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", 515 | "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93" 516 | ], 517 | "version": "==1.3" 518 | }, 519 | "toga": { 520 | "hashes": [ 521 | "sha256:9229eb119da97638b4903c4b6688ba04e9525f63cf0cef9cdda939ab8ccbd089", 522 | "sha256:a9f9f5e266be3e2f7d62b17fca6a37d51c0d0737d92384090aa69f500b08f001" 523 | ], 524 | "index": "pypi", 525 | "version": "==0.3.0.dev19" 526 | }, 527 | "toga-cocoa": { 528 | "hashes": [ 529 | "sha256:f33b880ba0e6dcfa3dcacf009fd9a91bd718edf095a5a549abe19ea5d3ec4224", 530 | "sha256:f5b6d9c90beb2714c63180803d7045637783b58461f52090cae506344373237c" 531 | ], 532 | "markers": "sys_platform == 'darwin'", 533 | "version": "==0.3.0.dev19" 534 | }, 535 | "toga-core": { 536 | "hashes": [ 537 | "sha256:6facded76aee70adb968e80b072dbaf83680b918f99c3a3f039401676943a7e4", 538 | "sha256:8bb1ac13223086dd962ee5c8be6491881253bf1cab3bcb36dbbb148f723b156b" 539 | ], 540 | "version": "==0.3.0.dev19" 541 | }, 542 | "toml": { 543 | "hashes": [ 544 | "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", 545 | "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e" 546 | ], 547 | "version": "==0.10.0" 548 | }, 549 | "tornado": { 550 | "hashes": [ 551 | "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc", 552 | "sha256:22aed82c2ea340c3771e3babc5ef220272f6fd06b5108a53b4976d0d722bcd52", 553 | "sha256:2c027eb2a393d964b22b5c154d1a23a5f8727db6fda837118a776b29e2b8ebc6", 554 | "sha256:5217e601700f24e966ddab689f90b7ea4bd91ff3357c3600fa1045e26d68e55d", 555 | "sha256:5618f72e947533832cbc3dec54e1dffc1747a5cb17d1fd91577ed14fa0dc081b", 556 | "sha256:5f6a07e62e799be5d2330e68d808c8ac41d4a259b9cea61da4101b83cb5dc673", 557 | "sha256:c58d56003daf1b616336781b26d184023ea4af13ae143d9dda65e31e534940b9", 558 | "sha256:c952975c8ba74f546ae6de2e226ab3cc3cc11ae47baf607459a6728585bb542a", 559 | "sha256:c98232a3ac391f5faea6821b53db8db461157baa788f5d6222a193e9456e1740" 560 | ], 561 | "version": "==6.0.4" 562 | }, 563 | "traitlets": { 564 | "hashes": [ 565 | "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44", 566 | "sha256:d023ee369ddd2763310e4c3eae1ff649689440d4ae59d7485eb4cfbbe3e359f7" 567 | ], 568 | "version": "==4.3.3" 569 | }, 570 | "travertino": { 571 | "hashes": [ 572 | "sha256:7277f00ad6a88673ec7da3bc787e552421ab366062a09007e30d453121b5611e", 573 | "sha256:f24a5ee5a5da9f4d3d6d02ae6fac268160b703a51aee9104fdb072fcb3532f19" 574 | ], 575 | "version": "==0.1.2" 576 | }, 577 | "urllib3": { 578 | "hashes": [ 579 | "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", 580 | "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" 581 | ], 582 | "version": "==1.25.9" 583 | }, 584 | "wcwidth": { 585 | "hashes": [ 586 | "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1", 587 | "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1" 588 | ], 589 | "version": "==0.1.9" 590 | }, 591 | "webencodings": { 592 | "hashes": [ 593 | "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", 594 | "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" 595 | ], 596 | "version": "==0.5.1" 597 | }, 598 | "widgetsnbextension": { 599 | "hashes": [ 600 | "sha256:079f87d87270bce047512400efd70238820751a11d2d8cb137a5a5bdbaf255c7", 601 | "sha256:bd314f8ceb488571a5ffea6cc5b9fc6cba0adaf88a9d2386b93a489751938bcd" 602 | ], 603 | "version": "==3.5.1" 604 | }, 605 | "zipp": { 606 | "hashes": [ 607 | "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", 608 | "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" 609 | ], 610 | "version": "==3.1.0" 611 | } 612 | }, 613 | "develop": {} 614 | } 615 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hera - a desktop app for Jupyter 2 | 3 | **THIS IS VERY ALPHA SOFTWARE.** 4 | 5 | [Latest Release](https://github.com/phildini/hera/releases/latest) 6 | 7 | **Hera** is a desktop app (currently only macOS) that opens Jupyter notebooks 8 | (`.ipynb` files) as a standalone app. A major benefit of Hera is that there is 9 | no need to install python, conda, or jupyter. 10 | 11 | ## Some caveats 12 | 13 | - Right now, Hera only supports [classic Jupyter Notebook](https://github.com/jupyter/notebook). 14 | No add-ons, extensions, or plugins are currently supported (although we'd 15 | love to to support more) 16 | - On first run of the app, you might need to right-click on the app and select 17 | "Open" from the menu since we haven't registered as a macOS developer yet. 18 | - THIS IS VERY ALPHA SOFTWARE. It works for me on my machine, and should work on 19 | yours. We _want_ it work on yours, so please file bugs, but we make no promises 20 | it does. 21 | 22 | **This cross-platform app was generated by** 23 | [Briefcase](https://github.com/pybee/briefcase) **- part of** 24 | [The BeeWare Project](https://pybee.org/). 25 | 26 | **If you want to see more tools like Briefcase, please consider** 27 | [becoming a financial member of BeeWare](https://pybee.org/contributing/membership). 28 | 29 | # Developer Notes 30 | - Remember to `briefcase update -dr` after updating the pyproject.toml 31 | -------------------------------------------------------------------------------- /hera.dist-info/INSTALLER: -------------------------------------------------------------------------------- 1 | briefcase 2 | -------------------------------------------------------------------------------- /hera.dist-info/METADATA: -------------------------------------------------------------------------------- 1 | Metadata-Version: 2.1 2 | Name: hera 3 | Formal-Name: Hera 4 | App-ID: com.phildini.hera 5 | Version: 0.1.2 6 | Summary: Running Jupyter notebooks locally 7 | -------------------------------------------------------------------------------- /hera/__init__.py: -------------------------------------------------------------------------------- 1 | # Examples of valid version strings 2 | # __version__ = '1.2.3.dev1' # Development release 1 3 | # __version__ = '1.2.3a1' # Alpha Release 1 4 | # __version__ = '1.2.3b1' # Beta Release 1 5 | # __version__ = '1.2.3rc1' # RC Release 1 6 | # __version__ = '1.2.3' # Final Release 7 | # __version__ = '1.2.3.post1' # Post Release 1 8 | 9 | __version__ = '0.0.1' 10 | -------------------------------------------------------------------------------- /hera/__main__.py: -------------------------------------------------------------------------------- 1 | from hera.app import main 2 | 3 | if __name__ == '__main__': 4 | main() 5 | -------------------------------------------------------------------------------- /hera/app.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import subprocess 3 | import toga 4 | from toga.style.pack import Pack, ROW, CENTER, COLUMN 5 | import time 6 | import sys 7 | import os 8 | from pathlib import Path 9 | from urllib.parse import quote 10 | 11 | def install_dependencies(*args, **kwargs): 12 | print("Command called") 13 | import subprocess 14 | subprocess.call("pip install numpy", shell=True) 15 | print("Success") 16 | # stdout, stderr = await proc.communicate() 17 | 18 | # print(f'[{cmd!r} exited with {proc.returncode}]') 19 | # if stdout: 20 | # print(f'[stdout]\n{stdout.decode()}') 21 | # if stderr: 22 | # print(f'[stderr]\n{stderr.decode()}') 23 | 24 | class Notebook(toga.Document): 25 | def __init__(self, filename, app): 26 | super().__init__(filename=filename, document_type='Jupyter Notebook', app=app) 27 | 28 | self.window = toga.Window(title=filename, size=(768,768)) 29 | self.window.on_close = self.close_window 30 | self.webview = toga.WebView(style=Pack(flex=1)) 31 | self.window.content = self.webview 32 | 33 | def close_window(self): 34 | self.proc.kill() 35 | 36 | def read(self): 37 | asyncio.ensure_future(self.start_jupyter(self.filename)) 38 | 39 | def show(self): 40 | self.window.show() 41 | 42 | async def start_jupyter(self, filename): 43 | filename = Path(filename) 44 | command = '{} -m notebook --NotebookApp.token="" --NotebookApp.open_browser=False --notebook-dir="{}"'.format(sys.executable, filename.parent) 45 | self.proc = await asyncio.create_subprocess_shell( 46 | command, 47 | stdin=None, 48 | stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, 49 | ) 50 | line = await self.proc.stderr.readline() 51 | while line: 52 | line = line.strip().decode('utf-8') 53 | if 'http' in line: 54 | url = line.split(' ')[-1] 55 | url = "{}notebooks/{}".format(url, quote(filename.name)) 56 | self.webview.url = url 57 | line = await self.proc.stderr.readline() 58 | 59 | 60 | class Hera(toga.DocumentApp): 61 | 62 | def __init__(self): 63 | resource_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) 64 | super().__init__( 65 | 'Hera', 66 | document_types={'ipynb': Notebook}, 67 | ) 68 | os.environ['PIP_TARGET'] = str(self.paths.data / 'pkgs') 69 | sys.path.append(str(self.paths.data / 'pkgs')) 70 | os.environ['PYTHONPATH'] += ':' + str(self.paths.data / 'pkgs') 71 | print(os.environ['PYTHONPATH']) 72 | 73 | cmd1 = toga.Command( 74 | install_dependencies, 75 | label='Install packages', 76 | tooltip='Installs some helpful packages', 77 | shortcut=toga.Key.MOD_1 + 'i', 78 | icon='icons/pretty.png', 79 | group=toga.Group.FILE, 80 | section=0 81 | ) 82 | 83 | self.commands.add(cmd1) 84 | 85 | def startup(self): 86 | pass 87 | 88 | def main(): 89 | Hera().main_loop() 90 | 91 | 92 | if __name__ == '__main__': 93 | main() -------------------------------------------------------------------------------- /icons/Hera.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildini/hera/b33be2a4c5b4edec6aea5953785aa3ae25f0b4a2/icons/Hera.icns -------------------------------------------------------------------------------- /icons/JupyterDoc.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phildini/hera/b33be2a4c5b4edec6aea5953785aa3ae25f0b4a2/icons/JupyterDoc.icns -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["briefcase"] 3 | 4 | [tool.briefcase] 5 | project_name = "Hera" 6 | bundle = "com.phildini" 7 | version = "0.1.2" 8 | icon = "icons/Hera" 9 | 10 | [tool.briefcase.app.hera] 11 | formal_name = "Hera" 12 | description = "Running Jupyter notebooks locally" 13 | sources = ['hera'] 14 | requires = ['jupyter', 'pip'] 15 | 16 | [tool.briefcase.app.hera.macOS] 17 | requires = ['toga-cocoa==0.3.0.dev19'] 18 | 19 | [tool.briefcase.app.hera.document_type.ipynb] 20 | icon = "icons/JupyterDoc" 21 | description = "Jupyter Notbook" 22 | url = "http://jupyter.org/" 23 | --------------------------------------------------------------------------------