Browse Source

Merge pull request #148 from invisiblethreat/output-saver

helper utility for saving a Markdown file
pull/219/head
xssdoctor 8 months ago committed by GitHub
parent
commit
9a78e94ced
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 58
      helpers/README.md
  2. 121
      helpers/save.py
  3. 25
      helpers/yt.py
  4. 1
      pyproject.toml

58
helpers/README.md

@ -6,6 +6,20 @@ These are helper tools to work with Fabric. Examples include things like getting
`yt` is a command that uses the YouTube API to pull transcripts, get video duration, and other functions. It's primary function is to get a transcript from a video that can then be stitched (piped) into other Fabric Patterns.
```bash
usage: yt [-h] [--duration] [--transcript] [url]
vm (video meta) extracts metadata about a video, such as the transcript and the video's duration. By Daniel Miessler.
positional arguments:
url YouTube video URL
options:
-h, --help show this help message and exit
--duration Output only the duration
--transcript Output only the transcript
```
## ts (Audio transcriptions)
'ts' is a command that uses the OpenApi Whisper API to transcribe audio files. Due to the context window, this tool uses pydub to split the files into 10 minute segments. for more information on pydub, please refer https://github.com/jiaaro/pydub
@ -24,9 +38,6 @@ windows:
download instructions https://www.ffmpeg.org/download.html
```
````bash
usage: yt [-h] [--duration] [--transcript] [url]
```bash
ts -h
@ -39,4 +50,43 @@ positional arguments:
options:
-h, --help show this help message and exit
````
## save
`save` is a "tee-like" utility to pipeline saving of content, while keeping the output stream intact. Can optionally generate "frontmatter" for PKM utilities like Obsidian via the
"FABRIC_FRONTMATTER" environment variable
If you'd like to default variables, set them in `~/.config/fabric/.env`. `FABRIC_OUTPUT_PATH` needs to be set so `save` where to write. `FABRIC_FRONTMATTER_TAGS` is optional, but useful for tracking how tags have entered your PKM, if that's important to you.
### usage
```bash
usage: save [-h] [-t, TAG] [-n] [-s] [stub]
save: a "tee-like" utility to pipeline saving of content, while keeping the output stream intact. Can optionally generate "frontmatter" for PKM utilities like Obsidian via the
"FABRIC_FRONTMATTER" environment variable
positional arguments:
stub stub to describe your content. Use quotes if you have spaces. Resulting format is YYYY-MM-DD-stub.md by default
options:
-h, --help show this help message and exit
-t, TAG, --tag TAG add an additional frontmatter tag. Use this argument multiple timesfor multiple tags
-n, --nofabric don't use the fabric tags, only use tags from --tag
-s, --silent don't use STDOUT for output, only save to the file
```
### example
```bash
echo test | save --tag extra-tag stub-for-name
test
$ cat ~/obsidian/Fabric/2024-03-02-stub-for-name.md
---
generation_date: 2024-03-02 10:43
tags: fabric-extraction stub-for-name extra-tag
---
test
```

121
helpers/save.py

