From 00d6d37553cabab34c474d113ebb46b3c1341c94 Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:59:56 +0000 Subject: [PATCH 01/14] wip --- .gitignore | 7 +- README.md | 55 ++---- demo.sh | 64 +++--- main.py | 21 +- setup.py | 4 +- termtosvg_0oihyn7a.svg | 129 ------------- termtosvg_9evceaqa.svg | 182 ------------------ toc_sb.md | 15 ++ toc_zt.md | 17 ++ zero_to_one_hundred/configs/a_config_map.py | 8 +- zero_to_one_hundred/factories/a_factory.py | 25 ++- .../factories/a_factory_provider.py | 12 +- zero_to_one_hundred/factories/sb_factory.py | 18 +- .../factories/sb_factory_provider.py | 4 +- zero_to_one_hundred/factories/ztoh_factory.py | 21 +- .../factories/ztoh_factory_provider.py | 2 +- .../processors/help_processor.py | 5 +- .../processors/unsupported_processor.py | 8 +- zero_to_one_hundred/runner.py | 20 +- .../tests/tests_sb/resources/map.yaml | 2 +- zero_to_one_hundred/validator/validator.py | 15 ++ 21 files changed, 163 insertions(+), 471 deletions(-) delete mode 100644 termtosvg_0oihyn7a.svg delete mode 100644 termtosvg_9evceaqa.svg create mode 100644 toc_sb.md create mode 100644 toc_zt.md diff --git a/.gitignore b/.gitignore index 1cebb58..415ffa6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,15 +14,14 @@ venv/ # idea .idea/** -# test related +# demo 0to100**/ 978*/ 0*/ -map.md repo/ -toc*.md -*.yaml safaribooks/ +*.yaml +toc.md # pip install build diff --git a/README.md b/README.md index 288e0d4..0ded9f1 100644 --- a/README.md +++ b/README.md @@ -16,24 +16,23 @@ Given a 'url', it creates the entry in a markdown map and a folder and links the just open this repo in your GitHub Codespace and run the demo as: ```bash -bash demo.sh 0to100_zt +bash demo.sh zt ``` -![](termtosvg_0oihyn7a.svg) +![](2dc4491c-fa27-4c5e-bd0c-71951b3ef0e5.png) ```bash -bash demo.sh 0to100_sb +bash demo.sh sb ``` -![](termtosvg_9evceaqa.svg) - +![](z05502bb-4b90-422f-9624-568d9f02cd01.png) ## oto100 -0 to 100 ... learn anything from webresources (and not) +0 to 100 ... learn anything from the web -current commands: +commands: ``` ['create_section', 'done_section', 'refresh_map', 'refresh_links', 'help'] @@ -57,9 +56,9 @@ ex https://www.cloudskillsboost.google/doc ``` -expand the last link to point to the section for the doc - handy as anchor tecnique +expand the last link to point to the section for the doc - handy as anchor technique -### 1st time usage: +### setup and usage: ```bash # env @@ -73,31 +72,12 @@ cat map.yaml export MAP_YAML_PATH=map.yaml # tip: add it to .bash_rc etc or some shell script -``` - -![](ab67dd2b-7c12-4cdf-a7a5-f773c2b67919.png) - -```bash chmod +x *.py +# run main ./main.py zt help ``` -![](50a86373-910b-4a12-85ef-251b6d4f08f0.png) - -### daily usage: - -- create new section - -```bash -url=https://cloud.google.com/docs -./main.py zt create_section $url - -url=https://cloud.google.com/help -./main.py zt create_section $url -#...etc -``` - -![](9b873c30-eccb-4c17-9d36-1c302060f5c3.png) + ## oto100 safari books :construction: @@ -111,7 +91,7 @@ current commands: ['snatch_book', 'refresh_toc', 'help'] ``` -### 0th time usage: +### setup and usage: > use what you prefer to grab epub/pdf from oreilly check this @@ -120,8 +100,6 @@ or just save as pdf section by section with this https://chromewebstore.google.com/detail/reader-view/ecabifbgmdmgdllomnfinbmaellmclnh -### 1st time usage: - ```bash # env python -m venv .venv @@ -157,7 +135,6 @@ chmod +x *.py ![](63fd79b5-ad41-45fd-a2dc-367f317bcc0c.png) -### daily usage: - create new meta-book @@ -170,24 +147,22 @@ and you have a `toc.md` for free to use as your index (bookmark it) > as I use myself Lorenzo's great utility `safaribooks` I added some code to convert the downloaded epub contents into a related pdf and split that in chunks so I can easily use it on ipad or better remarkable for studying and later sync back in a repo for hands-on code... they call that **learning by doing** đŸ––đŸ» -example: -![](2dc4491c-fa27-4c5e-bd0c-71951b3ef0e5.png) -![](z05502bb-4b90-422f-9624-568d9f02cd01.png) + ### tools > when you start to have a a few 0to100 based folders -> + [gist to sync multiple 0to100 based repos](https://gist.github.com/obar1/771b1992368262737d9f25fcf17ce1c1) [gist venv auto activate for 0to100 folders](https://gist.github.com/obar1/212e4c778548f8bcdc6e9c1b05856f3f) ## online example -- 0to100 +- zt https://github.com/obar1/zero2hero -- 0to100sb +- sb > mostly private contents, `sorry but I don't want to get suited :P` https://github.com/obar1/0to100.oreilly diff --git a/demo.sh b/demo.sh index a1d7d56..ad972ba 100644 --- a/demo.sh +++ b/demo.sh @@ -4,70 +4,76 @@ function setup { # set -x export MAP_YAML_PATH=map.yaml - + pip install . - - chmod +x main*.py + + chmod +x main.py } -function setup0to100_zt { +function setup_zt { cp ./zero_to_one_hundred/tests/test_ztoh/resources/gcp_map.yaml map.yaml } -function setup0to100_sb { +function setup_sb { cp ./zero_to_one_hundred/tests/tests_sb/resources/map.yaml map.yaml - + # safari books from lorenzodifuccia git clone https://github.com/lorenzodifuccia/safaribooks.git pip install --quiet -r safaribooks/requirements.txt } -function 0to100_zt { +function zt { # 0to100 - setup0to100_zt - + setup_zt + ./main.py zt help -content=$(cat << 'EOF' + content=$( + cat <<'EOF' https://www.cloudskillsboost.google/0 https://www.cloudskillsboost.google/paths/16 https://www.cloudskillsboost.google/games/4424/labs/28651 https://www.cloudskillsboost.google/course_templates/3 https://www.cloudskillsboost.google/games/4422 https://storage.googleapis.com/cloud-training/cls-html5-courses/T-BQRS-I/M1/index.html - EOF -) -while IFS= read -r section || [[ -n "$section" ]]; do - ./main.py zt create_section "$section" -done <<< "$content" + ) + while IFS= read -r section || [[ -n "$section" ]]; do + ./main.py zt create_section "$section" + done <<<"$content" -echo "# a_custom_header 0" >> 0to100/https§§§www.cloudskillsboost.google§0/readme.md + echo "# a_custom_header 0" >>0to100/https§§§www.cloudskillsboost.google§0/readme.md -./main.py zt done_section "https://www.cloudskillsboost.google/0" + ./main.py zt done_section "https://www.cloudskillsboost.google/0" ls -1R 0to100 - cp toc.md toc_0to100.md + cp toc.md toc_zt.md } -function 0to100_sb { +function sb { # 0to100 safari books - setup0to100_sb - + setup_sb + ./main.py sb help - + ./main.py sb snatch_book https://learning.oreilly.com/course/clean-code-fundamentals/9780134661742 echo 'add any metadata you like' - echo '{"title": "Clean Code Fundamentals"}'> 9780134661742/9780134661742.json + echo '{"title": "Clean Code Fundamentals"}' >9780134661742/9780134661742.json ./main.py sb refresh_toc - + ./main.py sb snatch_book https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947 echo 'pretend book was read fully and get % calc for free :P' - echo '{"page_curr": "100", "page_tot": "100", "url":"https://www.oreilly.com/library/view/rewire-your-brain/9781119895947"}' > 9781119895947/9781119895947.json + echo '{"page_curr": "100", "page_tot": "100", "url":"https://www.oreilly.com/library/view/rewire-your-brain/9781119895947"}' >9781119895947/9781119895947.json ./main.py sb refresh_toc - + ls -1R 978* - cp toc.md toc_0to100_sb.md + cp toc.md toc_sb.md } -setup -$1 +#!/bin/bash + +if [ $# -eq 0 ]; then + echo "No arguments were passed: use sb or zt" +else + setup + $1 +fi diff --git a/main.py b/main.py index 9b327a3..2f38813 100755 --- a/main.py +++ b/main.py @@ -1,31 +1,36 @@ #!/usr/bin/env python3 # coding: utf-8 +from enum import Enum import sys import logging from zero_to_one_hundred.runner import run_core - +from zero_to_one_hundred.validator.validator import Validator + if __name__ == "__main__": logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') - - err_msg = f'zt or sb available, passed {str(sys.argv)}' try: arg1= sys.argv[1] match arg1: case 'zt': - from zero_to_one_hundred.factories.ztoh_factory_provider import ZTOHFactoryProvider from zero_to_one_hundred.repository.ztoh_persist_fs import ZTOHPersistFS as persist_fs from zero_to_one_hundred.repository.ztoh_process_fs import ZTOHProcessFS as process_fs + from zero_to_one_hundred.factories.ztoh_factory_provider import ZTOHFactoryProvider run_core(sys.argv, ZTOHFactoryProvider(persist_fs, process_fs)) case 'sb': - from zero_to_one_hundred.factories.sb_factory_provider import SBFactoryProvider from zero_to_one_hundred.repository.sb_persist_fs import SBPersistFS as persist_fs from zero_to_one_hundred.repository.sb_process_fs import SBProcessFS as process_fs + from zero_to_one_hundred.factories.sb_factory_provider import SBFactoryProvider run_core(sys.argv, SBFactoryProvider(persist_fs, process_fs)) case _: - raise ValueError(err_msg) - except Exception as e: - logging.info(err_msg) + raise ValueError + except (ValueError,IndexError, TypeError): + from zero_to_one_hundred.repository.a_persist_fs import APersistFS as persist_fs + from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider + run_core(sys.argv, AFactoryProvider(persist_fs=persist_fs)) + except Exception as e: + Validator.print_e(e) + diff --git a/setup.py b/setup.py index 54712f9..6d63f69 100644 --- a/setup.py +++ b/setup.py @@ -12,10 +12,10 @@ setup( name="0to100", - version="0.4.3", + version="0.5.3", author="obar1", author_email="obar1+gh@pm.me", - description="Simple python tool to learn everything and keep all local.", + description="Simple python tool to learn everything and keep it local.", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/obar1/0to100", diff --git a/termtosvg_0oihyn7a.svg b/termtosvg_0oihyn7a.svg deleted file mode 100644 index 4dd4f10..0000000 --- a/termtosvg_0oihyn7a.svg +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - xsazcd@obar1:~/git/obar1/0to100.git$ xsazcd@obar1:~/git/obar1/0to100.git$ b xsazcd@obar1:~/git/obar1/0to100.git$ ba xsazcd@obar1:~/git/obar1/0to100.git$ bas xsazcd@obar1:~/git/obar1/0to100.git$ bash xsazcd@obar1:~/git/obar1/0to100.git$ bash xsazcd@obar1:~/git/obar1/0to100.git$ bash d xsazcd@obar1:~/git/obar1/0to100.git$ bash de xsazcd@obar1:~/git/obar1/0to100.git$ bash dem xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0t xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0ti xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0t xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to1 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to10 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100 + export MAP_YAML_PATH=map.yaml+ MAP_YAML_PATH=map.yaml+ rm -rf safaribooks/+ pip install .Defaulting to user installation because normal site-packages is not writeableProcessing /home/xsazcd/git/obar1/0to100.git Preparing metadata (setup.py) ... - Preparing metadata (setup.py) ... doneRequirement already satisfied: PyMuPDF==1.23.8 in /home/xsazcd/.local/lib/python3.10/site-packages (from 0to100==0.4.0) (1.23.8)Requirement already satisfied: PyYAML==6.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from 0to100==0.4.0) (6.0)Requirement already satisfied: connect-markdown-renderer==3.0.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from 0to100==0.4.0) (3.0.0)Requirement already satisfied: markdown-it-py<3.0.0,>=2.2.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from connect-markdown-renderer==3.0.0->0to100==0.4.0) (2.2.0)Requirement already satisfied: rich<13,>=12.4.4 in /home/xsazcd/.local/lib/python3.10/site-packages (from connect-markdown-renderer==3.0.0->0to100==0.4.0) (12.6.0)Requirement already satisfied: PyMuPDFb==1.23.7 in /home/xsazcd/.local/lib/python3.10/site-packages (from PyMuPDF==1.23.8->0to100==0.4.0) (1.23.7)Requirement already satisfied: mdurl~=0.1 in /home/xsazcd/.local/lib/python3.10/site-packages (from markdown-it-py<3.0.0,>=2.2.0->connect-markdown-renderer==3.0.0->0to100==0.4.0) (0.1.2)Requirement already satisfied: commonmark<0.10.0,>=0.9.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from rich<13,>=12.4.4->connect-markdown-renderer==3.0.0->0to100==0.4.0) (0.9.1)Requirement already satisfied: pygments<3.0.0,>=2.6.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from rich<13,>=12.4.4->connect-markdown-renderer==3.0.0->0to100==0.4.0) (2.17.2)Building wheels for collected packages: 0to100 Building wheel for 0to100 (setup.py) ... - Building wheel for 0to100 (setup.py) ... done Created wheel for 0to100: filename=0to100-0.4.0-py3-none-any.whl size=14925 sha256=e37ff74d536a18fa0d69f7f8150fa3ad8ff9ca292e1bc24fee33f8259c1500cb Stored in directory: /tmp/pip-ephem-wheel-cache-8zzznoqa/wheels/d8/d8/99/0abb8fb05b3dcf6eb93e0f32bc20dc18d4c1278594ab17a34eSuccessfully built 0to100DEPRECATION: distro-info 1.1build1 has a non-standard version number. pip 24.0 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of distro-info or contact the author to suggest that they release a version with a conforming version number. Discussion can be found at https://github.com/pypa/pip/issues/12063Installing collected packages: 0to100 Attempting uninstall: 0to100 Found existing installation: 0to100 0.3.0 Uninstalling 0to100-0.3.0: Successfully uninstalled 0to100-0.3.0Successfully installed 0to100-0.4.0[notice] A new release of pip is available: 23.3.1 -> 23.3.2[notice] To update, run: python3 -m pip install --upgrade pip+ chmod +x main.py main_sb.py+ 0to100+ setup0to100+ rm -rf 0to100/+ cp ./zero_to_one_hundred/tests/resources/map.yaml .+ ./main.py helpread_file 0to100.egg-info/PKG-INFOMetadata-Version: 2.1 Name: 0to100 Version: 0.4.0 Summary: Simple python tool to learn everything and keep all local.MAP_YAML_PATH from map.yaml type ztoh-map['create_section', 'done_section', 'refresh_map', 'refresh_links', 'help']+ url=https://cloud.google.com/docs/+ ./main.py create_section https://cloud.google.com/docs/make_dirs /home/xsazcd/git/obar1/0to100.git/0to100/https§§§cloud.google.com§docs§write_file /home/xsazcd/git/obar1/0to100.git/0to100/https§§§cloud.google.com§docs§/readme.mdlist_dirs /home/xsazcd/git/obar1/0to100.git/0to100done_section_status https§§§cloud.google.com§docs§path /home/xsazcd/git/obar1/0to100.git/0to100/https§§§cloud.google.com§docs§/.doneexists FalseFalseread_file /home/xsazcd/git/obar1/0to100.git/0to100/https§§§cloud.google.com§docs§/readme.md╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮/home/xsazcd/git/obar1/0to100.git/0to100/0to100.md╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ sorted: False legend: ╭────────────┬───────────╮ footprints completed ├────────────┼───────────┤ 👣 💚 ╰────────────┴───────────╯ extra ▌ extra ╭───────┬─────┬──────────┬──────┬────────╮ quest lab template game course ├───────┼─────┼──────────┼──────┼────────┤ 🌀 💾 🐳 🐍 📌 ╰───────┴─────┴──────────┴──────┴────────╯here (https%C2%A7%C2%A7%C2%A7cloud.google.com%C2%A7docs%C2%A7/readme.md) here (https%C2%A7%C2%A7%C2%A7cloud.google.com%C2%A7docs%C2%A7/readme.md) 1 ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ <https§§§cloud.google.com§docs§> 👣 📌 ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯write_file /home/xsazcd/git/obar1/0to100.git/0to100/0to100.md+ url=https://docs.getdbt.com/docs/introduction+ ./main.py create_section https://docs.getdbt.com/docs/introductionmake_dirs /home/xsazcd/git/obar1/0to100.git/0to100/https§§§docs.getdbt.com§docs§introductionwrite_file /home/xsazcd/git/obar1/0to100.git/0to100/https§§§docs.getdbt.com§docs§introduction/readme.mddone_section_status https§§§docs.getdbt.com§docs§introductionpath /home/xsazcd/git/obar1/0to100.git/0to100/https§§§docs.getdbt.com§docs§introduction/.doneread_file /home/xsazcd/git/obar1/0to100.git/0to100/https§§§docs.getdbt.com§docs§introduction/readme.mdhere (https%C2%A7%C2%A7%C2%A7docs.getdbt.com%C2%A7docs%C2%A7introduction/readme.md) ╰──────────────────────────────────────────────────────── 2 ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ <https§§§docs.getdbt.com§docs§introduction> 👣 📌 ╰────────────────────────────────────────────────── + ./main.py done_section https://cloud.google.com/docs/done_section /home/xsazcd/git/obar1/0to100.git/0to100/https§§§cloud.google.com§docs§created /home/xsazcd/git/obar1/0to100.git/0to100/https§§§cloud.google.com§docs§/.doneexists True╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ▌ extra here (https%C2%A7%C2%A7%C2%A7docs.getdbt.c ╰─────────────────────── <https§§§cloud.google.com§docs§> 💚 📌 ╰───────────────── + ls -1R 0to1000to100:0to100.mdhttps§§§cloud.google.com§docs§https§§§docs.getdbt.com§docs§introduction0to100/https§§§cloud.google.com§docs§:readme.md0to100/https§§§docs.getdbt.com§docs§introduction:xsazcd@obar1:~/git/obar1/0to100.git$ exit - \ No newline at end of file diff --git a/termtosvg_9evceaqa.svg b/termtosvg_9evceaqa.svg deleted file mode 100644 index 5bf6b99..0000000 --- a/termtosvg_9evceaqa.svg +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - xsazcd@obar1:~/git/obar1/0to100.git$ xsazcd@obar1:~/git/obar1/0to100.git$ b xsazcd@obar1:~/git/obar1/0to100.git$ ba xsazcd@obar1:~/git/obar1/0to100.git$ bas xsazcd@obar1:~/git/obar1/0to100.git$ bash xsazcd@obar1:~/git/obar1/0to100.git$ bash xsazcd@obar1:~/git/obar1/0to100.git$ bash d xsazcd@obar1:~/git/obar1/0to100.git$ bash de xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0t xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to1 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to10 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100 xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100_ xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100_s xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100_sb xsazcd@obar1:~/git/obar1/0to100.git$ bash demo.sh 0to100_sb + export MAP_YAML_PATH=map.yaml+ MAP_YAML_PATH=map.yaml+ rm -rf safaribooks/+ pip install .Defaulting to user installation because normal site-packages is not writeableProcessing /home/xsazcd/git/obar1/0to100.git Preparing metadata (setup.py) ... - Preparing metadata (setup.py) ... doneRequirement already satisfied: PyMuPDF==1.23.8 in /home/xsazcd/.local/lib/python3.10/site-packages (from 0to100==0.4.0) (1.23.8)Requirement already satisfied: PyYAML==6.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from 0to100==0.4.0) (6.0)Requirement already satisfied: connect-markdown-renderer==3.0.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from 0to100==0.4.0) (3.0.0)Requirement already satisfied: markdown-it-py<3.0.0,>=2.2.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from connect-markdown-renderer==3.0.0->0to100==0.4.0) (2.2.0)Requirement already satisfied: rich<13,>=12.4.4 in /home/xsazcd/.local/lib/python3.10/site-packages (from connect-markdown-renderer==3.0.0->0to100==0.4.0) (12.6.0)Requirement already satisfied: PyMuPDFb==1.23.7 in /home/xsazcd/.local/lib/python3.10/site-packages (from PyMuPDF==1.23.8->0to100==0.4.0) (1.23.7)Requirement already satisfied: mdurl~=0.1 in /home/xsazcd/.local/lib/python3.10/site-packages (from markdown-it-py<3.0.0,>=2.2.0->connect-markdown-renderer==3.0.0->0to100==0.4.0) (0.1.2)Requirement already satisfied: commonmark<0.10.0,>=0.9.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from rich<13,>=12.4.4->connect-markdown-renderer==3.0.0->0to100==0.4.0) (0.9.1)Requirement already satisfied: pygments<3.0.0,>=2.6.0 in /home/xsazcd/.local/lib/python3.10/site-packages (from rich<13,>=12.4.4->connect-markdown-renderer==3.0.0->0to100==0.4.0) (2.17.2)Building wheels for collected packages: 0to100 Building wheel for 0to100 (setup.py) ... - Building wheel for 0to100 (setup.py) ... done Created wheel for 0to100: filename=0to100-0.4.0-py3-none-any.whl size=14925 sha256=a0a9f37743865b6f2f5ed491ac0f3ebdfe074ed7d9d82e5ac342bae6506653c6 Stored in directory: /tmp/pip-ephem-wheel-cache-dho3f_a0/wheels/d8/d8/99/0abb8fb05b3dcf6eb93e0f32bc20dc18d4c1278594ab17a34eSuccessfully built 0to100DEPRECATION: distro-info 1.1build1 has a non-standard version number. pip 24.0 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of distro-info or contact the author to suggest that they release a version with a conforming version number. Discussion can be found at https://github.com/pypa/pip/issues/12063Installing collected packages: 0to100 Attempting uninstall: 0to100 Found existing installation: 0to100 0.4.0 Uninstalling 0to100-0.4.0: Successfully uninstalled 0to100-0.4.0Successfully installed 0to100-0.4.0[notice] A new release of pip is available: 23.3.1 -> 23.3.2[notice] To update, run: python3 -m pip install --upgrade pip+ chmod +x main.py main_sb.py+ 0to100_sb+ setup0to100_sb+ rm -rf '978*/'+ cp ./zero_to_one_hundred/tests_sb/resources/map.yaml .+ git clone https://github.com/lorenzodifuccia/safaribooks.gitCloning into 'safaribooks'...remote: Enumerating objects: 417, done. remote: Counting objects: 22% (40/180) remote: Counting objects: 46% (81/180) remote: Counting objects: 69% (125/180) remote: Counting objects: 92% (166/180) remote: Counting objects: 100% (180/180), done. remote: Compressing objects: 53% (14/26) remote: Compressing objects: 100% (26/26), done. Receiving objects: 1% (5/417)Receiving objects: 3% (13/417)Receiving objects: 5% (21/417)Receiving objects: 16% (67/417)Receiving objects: 17% (71/417)Receiving objects: 27% (113/417)Receiving objects: 37% (155/417)Receiving objects: 57% (238/417)Receiving objects: 69% (288/417)Receiving objects: 71% (297/417)remote: Total 417 (delta 166), reused 155 (delta 154), pack-reused 237 Receiving objects: 72% (301/417)Receiving objects: 100% (417/417), 170.90 KiB | 467.00 KiB/s, done.Res Resolving deltas: 31% (71/227)Resolving deltas: 62% (141/227)Resolving deltas: 94% (212/227)Resolving deltas: 100% (227/227), done.+ pip install --quiet -r safaribooks/requirements.txt+ ./main_sb.py helpread_file 0to100.egg-info/PKG-INFOMetadata-Version: 2.1 Name: 0to100 Version: 0.4.0 Summary: Simple python tool to learn everything and keep all local.MAP_YAML_PATH from map.yaml type safari-books-map['snatch_book', 'refresh_toc', 'help']+ url=https://learning.oreilly.com/library/view/the-pragmatic-programmer/9780135956977/+ ./main_sb.py snatch_book https://learning.oreilly.com/library/view/the-pragmatic-programmer/9780135956977/make_dirs safaribooks/Booksmake_dirs /home/xsazcd/git/obar1/0to100.git/9780135956977write_img /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.png https://learning.oreilly.com/library/cover/9780135956977/ % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 12535 100 12535 0 0 68039 0 --:--:-- --:--:-- --:--:-- 68125write_fake_epub /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.epubwrite_epub /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.epub 9780135956977usage: safaribooks.py [--cred <EMAIL:PASS> | --login] [--no-cookies] [--kindle] [--preserve-log] [--help] <BOOK ID>safaribooks.py: error: invalid credential: username:userpasswordDDD issue with Command '['python', 'safaribooks/safaribooks.py', '--cred', 'username:userpassword', '9780135956977']' returned non-zero exit status 2.read_pages_curr /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.jsonDDD issue with [Errno 2] No such file or directory: '/home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.json'read_pages_tot /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.pdfDDD issue with no such file: '/home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.pdf'"isbn":"9780135956977", "url":"https://learning.oreilly.com/library/view/the-pragmatic-programmer/9780135956977/", "page_curr":"0", "pages_tot":"0", "page_perc":"0%"write_json /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.json {"isbn":"9780135956977", "page_perc":"0%"}write_file /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.jsonwrite_pdf /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.epubwrite_pdf /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.pdf 100{'isbn': '9780135956977', 'url': 'https://learning.oreilly.com/library/view/the-pragmatic-programmer/9780135956977/', 'page_curr': '0', 'pages_tot': '0', 'page_perc': '0%'}Document('/home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.pdf') "pages_tot":"1", "page_perc":"0.0%" "page_perc":"0.0%"}write_file /home/xsazcd/git/obar1/ list_dirs .[MetaBook https://learning.oreilly.com/library//9780135956977, 9780135956977 /home/xsazcd/git/obar1/0to100.git/9780135956977]flatten_meta_book MetaBook https://learning.oreilly.com/library//9780135956977, 9780135956977 /home/xsazcd/git/obar1/0to100.git/9780135956977read_file /home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.json{<br/> "isbn": "9780135956977",<br/> "url": "https://learning.oreilly.com/library/view/the-pragmatic-programmer/9780135956977/",<br/> "page_curr": "0",<br/> "pages_tot": "1",<br/> "page_perc": "0.0%"<br/>}╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮TOC╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ 1 books 2023/12/29-14:52:34 🌆 `img` epub (/home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.ep epub (/home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.epub) pdf (/home/xsazcd/git/obar1/0to100.git/9780135956977/9780135956977.pdf) ╭───────────────────────────────────────┬─────┬──┬──┬───────────────────────────────────────┬───────────────────────────────────────╮ ISBN json-contents ISBN json-contents status ├───────────────────────────────────────┼─────┼──┼──┼───────────────────────────────────────┼───────────────────────────────────────┤ <span img {<br/> "isbn": <span style="color:yellow">WIP</span> style="color:blue">9780135956977</sp… "9780135956977",<br/> "url": "https://learning.oreilly.com/librar… "page_curr": "0",<br/> "pages_tot": "1",<br/> "page_perc": "0.0%"<br/>} ╰───────────────────────────────────────┴─────┴──┴──┴─────────────────── ╰───────────────────────────────────────┴─────┴──┴──┴───────────────────────────────────────┴───────────────────────────────────────╯write_file toc.md+ url=https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947/+ ./main_sb.py snatch_book https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947/make_dirs /home/xsazcd/git/obar1/0to100.git/9781119895947write_img /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.png https://learning.oreilly.com/library/cover/9781119895947100 11219 100 11219 0 0 96838 0 --:--:-- --:--:-- --:--:-- 97556write_fake_epub /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.epubwrite_epub /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.epub 9781119895947DDD issue with Command '['python', 'safaribooks/safaribooks.py', '--cred', 'username:userpassword', '9781119895947']' returned non-zeread_pages_curr /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.jsonDDD issue with [Errno 2] No such file or directory: '/home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.json'read_pages_tot /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.pdfDDD issue with no such file: '/home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.pdf'"isbn":"9781119895947", "url":"https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947/",write_json /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.json {"isbn":"9781119895947",write_file /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.jsonwrite_pdf /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.epubwrite_pdf /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.pdf 100{'isbn': '9781119895947', 'url': 'https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947/', 'page_curr': '0', 'pages_tot': '0', 'page_perc': '0%'}Document('/home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.pdf')write_file /home/xsazcd/git/obar1/0to100.git/9781119895 [MetaBook https://learning.oreilly.com/library//9780135956977, 9780135956977 /home/xsazcd/git/obar1/0to100.git/9780135956977, MetaBook https://learning.oreilly.com/library//9781119895947, 9781119895947 /home/xsazcd/git/obar1/0to100.git/9781119895947]flatten_meta_book MetaBook https://learning.oreilly.com/library//9781119895947, 9781119895947 /home/xsazcd/git/obar1/0to100.git/9781119895947read_file /home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.json{<br/> "isbn": "9781119895947",<br/> "url": "https://learning.ore {<br/> "isbn": "9781119895947",<br/> "url": "https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947/",<br/> "page_curr": "0",<br/> "pages_tot": "1",<br/> "page_perc": "0.0%"<br/>}╰─────────────────────────────────────────────────────────────────────────────────────────────────────────── 2 books epub (/home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.epub) pdf (/home/xsazcd/git/obar1/0to100.git/9781119895947/9781119895947.pdf) ISBN json-contents status "https://learning.oreilly.com/librar style="color:blue">9781119895947</sp… style="color:blue">9781119895947</sp… "9781119895947",<br/> "url": ╰──────── + echo 'pretend book was read fully :P'pretend book was read fully :P+ echo '{"page_curr": "1", "pages_tot": "1"}'+ ./main_sb.py refresh_metadata https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947/{'page_curr': '1', 'pages_tot': '1'} "page_curr":"1", "page_perc":"100.0%" "page_perc":"100.0%"}flatten_meta_book MetaBook https://learning.oreilly.com/library//9780135956977, 9780135956977 /home/xsazcd/git/obar1/0to1 "page_curr": "1",<br/> "pages_tot": "1",<br/> "page_perc": "100.0%"<br/>}╭────────────────────────────────────────────────────────────────────────────────────── 2023/12/29-14:52:34 ╭───────────────────────────────────────┬─────┬──┬──┬────────────────────── ├───────────────────────────────────────┼─────┼──┼──┼───────────────────────────────────────┼────────────────────────────────────── "pages_tot": "1",< <span img {<br/> "isbn": <span style="color:green">DONE</span> "page_curr": "1",<br/> "page_perc": "100.0%"<br/>} + ./main_s + ./main_sb.py refresh_toc{<br/> "isbn": "9781119895947",<br/> "url": "https://learning.oreilly.com/library/view/rewire-your-bra ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── pdf (/home/xsaz ├────── "https://learning.oreilly.com/librar… style="color:blue">9781119895947</sp… ╰──────────────────── + ls -1R 9780135956977 97811198959479780135956977:9780135956977.epub9780135956977.json9780135956977.pdf9780135956977.png9781119895947:9781119895947.epub9781119895947.json9781119895947.pdf9781119895947.pngxsazcd@obar1:~/git/obar1/0to100.git$ exit - \ No newline at end of file diff --git a/toc_sb.md b/toc_sb.md new file mode 100644 index 0000000..1ffefe2 --- /dev/null +++ b/toc_sb.md @@ -0,0 +1,15 @@ + +# TOC +## `2` metabook +### 2024/09/13-07:48:42 + +## legend: + +**legend_icons** +`Book` :cyclone: + +| ISBN | img | `meta-contents` | `json-contents` | `status` | `icons` +|--- |--- |--- |--- |--- |--- | +|**9780134661742**|![`img`](./9780134661742/9780134661742.png)|[`xyz`](./9780134661742/)|{'isbn': '9780134661742',
'pages_perc': 'n/a',
'title': 'Clean Code Fundamentals',
'url': '> https://learning.oreilly.com/library/9780134661742 <'}|**WIP**|:cyclone:| +|**9781119895947**|![`img`](./9781119895947/9781119895947.png)|[`xyz`](./9781119895947/)|{'isbn': '9781119895947',
'page_curr': '100',
'page_tot': '100',
'pages_perc': '100.0%',
'url': '> https://www.oreilly.com/library/view/rewire-your-brain/9781119895947 <'}|**DONE**|:cyclone:| + \ No newline at end of file diff --git a/toc_zt.md b/toc_zt.md new file mode 100644 index 0000000..a4e0340 --- /dev/null +++ b/toc_zt.md @@ -0,0 +1,17 @@ +# map toc.md, 6 + +## legend: + +**legend_icons** +`Path` :cyclone: +`Lab` :floppy_disk: +`Template` :whale: +`Game` :snake: +`Course` :pushpin: + +1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§paths§16/readme.md) `wip` :cyclone: +1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§games§4424§labs§28651/readme.md) `wip` :floppy_disk: :snake: +1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§course_templates§3/readme.md) `wip` :whale: :pushpin: +1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§games§4422/readme.md) `wip` :snake: +1. # [`here`](./0to100/https§§§storage.googleapis.com§cloud-training§cls-html5-courses§T-BQRS-I§M1§index.html/readme.md) `wip` :pushpin: +1. # a_custom_header 0 [`here`](./0to100/https§§§www.cloudskillsboost.google§0/readme.md) `done` diff --git a/zero_to_one_hundred/configs/a_config_map.py b/zero_to_one_hundred/configs/a_config_map.py index bdd47d9..942303a 100644 --- a/zero_to_one_hundred/configs/a_config_map.py +++ b/zero_to_one_hundred/configs/a_config_map.py @@ -7,7 +7,7 @@ from zero_to_one_hundred.repository.a_persist_fs import APersistFS -class AConfigMap(ABC): +class AConfigMap: MAP_YAML_PATH = "MAP_YAML_PATH" @dataclass @@ -20,14 +20,12 @@ def __init__(self, persist_fs: APersistFS): self.map_yaml_path = os.getenv(AConfigMap.MAP_YAML_PATH) if self.map_yaml_path is None: raise SomeError( - f"map_yaml_path {self.map_yaml_path} is not valid,\nplease set it in the env ex:\n`export MAP_YAML_PATH=map.yaml`" + f"map_yaml_path {self.map_yaml_path} is not valid,\nplease set it in the env ex:\nexport MAP_YAML_PATH=map.yaml" ) self.persist_fs = persist_fs def __repr__(self): - return ( - f"{AConfigMap.MAP_YAML_PATH} from {self.map_yaml_path} type {self.get_type}" - ) + return f"{AConfigMap.MAP_YAML_PATH} from {self.map_yaml_path} type {self.get_type}\nraw data:\n{self.load}" @property def load(self): diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index 0783820..9acaa5f 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -1,21 +1,32 @@ -from abc import ABC, abstractmethod +from abc import abstractmethod from enum import Enum from typing import Generator +from zero_to_one_hundred.configs.a_config_map import AConfigMap from zero_to_one_hundred.processors.a_processor import AProcessor +from zero_to_one_hundred.processors.help_processor import HelpProcessor from zero_to_one_hundred.processors.unsupported_processor import UnsupportedProcessor +from zero_to_one_hundred.repository.a_persist_fs import APersistFS +from zero_to_one_hundred.validator.validator import Validator -class AFactory(ABC): +class AFactory: """AFactory class.""" class SUPPORTED_PROCESSOR(Enum): - help = 1 + zt = 1 + sb = 2 + help = 3 + + def __init__(self, persist_fs: APersistFS): + self.persist_fs = persist_fs - @abstractmethod def get_processor(self, args) -> Generator[AProcessor, None, None]: - pass + yield self.help_processor() + + def help_processor(self): + return HelpProcessor(None, self.persist_fs, self.SUPPORTED_PROCESSOR) @staticmethod - def unsupported_processor(cmd): - return UnsupportedProcessor(cmd) + def unsupported_processor(cmd, supp): + return UnsupportedProcessor(cmd, supp) diff --git a/zero_to_one_hundred/factories/a_factory_provider.py b/zero_to_one_hundred/factories/a_factory_provider.py index 2bf566a..d0c0b41 100644 --- a/zero_to_one_hundred/factories/a_factory_provider.py +++ b/zero_to_one_hundred/factories/a_factory_provider.py @@ -1,16 +1,16 @@ from abc import ABC, abstractmethod +from zero_to_one_hundred.configs.a_config_map import AConfigMap from zero_to_one_hundred.factories.a_factory import AFactory from zero_to_one_hundred.repository.a_persist_fs import APersistFS -class AFactoryProvider(ABC): +class AFactoryProvider: """AFactoryProvider.""" - @abstractmethod - def __init__(self, persist_fs: APersistFS, process_fs): - pass + def __init__(self, persist_fs=None, process_fs=None): + self.persist_fs = persist_fs + self.process_fs = process_fs - @abstractmethod def provide(self) -> None | AFactory: - pass + return AFactory(persist_fs=self.persist_fs) diff --git a/zero_to_one_hundred/factories/sb_factory.py b/zero_to_one_hundred/factories/sb_factory.py index 82fe63d..3b6db2e 100644 --- a/zero_to_one_hundred/factories/sb_factory.py +++ b/zero_to_one_hundred/factories/sb_factory.py @@ -10,6 +10,7 @@ ) from zero_to_one_hundred.repository.sb_persist_fs import SBPersistFS from zero_to_one_hundred.repository.sb_process_fs import SBProcessFS +from zero_to_one_hundred.validator.validator import Validator class SBFactory(AFactory): @@ -28,19 +29,7 @@ def __init__( self.process_fs = process_fs def get_processor(self, args): - parser = argparse.ArgumentParser(description="Run 0to100_sb.") - valid_cmds = list(p.name for p in self.SUPPORTED_PROCESSOR) - parser.add_argument( - "cmd", - type=str, - help=f'command, must be {" ".join(valid_cmds)}', - choices=valid_cmds, - ) - parser.add_argument("p1", type=str, help="arg p1", nargs="?", default=None) - - args = parser.parse_args(args[2:]) - cmd = args.cmd - p1 = args.p1 + cmd, p1 = Validator.validate_args(args) if cmd == SBFactory.SUPPORTED_PROCESSOR.snatch_book.name: http_url = p1 yield self.snatch_book_processor(http_url) @@ -59,6 +48,3 @@ def snatch_book_processor(self, http_url): def refresh_toc_processor(self): return RefreshTocProcessor(self.config_map, self.persist_fs, self.process_fs) - - def help_processor(self): - return HelpProcessor(self.config_map, self.persist_fs, self.SUPPORTED_PROCESSOR) diff --git a/zero_to_one_hundred/factories/sb_factory_provider.py b/zero_to_one_hundred/factories/sb_factory_provider.py index 67bed23..408990d 100644 --- a/zero_to_one_hundred/factories/sb_factory_provider.py +++ b/zero_to_one_hundred/factories/sb_factory_provider.py @@ -19,4 +19,6 @@ def provide(self) -> SBFactory: config_map_type = config_map.get_type if config_map_type == SAFARI_BOOKS_MAP: return SBFactory(config_map, self.persist_fs, self.process_fs) - raise UnsupportedConfigMapError(config_map_type) + raise NotImplementedError( + f"Expected {config_map_type}, check the files contents of {config_map}" + ) diff --git a/zero_to_one_hundred/factories/ztoh_factory.py b/zero_to_one_hundred/factories/ztoh_factory.py index e594496..aef4983 100644 --- a/zero_to_one_hundred/factories/ztoh_factory.py +++ b/zero_to_one_hundred/factories/ztoh_factory.py @@ -12,6 +12,7 @@ from zero_to_one_hundred.processors.refresh_map_processor import RefreshMapProcessor from zero_to_one_hundred.repository.ztoh_persist_fs import ZTOHPersistFS from zero_to_one_hundred.repository.ztoh_process_fs import ZTOHProcessFS +from zero_to_one_hundred.validator.validator import Validator class ZTOHFactory(AFactory): @@ -35,20 +36,7 @@ def __init__( self.process_fs = process_fs def get_processor(self, args): - parser = argparse.ArgumentParser(description="Run 0to100.") - valid_cmds = list(p.name for p in self.SUPPORTED_PROCESSOR) - parser.add_argument( - "cmd", - type=str, - help=f'command, must be {" ".join(valid_cmds)}', - choices=valid_cmds, - ) - parser.add_argument("p1", type=str, help="arg p1", nargs="?", default=None) - - args = parser.parse_args(args[2:]) - cmd = args.cmd - p1 = args.p1 - + cmd, p1 = Validator.validate_args(args) if cmd == ZTOHFactory.SUPPORTED_PROCESSOR.create_section.name: yield self.create_section_processor(p1) yield self.refresh_map_processor() @@ -63,7 +51,7 @@ def get_processor(self, args): elif cmd == ZTOHFactory.SUPPORTED_PROCESSOR.help.name: yield self.help_processor() else: - yield self.unsupported_processor(cmd) + yield self.unsupported_processor(cmd, ZTOHFactory.SUPPORTED_PROCESSOR) def create_section_processor(self, http_url): return CreateSectionProcessor( @@ -80,6 +68,3 @@ def refresh_map_processor(self): def refresh_links_processor(self): return RefreshLinksProcessor(self.config_map, self.persist_fs, self.process_fs) - - def help_processor(self): - return HelpProcessor(self.config_map, self.persist_fs, self.SUPPORTED_PROCESSOR) diff --git a/zero_to_one_hundred/factories/ztoh_factory_provider.py b/zero_to_one_hundred/factories/ztoh_factory_provider.py index 1e2979b..482287c 100644 --- a/zero_to_one_hundred/factories/ztoh_factory_provider.py +++ b/zero_to_one_hundred/factories/ztoh_factory_provider.py @@ -19,5 +19,5 @@ def provide(self) -> ZTOHFactory: if config_map_type == ZTOH_MAP: return ZTOHFactory(config_map, self.persist_fs, self.process_fs) raise NotImplementedError( - f"NotImplementedError {config_map_type}, check the files contents of {config_map.map_yaml_path}" + f"Expected {config_map_type}, check the files contents of {config_map}" ) diff --git a/zero_to_one_hundred/processors/help_processor.py b/zero_to_one_hundred/processors/help_processor.py index 971a2ae..f482e78 100644 --- a/zero_to_one_hundred/processors/help_processor.py +++ b/zero_to_one_hundred/processors/help_processor.py @@ -15,5 +15,6 @@ def __init__( def process(self): logging.info(self.persist_fs.get_pkg_info()) - logging.info(f"{repr(self.config_map)}") - logging.info([p.name for p in self.supported_processor]) + if self.config_map: + logging.info(f"config_map: {repr(self.config_map)}") + logging.info(f"supported: {[p.name for p in self.supported_processor]}") diff --git a/zero_to_one_hundred/processors/unsupported_processor.py b/zero_to_one_hundred/processors/unsupported_processor.py index 88e46d5..daa921b 100644 --- a/zero_to_one_hundred/processors/unsupported_processor.py +++ b/zero_to_one_hundred/processors/unsupported_processor.py @@ -9,9 +9,11 @@ class UnsupportedProcessor(AProcessor): """UnsupportedProcessor: std UnsupportedProcessor""" - def __init__(self, cmd): + def __init__(self, cmd, supp): self.cmd = cmd + self.supp = supp def process(self): - logging.info(f"DDD Unsupported Processor {self.cmd}") - raise UnsupportedOptionError("DDD Unsupported Processor {self.cmd}") + raise UnsupportedOptionError( + f"Unsupported Processor {self.cmd}, supported {[x.name for x in self.supp]}" + ) diff --git a/zero_to_one_hundred/runner.py b/zero_to_one_hundred/runner.py index 01c1ae9..7a78d86 100644 --- a/zero_to_one_hundred/runner.py +++ b/zero_to_one_hundred/runner.py @@ -2,7 +2,7 @@ from typing import List from typing import Union, TypeVar -from zero_to_one_hundred.exceptions.errors import SomeError +from zero_to_one_hundred.exceptions.errors import SomeError, UnsupportedConfigMapError from zero_to_one_hundred.factories.a_factory import AFactory from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider from zero_to_one_hundred.validator.validator import Validator @@ -18,19 +18,5 @@ def run_core(argv: List[str], factory_provider: AFactoryProvider): """ T = TypeVar("T", bound=AFactory) - factory: Union[AFactory, T] - try: - factory = factory_provider.provide() - [processor.process() for processor in factory.get_processor(argv) if processor] - except SomeError as e: - Validator.print_e(e) - return - except FileNotFoundError as e: - Validator.print_e(e) - return - except NotImplementedError as e: - Validator.print_e(e) - return - except Exception as e: - Validator.print_e(e) - factory.help_processor().process() + factory: Union[AFactory, T] = factory_provider.provide() + [processor.process() for processor in factory.get_processor(argv) if processor] diff --git a/zero_to_one_hundred/tests/tests_sb/resources/map.yaml b/zero_to_one_hundred/tests/tests_sb/resources/map.yaml index dd45669..2e3d21b 100644 --- a/zero_to_one_hundred/tests/tests_sb/resources/map.yaml +++ b/zero_to_one_hundred/tests/tests_sb/resources/map.yaml @@ -5,7 +5,7 @@ configs: download_books: false oreilly_username: "username" oreilly_userpassword: "userpassword" - split_pdf_pages: 100 + split_pdf_pages: 0 legend: type: "sb" icons: diff --git a/zero_to_one_hundred/validator/validator.py b/zero_to_one_hundred/validator/validator.py index 735142e..fb97efb 100644 --- a/zero_to_one_hundred/validator/validator.py +++ b/zero_to_one_hundred/validator/validator.py @@ -1,3 +1,4 @@ +import argparse import logging import traceback import re @@ -17,3 +18,17 @@ def is_valid_http(cls, url: str): def print_e(cls, e: Exception): logging.exception(traceback.format_exc()) logging.exception(f"#DDD issue with {e}") + + @classmethod + def validate_args(cls, args): + parser = argparse.ArgumentParser() + parser.add_argument("cmd", type=str, nargs="?", default=None) + parser.add_argument("p1", type=str, nargs="?", default=None) + try: + args = parser.parse_args(args[2:]) # skip fn + cmd = args.cmd + p1 = args.p1 + return cmd, p1 + except Exception: + pass + return None, None From a3da1c222ee99542ee0c6e5f53e4850e9731d6e2 Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 09:22:28 +0200 Subject: [PATCH 02/14] wip --- zero_to_one_hundred/configs/a_config_map.py | 1 - zero_to_one_hundred/factories/a_factory.py | 3 --- zero_to_one_hundred/factories/a_factory_provider.py | 4 ---- zero_to_one_hundred/factories/sb_factory.py | 2 -- zero_to_one_hundred/factories/sb_factory_provider.py | 1 - zero_to_one_hundred/factories/ztoh_factory.py | 2 -- zero_to_one_hundred/processors/unsupported_processor.py | 2 -- zero_to_one_hundred/runner.py | 2 -- zero_to_one_hundred/tests/conftest.py | 1 + zero_to_one_hundred/tests/test_ztoh/test_map.py | 1 + zero_to_one_hundred/validator/validator.py | 3 +-- 11 files changed, 3 insertions(+), 19 deletions(-) diff --git a/zero_to_one_hundred/configs/a_config_map.py b/zero_to_one_hundred/configs/a_config_map.py index 942303a..e842c1b 100644 --- a/zero_to_one_hundred/configs/a_config_map.py +++ b/zero_to_one_hundred/configs/a_config_map.py @@ -1,6 +1,5 @@ # pylint: disable=W0246 import os -from abc import ABC from dataclasses import dataclass from zero_to_one_hundred.exceptions.errors import SomeError diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index 9acaa5f..49d3944 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -1,13 +1,10 @@ -from abc import abstractmethod from enum import Enum from typing import Generator -from zero_to_one_hundred.configs.a_config_map import AConfigMap from zero_to_one_hundred.processors.a_processor import AProcessor from zero_to_one_hundred.processors.help_processor import HelpProcessor from zero_to_one_hundred.processors.unsupported_processor import UnsupportedProcessor from zero_to_one_hundred.repository.a_persist_fs import APersistFS -from zero_to_one_hundred.validator.validator import Validator class AFactory: diff --git a/zero_to_one_hundred/factories/a_factory_provider.py b/zero_to_one_hundred/factories/a_factory_provider.py index d0c0b41..cc09254 100644 --- a/zero_to_one_hundred/factories/a_factory_provider.py +++ b/zero_to_one_hundred/factories/a_factory_provider.py @@ -1,8 +1,4 @@ -from abc import ABC, abstractmethod - -from zero_to_one_hundred.configs.a_config_map import AConfigMap from zero_to_one_hundred.factories.a_factory import AFactory -from zero_to_one_hundred.repository.a_persist_fs import APersistFS class AFactoryProvider: diff --git a/zero_to_one_hundred/factories/sb_factory.py b/zero_to_one_hundred/factories/sb_factory.py index 3b6db2e..6db7f63 100644 --- a/zero_to_one_hundred/factories/sb_factory.py +++ b/zero_to_one_hundred/factories/sb_factory.py @@ -1,9 +1,7 @@ -import argparse from enum import Enum from zero_to_one_hundred.configs.sb_config_map import SBConfigMap from zero_to_one_hundred.factories.a_factory import AFactory -from zero_to_one_hundred.processors.help_processor import HelpProcessor from zero_to_one_hundred.processors.refresh_toc_processor import RefreshTocProcessor from zero_to_one_hundred.processors.snatch_book_processor import ( SnatchBookProcessor, diff --git a/zero_to_one_hundred/factories/sb_factory_provider.py b/zero_to_one_hundred/factories/sb_factory_provider.py index 408990d..5c37d34 100644 --- a/zero_to_one_hundred/factories/sb_factory_provider.py +++ b/zero_to_one_hundred/factories/sb_factory_provider.py @@ -1,5 +1,4 @@ from zero_to_one_hundred.configs.sb_config_map import SAFARI_BOOKS_MAP, SBConfigMap -from zero_to_one_hundred.exceptions.errors import UnsupportedConfigMapError from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider from zero_to_one_hundred.factories.sb_factory import SBFactory from zero_to_one_hundred.repository.sb_persist_fs import SBPersistFS diff --git a/zero_to_one_hundred/factories/ztoh_factory.py b/zero_to_one_hundred/factories/ztoh_factory.py index aef4983..e24ad32 100644 --- a/zero_to_one_hundred/factories/ztoh_factory.py +++ b/zero_to_one_hundred/factories/ztoh_factory.py @@ -1,4 +1,3 @@ -import argparse from enum import Enum from zero_to_one_hundred.configs.ztoh_config_map import ZTOHConfigMap @@ -7,7 +6,6 @@ CreateSectionProcessor, ) from zero_to_one_hundred.processors.done_section_processor import DoneSectionProcessor -from zero_to_one_hundred.processors.help_processor import HelpProcessor from zero_to_one_hundred.processors.refresh_links_processor import RefreshLinksProcessor from zero_to_one_hundred.processors.refresh_map_processor import RefreshMapProcessor from zero_to_one_hundred.repository.ztoh_persist_fs import ZTOHPersistFS diff --git a/zero_to_one_hundred/processors/unsupported_processor.py b/zero_to_one_hundred/processors/unsupported_processor.py index daa921b..edf1f94 100644 --- a/zero_to_one_hundred/processors/unsupported_processor.py +++ b/zero_to_one_hundred/processors/unsupported_processor.py @@ -1,5 +1,3 @@ -import logging - from zero_to_one_hundred.exceptions.errors import UnsupportedOptionError from zero_to_one_hundred.processors.a_processor import AProcessor diff --git a/zero_to_one_hundred/runner.py b/zero_to_one_hundred/runner.py index 7a78d86..de4c48f 100644 --- a/zero_to_one_hundred/runner.py +++ b/zero_to_one_hundred/runner.py @@ -2,10 +2,8 @@ from typing import List from typing import Union, TypeVar -from zero_to_one_hundred.exceptions.errors import SomeError, UnsupportedConfigMapError from zero_to_one_hundred.factories.a_factory import AFactory from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider -from zero_to_one_hundred.validator.validator import Validator def run_core(argv: List[str], factory_provider: AFactoryProvider): diff --git a/zero_to_one_hundred/tests/conftest.py b/zero_to_one_hundred/tests/conftest.py index e060feb..6ee6d1d 100644 --- a/zero_to_one_hundred/tests/conftest.py +++ b/zero_to_one_hundred/tests/conftest.py @@ -1,5 +1,6 @@ import string from unittest.mock import patch + import pytest diff --git a/zero_to_one_hundred/tests/test_ztoh/test_map.py b/zero_to_one_hundred/tests/test_ztoh/test_map.py index c71151a..e747557 100644 --- a/zero_to_one_hundred/tests/test_ztoh/test_map.py +++ b/zero_to_one_hundred/tests/test_ztoh/test_map.py @@ -7,6 +7,7 @@ from zero_to_one_hundred.models.section import Section from zero_to_one_hundred.tests.conftest import str_relaxed + # pylint: disable=W0102 diff --git a/zero_to_one_hundred/validator/validator.py b/zero_to_one_hundred/validator/validator.py index fb97efb..ff787f2 100644 --- a/zero_to_one_hundred/validator/validator.py +++ b/zero_to_one_hundred/validator/validator.py @@ -1,8 +1,7 @@ import argparse import logging -import traceback import re - +import traceback from zero_to_one_hundred.exceptions.errors import NotURLFormatError From c648954a28fcb3b816da085a9ec503486489a2e4 Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:08:13 +0000 Subject: [PATCH 03/14] wip --- zero_to_one_hundred/factories/sb_factory.py | 4 ++-- zero_to_one_hundred/factories/ztoh_factory.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/zero_to_one_hundred/factories/sb_factory.py b/zero_to_one_hundred/factories/sb_factory.py index 6db7f63..8cab1dc 100644 --- a/zero_to_one_hundred/factories/sb_factory.py +++ b/zero_to_one_hundred/factories/sb_factory.py @@ -22,8 +22,8 @@ class SUPPORTED_PROCESSOR(Enum): def __init__( self, config_map: SBConfigMap, persist_fs: SBPersistFS, process_fs: SBProcessFS ): + super().__init__(persist_fs=persist_fs) self.config_map = config_map - self.persist_fs = persist_fs self.process_fs = process_fs def get_processor(self, args): @@ -37,7 +37,7 @@ def get_processor(self, args): elif cmd == SBFactory.SUPPORTED_PROCESSOR.help.name: yield self.help_processor() else: - yield self.unsupported_processor(cmd) + yield self.unsupported_processor(cmd, self.SUPPORTED_PROCESSOR) def snatch_book_processor(self, http_url): return SnatchBookProcessor( diff --git a/zero_to_one_hundred/factories/ztoh_factory.py b/zero_to_one_hundred/factories/ztoh_factory.py index e24ad32..0460d33 100644 --- a/zero_to_one_hundred/factories/ztoh_factory.py +++ b/zero_to_one_hundred/factories/ztoh_factory.py @@ -29,8 +29,8 @@ def __init__( persist_fs: ZTOHPersistFS, process_fs: ZTOHProcessFS, ): + super().__init__(persist_fs=persist_fs) self.config_map = config_map - self.persist_fs = persist_fs self.process_fs = process_fs def get_processor(self, args): @@ -49,7 +49,7 @@ def get_processor(self, args): elif cmd == ZTOHFactory.SUPPORTED_PROCESSOR.help.name: yield self.help_processor() else: - yield self.unsupported_processor(cmd, ZTOHFactory.SUPPORTED_PROCESSOR) + yield self.unsupported_processor(cmd, self.SUPPORTED_PROCESSOR) def create_section_processor(self, http_url): return CreateSectionProcessor( From ca947edf9d30b873eaeeeb5d14d7d66107004a73 Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 09:45:52 +0200 Subject: [PATCH 04/14] wip --- .../processors/unsupported_processor.py | 3 ++- .../tests/test_ztoh/test_ztoh_config_map.py | 10 ++-------- .../tests/tests_sb/test_sb_config_map.py | 11 ++--------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/zero_to_one_hundred/processors/unsupported_processor.py b/zero_to_one_hundred/processors/unsupported_processor.py index edf1f94..5fc38ad 100644 --- a/zero_to_one_hundred/processors/unsupported_processor.py +++ b/zero_to_one_hundred/processors/unsupported_processor.py @@ -12,6 +12,7 @@ def __init__(self, cmd, supp): self.supp = supp def process(self): + res = " ".join([s.name for s in self.supp]) raise UnsupportedOptionError( - f"Unsupported Processor {self.cmd}, supported {[x.name for x in self.supp]}" + f"Unsupported Processor {self.cmd}, supported {res}" ) diff --git a/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py b/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py index fd8787f..0c43539 100644 --- a/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py +++ b/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py @@ -1,4 +1,6 @@ from zero_to_one_hundred.configs.ztoh_config_map import ZTOH_MAP, ZTOHConfigMap +from zero_to_one_hundred.tests.conftest import str_relaxed + # pylint: disable=W0621,W0613 @@ -11,14 +13,6 @@ def test_config_map(get_config_map: ZTOHConfigMap): assert actual.get_legend_type is None -def test__repr__(get_config_map: ZTOHConfigMap, get_map_yaml_path: str): - actual = get_config_map - assert ( - repr(actual) - == f"MAP_YAML_PATH from {get_map_yaml_path} type {get_config_map.get_type}" - ) - - def test_gcp_config_map(get_gcp_config_map: ZTOHConfigMap): actual = get_gcp_config_map assert actual.get_type == ZTOH_MAP diff --git a/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py b/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py index 5cfc915..df5b169 100644 --- a/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py +++ b/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py @@ -1,4 +1,5 @@ from zero_to_one_hundred.configs.sb_config_map import SAFARI_BOOKS_MAP, SBConfigMap +from zero_to_one_hundred.tests.conftest import str_relaxed # pylint: disable=W0621,W0613 @@ -12,13 +13,5 @@ def test_provide__pass(get_config_map: SBConfigMap): assert actual.get_oreilly_username is not None assert actual.get_oreilly_userpassword is not None assert actual.get_oreilly_userpassword is not None - assert actual.get_split_pdf_pages == 100 + assert actual.get_split_pdf_pages == 0 assert actual.get_download_books is False - - -def test__repr__(get_config_map: SBConfigMap, get_map_yaml_path: str): - actual = get_config_map - assert ( - repr(actual) - == f"MAP_YAML_PATH from {get_map_yaml_path} type {get_config_map.get_type}" - ) From c383e004f10c2b44e3da5c9c5c741507ffb15800 Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:26:04 +0000 Subject: [PATCH 05/14] wip --- zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py | 1 - zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py | 1 - 2 files changed, 2 deletions(-) diff --git a/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py b/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py index 0c43539..4472d90 100644 --- a/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py +++ b/zero_to_one_hundred/tests/test_ztoh/test_ztoh_config_map.py @@ -1,5 +1,4 @@ from zero_to_one_hundred.configs.ztoh_config_map import ZTOH_MAP, ZTOHConfigMap -from zero_to_one_hundred.tests.conftest import str_relaxed # pylint: disable=W0621,W0613 diff --git a/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py b/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py index df5b169..595963c 100644 --- a/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py +++ b/zero_to_one_hundred/tests/tests_sb/test_sb_config_map.py @@ -1,5 +1,4 @@ from zero_to_one_hundred.configs.sb_config_map import SAFARI_BOOKS_MAP, SBConfigMap -from zero_to_one_hundred.tests.conftest import str_relaxed # pylint: disable=W0621,W0613 From 4e7940652bced0b3fab795bf143526f81d357df4 Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 09:51:27 +0200 Subject: [PATCH 06/14] wip --- Makefile | 2 +- setup.py | 3 ++- toc_sb.md | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 41f2a35..333f104 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ test: python -m pytest zero_to_one_hundred testint: - bash demo.sh 0to100_zt && bash demo.sh 0to100_sb + bash demo.sh zt && bash demo.sh sb format: black zero_to_one_hundred diff --git a/setup.py b/setup.py index 6d63f69..56be1a5 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from pathlib import Path -from setuptools import setup +from setuptools import setup, find_packages directory = Path(__file__).resolve().parent with open(directory / "README.md", encoding="utf-8") as f: @@ -14,6 +14,7 @@ name="0to100", version="0.5.3", author="obar1", + packages=find_packages(), author_email="obar1+gh@pm.me", description="Simple python tool to learn everything and keep it local.", long_description=long_description, diff --git a/toc_sb.md b/toc_sb.md index 1ffefe2..4b3f97c 100644 --- a/toc_sb.md +++ b/toc_sb.md @@ -1,7 +1,7 @@ # TOC ## `2` metabook -### 2024/09/13-07:48:42 +### 2024/09/13-09:51:03 ## legend: From 212175791f77b24024787c1e42ccb82a4128afd0 Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:41:01 +0000 Subject: [PATCH 07/14] wip --- README.md | 4 +++- main.py | 2 +- toc_sb.md | 2 +- zero_to_one_hundred/processors/help_processor.py | 2 +- zero_to_one_hundred/processors/unsupported_processor.py | 4 ++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0ded9f1..cd670d5 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ | [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=obar1_0to100)](https://sonarcloud.io/summary/new_code?id=obar1_0to100) | [![Makefile CI](https://github.com/obar1/0to100/actions/workflows/makefile.yml/badge.svg)](https://github.com/obar1/0to100/actions/workflows/makefile.yml) | We read training material from the web and learn from it by doing, but how do we keep that a bit organized? I came up with an idea: this small tool. -Given a 'url', it creates the entry in a markdown map and a folder and links them; in this way, you can easily jump between different sections inside your preferred ide. As you expand the map with new contents, you build some reference material, keep it local all the time, and searchable all the time on your daily coding. +Given a 'url', it creates the entry in a markdown map and a folder and links them; in this way, you can easily jump between different sections inside your preferred ide. As you expand the map with new contents, you build some reference material, keep it local all the time, and searchable all the time on your daily coding and use it to fee your local `llm` :). ## quick demo @@ -20,12 +20,14 @@ bash demo.sh zt ``` ![](2dc4491c-fa27-4c5e-bd0c-71951b3ef0e5.png) +[here](./toc_zt.md) ```bash bash demo.sh sb ``` ![](z05502bb-4b90-422f-9624-568d9f02cd01.png) +[here](./toc_sb.md) ## oto100 diff --git a/main.py b/main.py index 2f38813..86408e9 100755 --- a/main.py +++ b/main.py @@ -29,7 +29,7 @@ except (ValueError,IndexError, TypeError): from zero_to_one_hundred.repository.a_persist_fs import APersistFS as persist_fs from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider - run_core(sys.argv, AFactoryProvider(persist_fs=persist_fs)) + run_core(sys.argv, AFactoryProvider(persist_fs)) except Exception as e: Validator.print_e(e) diff --git a/toc_sb.md b/toc_sb.md index 4b3f97c..dab2d9a 100644 --- a/toc_sb.md +++ b/toc_sb.md @@ -1,7 +1,7 @@ # TOC ## `2` metabook -### 2024/09/13-09:51:03 +### 2024/09/13-08:37:28 ## legend: diff --git a/zero_to_one_hundred/processors/help_processor.py b/zero_to_one_hundred/processors/help_processor.py index f482e78..fa6bc04 100644 --- a/zero_to_one_hundred/processors/help_processor.py +++ b/zero_to_one_hundred/processors/help_processor.py @@ -17,4 +17,4 @@ def process(self): logging.info(self.persist_fs.get_pkg_info()) if self.config_map: logging.info(f"config_map: {repr(self.config_map)}") - logging.info(f"supported: {[p.name for p in self.supported_processor]}") + logging.info(f"supported: {[s.name for s in self.supported_processor]}") diff --git a/zero_to_one_hundred/processors/unsupported_processor.py b/zero_to_one_hundred/processors/unsupported_processor.py index 5fc38ad..da5ca6c 100644 --- a/zero_to_one_hundred/processors/unsupported_processor.py +++ b/zero_to_one_hundred/processors/unsupported_processor.py @@ -12,7 +12,7 @@ def __init__(self, cmd, supp): self.supp = supp def process(self): - res = " ".join([s.name for s in self.supp]) + supp_str = "`{}`".format('` `'.join([s.name for s in self.supp])) raise UnsupportedOptionError( - f"Unsupported Processor {self.cmd}, supported {res}" + f"Unsupported Processor `{self.cmd}`, supported: {supp_str}" ) From c7deb6bcda0e9d589e68f1456072e7e2393c0809 Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 10:04:18 +0200 Subject: [PATCH 08/14] wip --- 50a86373-910b-4a12-85ef-251b6d4f08f0.png | Bin 11357 -> 0 bytes 9b873c30-eccb-4c17-9d36-1c302060f5c3.png | Bin 57034 -> 0 bytes ab67dd2b-7c12-4cdf-a7a5-f773c2b67919.png | Bin 9198 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 50a86373-910b-4a12-85ef-251b6d4f08f0.png delete mode 100644 9b873c30-eccb-4c17-9d36-1c302060f5c3.png delete mode 100644 ab67dd2b-7c12-4cdf-a7a5-f773c2b67919.png diff --git a/50a86373-910b-4a12-85ef-251b6d4f08f0.png b/50a86373-910b-4a12-85ef-251b6d4f08f0.png deleted file mode 100644 index 508f880a9d23e5deda1c619036568f40599b3d12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11357 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%0AO!I$s`twXualE-)ACN5d58<}m8oj&dq;gp) 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

