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 @@
-
\ 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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