@ -0,0 +1,121 @@
#!/usr/bin/env python3
import argparse
import os
import sys
from datetime import datetime
from dotenv import load_dotenv
DEFAULT_CONFIG = "~/.config/fabric/.env"
PATH_KEY = "FABRIC_OUTPUT_PATH"
FM_KEY = "FABRIC_FRONTMATTER_TAGS"
DATE_FORMAT = "%Y-%m-%d"
load_dotenv(os.path.expanduser(DEFAULT_CONFIG))
def main(tag, tags, silent, fabric):
out = os.getenv(PATH_KEY)
if out is None:
print(f"'{PATH_KEY}' not set in {DEFAULT_CONFIG} or in your environment.")
sys.exit(1)
out = os.path.expanduser(out)
if not os.path.isdir(out):
print(f"'{out}' does not exist. Create it and try again.")
sys.exit(1)
if not out.endswith("/"):
out += "/"
if len(sys.argv) < 2:
print(f"'{sys.argv[0]}' takes a single argument to tag your summary")
sys.exit(1)
yyyymmdd = datetime.now().strftime(DATE_FORMAT)
target = f"{out}{yyyymmdd}-{tag}.md"
# don't clobber existing files- add an incremented number to the end instead
would_clobber = True
inc = 0
while would_clobber:
if inc > 0:
target = f"{out}{yyyymmdd}-{tag}-{inc}.md"
if os.path.exists(target):
inc += 1
else:
would_clobber = False
# YAML frontmatter stubs for things like Obsidian
# Prevent a NoneType ending up in the tags
frontmatter_tags = ""
if fabric:
frontmatter_tags = os.getenv(FM_KEY)
with open(target, "w") as fp:
if frontmatter_tags or len(tags) != 0:
fp.write("---\n")
now = datetime.now().strftime(f"{DATE_FORMAT} %H:%M")
fp.write(f"generation_date: {now}\n")
fp.write(f"tags: {frontmatter_tags} {tag} {' '.join(tags)}\n")
fp.write("---\n")
# function like 'tee' and split the output to a file and STDOUT
for line in sys.stdin:
if not silent:
print(line, end="")
fp.write(line)
def cli():
parser = argparse.ArgumentParser(
description=(
'save: a "tee-like" utility to pipeline saving of content, '
"while keeping the output stream intact. Can optionally generate "
'"frontmatter" for PKM utilities like Obsidian via the '
'"FABRIC_FRONTMATTER" environment variable'
)
)
parser.add_argument(
"stub",
nargs="?",
help=(
"stub to describe your content. Use quotes if you have spaces. "
"Resulting format is YYYY-MM-DD-stub.md by default"
),
)
parser.add_argument(
"-t,",
"--tag",
required=False,
action="append",
default=[],
help=(
"add an additional frontmatter tag. Use this argument multiple times"
"for multiple tags"
),
)
parser.add_argument(
"-n",
"--nofabric",
required=False,
action="store_false",
help="don't use the fabric tags, only use tags from --tag",
)
parser.add_argument(
"-s",
"--silent",
required=False,
action="store_true",
help="don't use STDOUT for output, only save to the file",
)
args = parser.parse_args()
if args.stub:
main(args.stub, args.tag, args.silent, args.nofabric)
else:
parser.print_help()
if __name__ == "__main__":
cli()

25
helpers/yt.py

@ -52,7 +52,7 @@ def main_function(url, options):
transcript_text = " ".join([item["text"] for item in transcript_list])
transcript_text = transcript_text.replace("\n", " ")
except Exception as e:
transcript_text = "Transcript not available."
transcript_text = f"Transcript not available. ({e})"
# Output based on options
if options.duration:
@ -65,13 +65,20 @@ def main_function(url, options):
# Print JSON object
print(json.dumps(output))
except HttpError as e:
print(
"Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid."
)
print(f"Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid: {e}")
def main():
parser = argparse.ArgumentParser(
description='yt (video meta) extracts metadata about a video, such as the transcript and the video\'s duration. By Daniel Miessler.')
parser.add_argument('url', nargs='?', help='YouTube video URL')
parser.add_argument('--duration', action='store_true',
help='Output only the duration')
parser.add_argument('--transcript', action='store_true',
help='Output only the transcript')
description="vm (video meta) extracts metadata about a video, such as the transcript and the video's duration. By Daniel Miessler."
)
parser.add_argument("url", nargs="?", help="YouTube video URL")
@ -81,13 +88,3 @@ def main():
parser.add_argument(
"--transcript", action="store_true", help="Output only the transcript"
)
args = parser.parse_args()
if args.url:
main_function(args.url, args)
else:
parser.print_help()
if __name__ == "__main__":
main()

1
pyproject.toml

@ -69,3 +69,4 @@ fabric-api = 'installer:run_api_server'
fabric-webui = 'installer:run_webui_server'
ts = 'helpers.ts:main'
yt = 'helpers.yt:main'
save = 'helpers.save:cli'

Loading…
Cancel
Save