9r=Rv1YfCuJ^K#B{#(ucZKa!YuUJoQS!clZO>!# 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 From a62c3c3c7df2bea6de185d2ef826f64cf5b83c6a Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 10:20:12 +0200 Subject: [PATCH 09/14] wip --- zero_to_one_hundred/factories/a_factory.py | 7 ++++++- zero_to_one_hundred/factories/sb_factory.py | 8 ++++++++ zero_to_one_hundred/factories/ztoh_factory.py | 16 ++++++++++++++++ .../factories/ztoh_factory_provider.py | 2 ++ zero_to_one_hundred/processors/help_processor.py | 6 +++--- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index 49d3944..800f32d 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -15,6 +15,11 @@ class SUPPORTED_PROCESSOR(Enum): sb = 2 help = 3 + extended_help = """ + zt = zeto to 100 + sb = sb to 100 + """ + def __init__(self, persist_fs: APersistFS): self.persist_fs = persist_fs @@ -22,7 +27,7 @@ def get_processor(self, args) -> Generator[AProcessor, None, None]: yield self.help_processor() def help_processor(self): - return HelpProcessor(None, self.persist_fs, self.SUPPORTED_PROCESSOR) + return HelpProcessor(None, self.persist_fs, self.SUPPORTED_PROCESSOR, self.extended_help) @staticmethod def unsupported_processor(cmd, supp): diff --git a/zero_to_one_hundred/factories/sb_factory.py b/zero_to_one_hundred/factories/sb_factory.py index 8cab1dc..a16df62 100644 --- a/zero_to_one_hundred/factories/sb_factory.py +++ b/zero_to_one_hundred/factories/sb_factory.py @@ -19,6 +19,14 @@ class SUPPORTED_PROCESSOR(Enum): refresh_toc = 2 help = 3 + extended_help = """ + snatch_book = snatch a book from safari + ./main.py sb snatch_book https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947 + + refresh_toc = refresh the toc with al the books info + ./main.py sb refresh_toc + """ + def __init__( self, config_map: SBConfigMap, persist_fs: SBPersistFS, process_fs: SBProcessFS ): diff --git a/zero_to_one_hundred/factories/ztoh_factory.py b/zero_to_one_hundred/factories/ztoh_factory.py index 0460d33..ce4168d 100644 --- a/zero_to_one_hundred/factories/ztoh_factory.py +++ b/zero_to_one_hundred/factories/ztoh_factory.py @@ -23,6 +23,22 @@ class SUPPORTED_PROCESSOR(Enum): refresh_links = 4 help = 5 + extended_help = """ + create_section = create a new section + section=https://www.cloudskillsboost.google/paths/16 + ./main.py zt create_section "$section" + + done_section = tag a section as done + section=https://www.cloudskillsboost.google/paths/16 + ./main.py zt done_section "$section" + + refresh_map = refresh the section map + ./main.py zt refresh_map + + refresh_links = refresh links to sections in the readme.md(s) + ./main.py zt refresh_links + """ + def __init__( self, config_map: ZTOHConfigMap, diff --git a/zero_to_one_hundred/factories/ztoh_factory_provider.py b/zero_to_one_hundred/factories/ztoh_factory_provider.py index 482287c..75eaf9e 100644 --- a/zero_to_one_hundred/factories/ztoh_factory_provider.py +++ b/zero_to_one_hundred/factories/ztoh_factory_provider.py @@ -1,3 +1,5 @@ +from typing import Type + from zero_to_one_hundred.configs.ztoh_config_map import ZTOH_MAP, ZTOHConfigMap from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider from zero_to_one_hundred.factories.ztoh_factory import ZTOHFactory diff --git a/zero_to_one_hundred/processors/help_processor.py b/zero_to_one_hundred/processors/help_processor.py index fa6bc04..2dfe6cc 100644 --- a/zero_to_one_hundred/processors/help_processor.py +++ b/zero_to_one_hundred/processors/help_processor.py @@ -6,15 +6,15 @@ class HelpProcessor(AProcessor): - def __init__( - self, config_map: AConfigMap, persist_fs: APersistFS, supported_processor - ): + def __init__(self, config_map: AConfigMap, persist_fs: APersistFS, supported_processor, extended_help): self.config_map = config_map self.persist_fs = persist_fs self.supported_processor = supported_processor + self.extended_help= extended_help def process(self): logging.info(self.persist_fs.get_pkg_info()) if self.config_map: logging.info(f"config_map: {repr(self.config_map)}") logging.info(f"supported: {[s.name for s in self.supported_processor]}") + logging.info(f"extended help: {self.extended_help}") From aeb1334159cb8aadcd824e15ad2baf2ec4bdfa36 Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 10:57:04 +0200 Subject: [PATCH 10/14] wip --- main.py | 3 ++- zero_to_one_hundred/factories/a_factory.py | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 86408e9..2365712 100755 --- a/main.py +++ b/main.py @@ -5,6 +5,7 @@ import sys import logging +from zero_to_one_hundred.exceptions.errors import UnsupportedOptionError from zero_to_one_hundred.runner import run_core from zero_to_one_hundred.validator.validator import Validator @@ -26,7 +27,7 @@ run_core(sys.argv, SBFactoryProvider(persist_fs, process_fs)) case _: raise ValueError - except (ValueError,IndexError, TypeError): + except (ValueError,IndexError, TypeError,UnsupportedOptionError): from zero_to_one_hundred.repository.a_persist_fs import APersistFS as persist_fs from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider run_core(sys.argv, AFactoryProvider(persist_fs)) diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index 800f32d..853db91 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -16,8 +16,14 @@ class SUPPORTED_PROCESSOR(Enum): help = 3 extended_help = """ - zt = zeto to 100 + zt = zero to 100 + ./main.py zt help + sb = sb to 100 + ./main.py sb help + + help = this :) + ./main.py help """ def __init__(self, persist_fs: APersistFS): From b80f52e5c11c75e5ea799ef6d614de5945d48d6b Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:37:31 +0000 Subject: [PATCH 11/14] wip --- toc_sb.md | 2 +- toc_zt.md | 2 +- zero_to_one_hundred/factories/a_factory.py | 4 +++- zero_to_one_hundred/processors/help_processor.py | 10 ++++++++-- .../processors/unsupported_processor.py | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/toc_sb.md b/toc_sb.md index dab2d9a..78ddb7e 100644 --- a/toc_sb.md +++ b/toc_sb.md @@ -1,7 +1,7 @@ # TOC ## `2` metabook -### 2024/09/13-08:37:28 +### 2024/09/13-09:37:09 ## legend: diff --git a/toc_zt.md b/toc_zt.md index a4e0340..b951d8f 100644 --- a/toc_zt.md +++ b/toc_zt.md @@ -9,9 +9,9 @@ `Game` :snake: `Course` :pushpin: -1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§paths§16/readme.md) `wip` :cyclone: 1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§games§4424§labs§28651/readme.md) `wip` :floppy_disk: :snake: 1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§course_templates§3/readme.md) `wip` :whale: :pushpin: 1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§games§4422/readme.md) `wip` :snake: 1. # [`here`](./0to100/https§§§storage.googleapis.com§cloud-training§cls-html5-courses§T-BQRS-I§M1§index.html/readme.md) `wip` :pushpin: 1. # a_custom_header 0 [`here`](./0to100/https§§§www.cloudskillsboost.google§0/readme.md) `done` +1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§paths§16/readme.md) `done` :cyclone: diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index 853db91..c7ec3b9 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -33,7 +33,9 @@ def get_processor(self, args) -> Generator[AProcessor, None, None]: yield self.help_processor() def help_processor(self): - return HelpProcessor(None, self.persist_fs, self.SUPPORTED_PROCESSOR, self.extended_help) + return HelpProcessor( + None, self.persist_fs, self.SUPPORTED_PROCESSOR, self.extended_help + ) @staticmethod def unsupported_processor(cmd, supp): diff --git a/zero_to_one_hundred/processors/help_processor.py b/zero_to_one_hundred/processors/help_processor.py index 2dfe6cc..371177f 100644 --- a/zero_to_one_hundred/processors/help_processor.py +++ b/zero_to_one_hundred/processors/help_processor.py @@ -6,11 +6,17 @@ class HelpProcessor(AProcessor): - def __init__(self, config_map: AConfigMap, persist_fs: APersistFS, supported_processor, extended_help): + def __init__( + self, + config_map: AConfigMap, + persist_fs: APersistFS, + supported_processor, + extended_help, + ): self.config_map = config_map self.persist_fs = persist_fs self.supported_processor = supported_processor - self.extended_help= extended_help + self.extended_help = extended_help def process(self): logging.info(self.persist_fs.get_pkg_info()) diff --git a/zero_to_one_hundred/processors/unsupported_processor.py b/zero_to_one_hundred/processors/unsupported_processor.py index da5ca6c..48f0727 100644 --- a/zero_to_one_hundred/processors/unsupported_processor.py +++ b/zero_to_one_hundred/processors/unsupported_processor.py @@ -12,7 +12,7 @@ def __init__(self, cmd, supp): self.supp = supp def process(self): - supp_str = "`{}`".format('` `'.join([s.name for s in self.supp])) + supp_str = "`{}`".format("` `".join([s.name for s in self.supp])) raise UnsupportedOptionError( f"Unsupported Processor `{self.cmd}`, supported: {supp_str}" ) From 144141b5938f98baf6af3c2e82aefa2d80783de2 Mon Sep 17 00:00:00 2001 From: obar1 Date: Fri, 13 Sep 2024 11:07:07 +0200 Subject: [PATCH 12/14] wip --- README.md | 20 +++++++++++++++++-- toc_sb.md | 2 +- toc_zt.md | 2 +- .../factories/ztoh_factory_provider.py | 2 -- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cd670d5..db29ad8 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,19 @@ bash demo.sh sb commands: ``` -['create_section', 'done_section', 'refresh_map', 'refresh_links', 'help'] +create_section = create a new section +section=https://www.cloudskillsboost.google/paths/16 +./main.py zt create_section "$section" + +done_section = tag a section as done +section=https://www.cloudskillsboost.google/paths/16 +./main.py zt done_section "$section" + +refresh_map = refresh the section map +./main.py zt refresh_map + +refresh_links = refresh links to sections in the readme.md(s) +./main.py zt refresh_links ``` > tip @@ -90,7 +102,11 @@ same as above but it can use some external lib to grab epub from oreilly current commands: ``` -['snatch_book', 'refresh_toc', 'help'] +snatch_book = snatch a book from safari +./main.py sb snatch_book https://learning.oreilly.com/library/view/rewire-your-brain/9781119895947 + +refresh_toc = refresh the toc with al the books info +./main.py sb refresh_toc ``` ### setup and usage: diff --git a/toc_sb.md b/toc_sb.md index 78ddb7e..742b634 100644 --- a/toc_sb.md +++ b/toc_sb.md @@ -1,7 +1,7 @@ # TOC ## `2` metabook -### 2024/09/13-09:37:09 +### 2024/09/13-11:06:37 ## legend: diff --git a/toc_zt.md b/toc_zt.md index b951d8f..a4e0340 100644 --- a/toc_zt.md +++ b/toc_zt.md @@ -9,9 +9,9 @@ `Game` :snake: `Course` :pushpin: +1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§paths§16/readme.md) `wip` :cyclone: 1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§games§4424§labs§28651/readme.md) `wip` :floppy_disk: :snake: 1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§course_templates§3/readme.md) `wip` :whale: :pushpin: 1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§games§4422/readme.md) `wip` :snake: 1. # [`here`](./0to100/https§§§storage.googleapis.com§cloud-training§cls-html5-courses§T-BQRS-I§M1§index.html/readme.md) `wip` :pushpin: 1. # a_custom_header 0 [`here`](./0to100/https§§§www.cloudskillsboost.google§0/readme.md) `done` -1. # [`here`](./0to100/https§§§www.cloudskillsboost.google§paths§16/readme.md) `done` :cyclone: diff --git a/zero_to_one_hundred/factories/ztoh_factory_provider.py b/zero_to_one_hundred/factories/ztoh_factory_provider.py index 75eaf9e..482287c 100644 --- a/zero_to_one_hundred/factories/ztoh_factory_provider.py +++ b/zero_to_one_hundred/factories/ztoh_factory_provider.py @@ -1,5 +1,3 @@ -from typing import Type - from zero_to_one_hundred.configs.ztoh_config_map import ZTOH_MAP, ZTOHConfigMap from zero_to_one_hundred.factories.a_factory_provider import AFactoryProvider from zero_to_one_hundred.factories.ztoh_factory import ZTOHFactory From 2e3f3812652986dbcc6324ff6fdcbd23b7533ca3 Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:42:32 +0000 Subject: [PATCH 13/14] wip --- zero_to_one_hundred/factories/a_factory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index c7ec3b9..c2e3666 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -29,7 +29,7 @@ class SUPPORTED_PROCESSOR(Enum): def __init__(self, persist_fs: APersistFS): self.persist_fs = persist_fs - def get_processor(self, args) -> Generator[AProcessor, None, None]: + def get_processor(self) -> Generator[AProcessor, None, None]: yield self.help_processor() def help_processor(self): From a3a30a89605afaf8ebeca72011e1d034e5fe9200 Mon Sep 17 00:00:00 2001 From: obar1 <387386+obar1@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:44:51 +0000 Subject: [PATCH 14/14] wip --- zero_to_one_hundred/factories/a_factory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zero_to_one_hundred/factories/a_factory.py b/zero_to_one_hundred/factories/a_factory.py index c2e3666..eae26fb 100644 --- a/zero_to_one_hundred/factories/a_factory.py +++ b/zero_to_one_hundred/factories/a_factory.py @@ -29,7 +29,7 @@ class SUPPORTED_PROCESSOR(Enum): def __init__(self, persist_fs: APersistFS): self.persist_fs = persist_fs - def get_processor(self) -> Generator[AProcessor, None, None]: + def get_processor(self,args) -> Generator[AProcessor, None, None]: yield self.help_processor() def help_processor(self):