Merge pull request #148 from invisiblethreat/output-saver
helper utility for saving a Markdown file
This commit is contained in:
commit
9a78e94ced
@ -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
Executable file
121
helpers/save.py
Executable file
@ -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()
|
@ -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()
|
||||
|
@ -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…
x
Reference in New Issue
Block a user