Compare commits

..

48 commits

Author SHA1 Message Date
8ab616e5fd 🚀 It's a new version!
All checks were successful
Release / check_for_changed_version (push) Successful in 26s
Release / build (push) Successful in 3m53s
2023-05-19 09:52:57 -04:00
1749a8659a Merge pull request 'reddit-support' (#1) from reddit-support into master
All checks were successful
Release / check_for_changed_version (push) Successful in 31s
Release / build (push) Successful in 4m10s
Reviewed-on: #1
2023-05-18 21:51:39 -04:00
5592c0e7cd finish reddit support 2023-05-18 21:49:23 -04:00
b8a482f86c 👷 doin' the thing 2023-05-18 18:45:40 -04:00
d3595cf6b0 👷 turns out I need to wait until 1.20.0
All checks were successful
Release / check_for_changed_version (push) Successful in 24s
Release / build (push) Successful in 3m54s
2023-04-26 10:31:15 -04:00
05d2f5829d 👷 shenanigans with versions
Some checks failed
Release / check_for_changed_version (push) Successful in 22s
Release / checkvar (push) Successful in 19s
Release / build (push) Failing after 3s
2023-04-26 10:26:27 -04:00
4fd6848372 💚 update version number to check deploy
All checks were successful
Release / check_for_changed_version (push) Successful in 23s
Release / build (push) Has been skipped
2023-04-26 10:20:25 -04:00
ff3319a2fc Merge remote-tracking branch 'origin/master'
All checks were successful
Release / check_for_changed_version (push) Successful in 22s
Release / build (push) Has been skipped
2023-04-26 10:16:52 -04:00
4568dd0e4c 💚 test 'needs' jobs on gitea 1.19.1 without changing the version number 2023-04-26 10:16:26 -04:00
fc2e10f9ad add local scope to shell
All checks were successful
build
check_for_changed_version
2023-04-23 16:04:23 -04:00
52e563c4dd 'needs' check not fixed yet
All checks were successful
build
check_for_changed_version
2023-04-17 17:08:22 -04:00
9d6a3c58d9 change version number
Some checks failed
check_for_changed_version
build
2023-04-17 16:51:34 -04:00
ce6d4d3ab8 add needs step back in
Some checks failed
check_for_changed_version
build
2023-04-17 16:49:42 -04:00
d87c813ddf test build for adding joplin conversion support
All checks were successful
build
check_for_changed_version
2023-04-17 00:38:18 -04:00
bd645ee02d 💚 apparently most of the gitea-specific envs don't work yet
All checks were successful
build
check_for_changed_version
2023-04-06 14:58:20 -04:00
a9eb6da4bd 💚 apparently GITEA_ENV isn't supported yet
Some checks failed
build
check_for_changed_version
2023-04-06 14:30:24 -04:00
a05332ba66 👷 change github -> gitea
Some checks failed
build
check_for_changed_version
2023-04-06 14:15:30 -04:00
9703aba83b 💚 gitea can't support "needs" yet. Will be fixed in next release 2023-04-06 14:13:51 -04:00
ec6d5fd2a2 add bson objectId 2023-04-06 14:12:48 -04:00
c9dc7fb270 adjust workflow to only run if version changes
Some checks failed
build
check_for_changed_version
2023-04-05 18:49:48 -04:00
cf61dcf705 fix issue with beautification
All checks were successful
build
2023-03-31 23:55:45 -04:00
f41a9f9966 fuckin' bash
All checks were successful
build
2023-03-25 21:33:05 -04:00
fd9830559b pull out json data
All checks were successful
build
2023-03-25 21:22:03 -04:00
4f9653558a make step clearer
All checks were successful
build
2023-03-25 20:45:42 -04:00
7a891f252e change message to get rid of backslashes
All checks were successful
build
2023-03-25 00:38:24 -04:00
e60cb703f3 add missing slash
Some checks failed
build
2023-03-25 00:27:21 -04:00
d98f3e4be2 adjust curl command
Some checks failed
build
2023-03-25 00:21:28 -04:00
12f020b0c8 move the update command to a flag
All checks were successful
build
2023-03-23 21:17:58 -04:00
e0e7eadbe0 another release 2
All checks were successful
build
2023-03-23 19:48:52 -04:00
e6dc6750ac another release
All checks were successful
build
2023-03-23 19:41:03 -04:00
10ee297269 try new release
All checks were successful
build
2023-03-23 19:30:25 -04:00
53499b0cbf update poetry2setup for modern poetry
All checks were successful
build
2023-03-23 00:21:57 -04:00
e23ab397a6 more lsb fun
Some checks failed
build
2023-03-22 23:37:25 -04:00
81989bdb89 lsb fun
Some checks failed
build
2023-03-22 23:31:00 -04:00
e0ecad451d update python
Some checks failed
build
2023-03-22 22:30:02 -04:00
81ef514459 try actions 2023-03-22 22:27:33 -04:00
8fffbb52a5 better exceptions 2022-08-16 13:17:43 -04:00
4580ab21a7 make print default to Rich version 2022-08-15 13:29:44 -04:00
d44340ab9d time to get RICH 2022-08-11 16:14:04 -04:00
dda6c9f1b7 add roller 2022-07-29 14:29:14 -04:00
203bf6d598 add test command to verify update functionality 2022-07-29 11:45:38 -04:00
e4b2d984ad fix update bug 2022-07-29 11:43:40 -04:00
c6180948c0 fix help message and update locals for repl 2022-07-28 13:33:12 -04:00
485e65a6c6 convert to click 2022-07-28 13:28:23 -04:00
83e685d4a7 remove test step 2022-07-23 15:39:56 -04:00
b2dde49957 test with timestamps 2022-07-23 15:36:49 -04:00
e3a55df241 get rid of the v 2022-07-23 15:27:57 -04:00
442ccce071 switch to datetime 2022-07-23 15:26:10 -04:00
14 changed files with 1756 additions and 388 deletions

View file

@ -0,0 +1,80 @@
name: Release
on:
push:
branches:
- master
jobs:
check_for_changed_version:
runs-on: 'ubuntu-latest'
# Declare outputs for next jobs
outputs:
version_changed: ${{ steps.check_file_changed.outputs.version_changed }}
steps:
- uses: actions/checkout@v2
with:
# Checkout as many commits as needed for the diff
fetch-depth: 2
- id: check_file_changed
run: |
# Diff HEAD with the previous commit
if git diff HEAD^ HEAD pyproject.toml | grep -q "+version =";
then
GOTIME="True"
else
GOTIME="False"
fi
echo "::notice title=GOTIME::$GOTIME"
# Set the output named "version_changed"
echo "version_changed=$GOTIME" >> $GITHUB_OUTPUT
build:
runs-on: ubuntu-latest
# this should start working with https://github.com/go-gitea/gitea/pull/24230
# needs: [ check_for_changed_version ]
# if: needs.check_for_changed_version.outputs.version_changed == 'True'
permissions:
contents: write
steps:
- uses: https://github.com/actions/checkout@v2
- uses: https://github.com/actions/setup-python@v4
with:
python-version: '3.11.x'
- name: Install Env
# this should be all we need because shiv will download the deps itself
run: |
pip install --upgrade pip
pip install shiv
pip install poetry
- name: Add VERSION env property
run: |
echo "VERSION=v$(poetry version | python -c 'import sys;print(sys.stdin.read().split()[1])')" >> $GITHUB_ENV
echo ${{ env.VERSION }}
- name: Build the sucker
run: |
sed -i -e "s/?????/${{ env.VERSION }}/g" src/__init__.py
make build
- name: Create release!
run: |
JSON_DATA=$(
printf '%s' \
'{'\
'"tag_name":"${{ env.VERSION }}",'\
'"name":"${{ env.VERSION }}",'\
'"body":"RELEASE THE KRAKEN"'\
'}' \
)
echo """release_id=$(\
curl -X POST \
-s https://git.joekaufeld.com/api/v1/repos/${GITHUB_REPOSITORY%/*}/${{ github.event.repository.name }}/releases \
-H "Authorization: token ${{ secrets.PAT }}" \
-H 'Content-Type: application/json' \
-d "$JSON_DATA" \
| python3 -c "import sys, json; print(json.load(sys.stdin)['id'])"\
)""" >> $GITHUB_ENV
- name: Upload assets!
run: |
curl https://git.joekaufeld.com/api/v1/repos/${GITHUB_REPOSITORY%/*}/${{ github.event.repository.name }}/releases/${{ env.release_id }}/assets \
-H "Authorization: token ${{ secrets.PAT }}" \
-F attachment=@utils

View file

@ -1,37 +0,0 @@
name: Release
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v4
with:
python-version: '3.10.x'
- name: Install Env
# this should be all we need because shiv will download the deps itself
run: |
pip install shiv
pip install poetry
# https://stackoverflow.com/a/64195658
- name: Add SHORT_SHA env property with commit short sha
run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-7`" >> $GITHUB_ENV
- name: Build the sucker
run: |
sed -i -e "s/?????/${{ env.SHORT_SHA }}/g" src/__init__.py
make build
- uses: ncipollo/release-action@v1
with:
artifacts: "utils"
body: "It's releasin' time"
generateReleaseNotes: false
tag: ${{ env.SHORT_SHA }}
commit: master
token: ${{ secrets.PAT }}

1
.gitignore vendored
View file

@ -129,3 +129,4 @@ dmypy.json
.pyre/ .pyre/
setup.py setup.py
utils utils
praw.ini

1484
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "src" name = "src"
version = "0.1.0" version = "0.3.0"
description = "" description = ""
authors = ["Joe Kaufeld <opensource@joekaufeld.com>"] authors = ["Joe Kaufeld <opensource@joekaufeld.com>"]
@ -8,6 +8,10 @@ authors = ["Joe Kaufeld <opensource@joekaufeld.com>"]
python = "^3.10" python = "^3.10"
shiv = "^1.0.1" shiv = "^1.0.1"
httpx = "^0.23.0" httpx = "^0.23.0"
click = "^8.1.3"
rich = "^12.5.1"
markdownify = "^0.11.6"
praw = "^7.7.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
poetry = "^1.1.14" poetry = "^1.1.14"

30
src/art.py Normal file
View file

@ -0,0 +1,30 @@
_BANNER1 = r"""
. o8o oooo o8o . o8o
.o8 `"' `888 `"' .o8 `"'
oooo oooo .o888oo oooo 888 oooo .o888oo oooo .ooooo. .oooo.o
`888 `888 888 `888 888 `888 888 `888 d88' `88b d88( "8
888 888 888 888 888 888 888 888 888ooo888 `"Y88b.
888 888 888 . 888 888 888 888 . 888 888 .o o. )88b
`V88V"V8P' "888" o888o o888o o888o "888" o888o `Y8bod8P' 8""888P'
"""
_BANNER2 = r"""
__ .__.__ .__ __ .__
__ ___/ |_|__| | |__|/ |_|__| ____ ______
| | \ __\ | | | \ __\ |/ __ \ / ___/
| | /| | | | |_| || | | \ ___/ \___ \
|____/ |__| |__|____/__||__| |__|\___ >____ >
\/ \/
"""
_BANNER3 = r"""
__ __ _______ ___ ___ ___ _______ ___ _______ _______
| | | || || | | | | | | || | | || |
| | | ||_ _|| | | | | | |_ _|| | | ___|| _____|
| |_| | | | | | | | | | | | | | | |___ | |_____
| | | | | | | |___ | | | | | | | ___||_____ |
| | | | | | | || | | | | | | |___ _____| |
|_______| |___| |___| |_______||___| |___| |___| |_______||_______|
"""
BANNERS: list[str] = [_BANNER1, _BANNER2, _BANNER3]

View file

@ -1,43 +1,248 @@
import code import code
import argparse import random
import importlib import string
import sys import sys
import uuid
import click
import httpx
from praw import Reddit
from rich import pretty
from rich.status import Status
from rich.traceback import install
from shiv.bootstrap import current_zipfile
import src import src
from src.helpers import flip_char, load_config, write_config
BANNER = """ from src.joplin import process_joplin_posts, get_folders, BASE_URL
. o8o oooo o8o . o8o from src.art import BANNERS
.o8 `"' `888 `"' .o8 `"'
oooo oooo .o888oo oooo 888 oooo .o888oo oooo .ooooo. .oooo.o
`888 `888 888 `888 888 `888 888 `888 d88' `88b d88( "8
888 888 888 888 888 888 888 888 888ooo888 `"Y88b.
888 888 888 . 888 888 888 888 . 888 888 .o o. )88b
`V88V"V8P' "888" o888o o888o o888o "888" o888o `Y8bod8P' 8""888P'
"""
def main(): @click.group(
parser = argparse.ArgumentParser( context_settings=dict(help_option_names=["-h", "--help", "--halp"]),
description="Run a specific script by name. If no name is provided, start a REPL." invoke_without_command=True,
) )
parser.add_argument( @click.pass_context
"user_input", @click.version_option(version=src.__version__, prog_name="utils")
type=str, @click.option(
nargs="*", "--update",
help="The name of the script that you want to run plus any arguments for that script.", is_flag=True,
help="Check Gitea for a new version and auto-update.",
) )
parser.add_argument( def main(ctx, update):
"--version", action="store_true", help="Print out the version string." """Launch a utility or drop into a command line REPL if no command is given."""
) if update:
update_from_gitea()
args = parser.parse_args()
user_input = args.user_input
if args.version is True:
print(src.__version__)
sys.exit() sys.exit()
if len(user_input) == 0: elif ctx.invoked_subcommand is None:
code.interact(banner=BANNER, local=locals()) banner = random.choice(BANNERS)
pretty.install() # type: ignore
install() # traceback handler
code.interact(local=globals(), banner=banner)
sys.exit()
@main.command()
def uuid4():
"""Generate a random UUID4."""
click.echo(uuid.uuid4())
@main.command()
def joplin():
"""Search Joplin for notes titled 'convert' and process them."""
process_joplin_posts()
@main.command()
def objectid():
"""Generate a random ObjectID."""
new_id = ""
for _ in range(24):
new_id += random.choice(string.ascii_lowercase[:6] + string.digits)
click.echo(new_id)
@main.command()
@click.argument("dice")
def roll(dice: str):
"""Roll some dice. Format: utils roll 3d8"""
if "d" not in dice:
click.echo("Missing part of the call. Example: 1d10")
return
if len(dice.split("d")) != 2:
click.echo("Error parsing dice. Example: 2d6")
return
num, sides = dice.split("d")
try:
num = int(num)
sides = int(sides)
except ValueError:
click.echo("Need numbers for the dice. Example: 30d4")
return
if num < 1 or sides < 1:
click.echo("Dude. Example: 2d8")
return
values: list[int] = []
for die in range(num):
values.append(random.randint(1, sides))
if num == 1:
click.echo(f"You rolled a {values[0]}.")
else: else:
command_name = user_input.pop(0) click.echo(f"You rolled: {'+'.join([str(item) for item in values])}")
module = importlib.import_module(f"src.commands.{command_name}") click.echo(f"Total: {sum(values)}")
sys.exit(module.main(user_input))
@main.command()
@click.argument("words", nargs=-1)
def beautify(words: list[str]):
"""
MAkE YoUr mEsSaGe bEaUtIfUl!!!1!!
WORDS is either a single string surrounded by double quotes or multiple bare words,
e.g. `utils beautify "one two three"` or `utils beautify one two three`.
"""
message = " ".join(words)
new_beautiful_string = []
for num, letter in enumerate(message):
if num % 2:
letter = flip_char(letter)
new_beautiful_string.append(letter)
click.echo("".join(new_beautiful_string))
@main.command()
def get_saved_from_reddit() -> None:
"""Get saved posts from reddit."""
def _process(item):
fullname = item.fullname
if fullname.startswith("t3"):
# we got a post
title = f"{item.subreddit.display_name} - {item.title}"
body = item.selftext if item.selftext else item.url
elif fullname.startswith("t1"):
# comment time
try:
author_name = item.author.name
except AttributeError:
author_name = "[deleted]"
title = (
f"{item.submission.subreddit.display_name} - {item.submission.title}"
)
body = f"Comment from {author_name}:\n\n{item.body}"
else:
click.echo(f"Not sure how to process https://reddit.com{item.permalink}")
return
if item.over_18:
title = "🔴 " + title
body = "https://reddit.com" + item.permalink + "\n\n" + body
joplin = BASE_URL + cfg["JOPLIN_PORT"]
notes_url = joplin + f"/notes/?token={cfg.get('JOPLIN_TOKEN')}"
click.echo(f"Processing {title}...")
httpx.post(
notes_url,
json={
"title": title,
"body": body,
"parent_id": cfg.get("joplin_saved_posts_folder_id"),
},
)
item.unsave()
cfg = load_config()
# because 2fa is enabled, we have to get the code first
twofa_code = click.prompt("What's the current 2fa code?", type=str)
if not cfg.get("REDDIT_CLIENT_ID"):
cfg["REDDIT_CLIENT_ID"] = ""
if not cfg.get("REDDIT_CLIENT_SECRET"):
cfg["REDDIT_CLIENT_SECRET"] = ""
if not cfg.get("REDDIT_PASSWORD"):
cfg["REDDIT_PASSWORD"] = ""
if not cfg.get("REDDIT_USERNAME"):
cfg["REDDIT_USERNAME"] = ""
if not cfg.get("joplin_saved_posts_folder_id"):
cfg["joplin_saved_posts_folder_id"] = ""
write_config(cfg)
username = cfg.get("REDDIT_USERNAME", "")
r = Reddit(
client_id=cfg.get("REDDIT_CLIENT_ID", ""),
client_secret=cfg.get("REDDIT_CLIENT_SECRET", ""),
username=username,
password=f"{cfg.get('REDDIT_PASSWORD', '')}:{twofa_code}",
user_agent=f"getter of saved posts, u/{username}",
)
try:
r.user.me()
except Exception as e:
click.echo(f"Cannot connect to reddit: {e}")
return
if not cfg.get("joplin_saved_posts_folder_id"):
folders = get_folders()
click.echo("Pick the folder that I should write your saved posts to:")
for count, option in enumerate(folders["items"]):
click.echo(f"{count} - {option['title']}")
folder_position = click.prompt("Number of folder?", type=int)
folder_name = folders["items"][folder_position]["title"]
folder_id = folders["items"][folder_position]["id"]
click.echo(f"Got it, will write to {folder_name}, ID {folder_id}.")
cfg["joplin_saved_posts_folder_id"] = folder_id
write_config(cfg)
for _ in range(10):
click.echo("Getting new posts...")
for item in r.user.me().saved(limit=None):
_process(item)
def update_from_gitea():
"""Get the newest release from Gitea and install it."""
status = Status("Checking for new release...")
status.start()
response = httpx.get(
"https://git.joekaufeld.com/api/v1/repos/jkaufeld/utils/releases/latest"
)
if response.status_code != 200:
status.stop()
click.echo(
f"Something went wrong when talking to Gitea; got a"
f" {response.status_code} with the following content:\n"
f"{response.content}"
)
return
status.update("Checking for new release...")
release_data = response.json()
if release_data["tag_name"] == src.__version__:
status.stop()
click.echo("Server version is the same as current version; nothing to update.")
return
status.update("Updating...")
url = release_data["assets"][0]["browser_download_url"]
with current_zipfile() as archive:
with open(archive.filename, "wb") as f, httpx.stream(
"GET", url, follow_redirects=True
) as r:
for line in r.iter_bytes():
f.write(line)
status.stop()
click.echo(f"Updated to {release_data['tag_name']}! 🎉")
if __name__ == "__main__":
main()

View file

@ -1,22 +0,0 @@
import string
def flip_char(char: str):
if char in string.ascii_lowercase:
return string.ascii_uppercase[string.ascii_lowercase.find(char)]
else:
return string.ascii_lowercase[string.ascii_uppercase.find(char)]
def main(args: list[str]):
message = " ".join(args)
new_beautiful_string = []
for num, letter in enumerate(message):
if letter in string.ascii_letters:
if num % 2:
new_beautiful_string.append(flip_char(letter))
continue
new_beautiful_string.append(letter)
print("".join(new_beautiful_string))

View file

@ -1,26 +0,0 @@
import httpx
import src
def main(args):
release_data = httpx.get(
"https://api.github.com/repos/itsthejoker/utils/releases/latest"
)
if release_data.status_code != 200:
print(
f"Something went wrong when talking to github; got a"
f" {release_data.status_code} with the following content:\n"
f"{release_data.content}"
)
return
json_data = release_data.json()
if json_data["name"] == src.__version__:
print("Server version is the same as current version; nothing to update.")
return
url = json_data["assets"][0]["browser_download_url"]
with open("utils", "wb") as f, httpx.stream("GET", url, follow_redirects=True) as r:
for line in r.iter_bytes():
f.write(line)
print(f"Updated to {json_data['name']}! 🎉")

View file

@ -1,6 +0,0 @@
"""Generate and print a random UUID4."""
import uuid
def main(args: list[str]):
print(uuid.uuid4())

46
src/helpers.py Normal file
View file

@ -0,0 +1,46 @@
from pathlib import Path
import json
import os
import string
import click
def flip_char(char: str):
if char.lower() not in string.ascii_letters:
return char
if char in string.ascii_lowercase:
return string.ascii_uppercase[string.ascii_lowercase.find(char)]
else:
return string.ascii_lowercase[string.ascii_uppercase.find(char)]
base_folder = Path(Path.home() / ".config")
config_file = base_folder / "utils_config.json"
def load_config() -> dict:
"""Try to load the computer-specific utils JSON file."""
if not base_folder.exists():
os.mkdir(base_folder)
if not config_file.exists():
with open(config_file, "w") as f:
f.write(json.dumps({}, indent=2))
return {}
try:
with open(config_file, "r") as f:
return json.load(f)
except json.JSONDecodeError:
click.echo(
f"Cannot load config -- potentially corrupt file. Check {config_file:s}"
)
return {}
def write_config(config_obj) -> None:
load_config() # make sure everything exists
with open(config_file, "w") as f:
f.write(json.dumps(config_obj, indent=2))

124
src/joplin.py Normal file
View file

@ -0,0 +1,124 @@
import click
import httpx
import time
import bs4
from markdownify import markdownify as md
from src.helpers import load_config, write_config
BASE_URL = "http://localhost:"
def doublecheck_port_number(port: int):
try:
if (
httpx.get(f"http://localhost:{port}/ping").content.decode()
== "JoplinClipperServer"
):
return True
except Exception:
return False
def auth_with_joplin():
config = load_config()
if not config.get("JOPLIN_PORT"):
while True:
config["JOPLIN_PORT"] = click.prompt(
"What's the port number of the Joplin Web Clipper service?",
type=int,
default=41184,
)
config["JOPLIN_PORT"] = str(config["JOPLIN_PORT"])
if doublecheck_port_number(config["JOPLIN_PORT"]):
break
else:
click.echo("Something's not right there. Is the service enabled?")
# this triggers the dialog in Joplin to accept the auth connection.
auth_token = (
httpx.post(BASE_URL + config["JOPLIN_PORT"] + "/auth").json().get("auth_token")
)
click.echo("Check Joplin to allow this connection.")
while True:
check_resp = httpx.get(
BASE_URL + config["JOPLIN_PORT"] + f"/auth/check?auth_token={auth_token}"
).json()
if check_resp.get("status") == "waiting":
time.sleep(0.5)
else:
config["JOPLIN_TOKEN"] = check_resp.get("token")
break
write_config(config)
def get_folders():
c = load_config()
first_call_success = False
try:
resp = httpx.get(
BASE_URL
+ c.get("JOPLIN_PORT", "")
+ f"/folders?token={c.get('JOPLIN_TOKEN')}"
)
if resp.status_code == 403:
click.echo("got 403")
auth_with_joplin()
else:
resp = resp.json()
first_call_success = True
except httpx._exceptions.ConnectError:
auth_with_joplin()
if not first_call_success:
c = load_config()
resp = httpx.get(
BASE_URL
+ c.get("JOPLIN_PORT", "")
+ f"/folders?token={c.get('JOPLIN_TOKEN')}"
).json()
return resp
def process_joplin_posts():
# this will handle the initial auth flow if we aren't already authed
get_folders()
c = load_config()
joplin = BASE_URL + c["JOPLIN_PORT"]
resp = httpx.get(
joplin
+ f"/search?query=convert&fields=id,parent_id&token={c.get('JOPLIN_TOKEN')}"
)
resp = resp.json()
if not resp.get("items"):
click.echo("No notes found with title 'convert'.")
return
else:
items = resp.get("items")
for blob in items:
url = (
httpx.get(
joplin
+ f"/notes/{blob['id']}?fields=body&token={c.get('JOPLIN_TOKEN')}"
)
.json()["body"]
.strip()
)
click.echo(f"Processing {url}...")
site = httpx.get(url, follow_redirects=True)
soup = bs4.BeautifulSoup(site.content, features="html5lib")
# clean up that schizz
title = soup.title.text
[t.extract() for t in soup(["script", "head", "style"])]
body = md(str(soup))
httpx.put(
joplin + f"/notes/{blob['id']}?token={c.get('JOPLIN_TOKEN')}",
json={"title": title, "body": body},
)
click.echo(resp)

View file

@ -1,6 +1,5 @@
from __future__ import print_function from pathlib import Path
from poetry.core.utils._compat import Path
from poetry.core.factory import Factory from poetry.core.factory import Factory
from poetry.core.masonry.builders.sdist import SdistBuilder from poetry.core.masonry.builders.sdist import SdistBuilder