mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-01-10 06:48:04 -05:00
Added metadata lookup to youtube helper
This commit is contained in:
17
README.md
17
README.md
@@ -211,7 +211,7 @@ yt() {
|
||||
}
|
||||
```
|
||||
|
||||
This also creates a `yt` alias that allows you to use `yt https://www.youtube.com/watch?v=4b0iet22VIk` to get your transcripts.
|
||||
This also creates a `yt` alias that allows you to use `yt https://www.youtube.com/watch?v=4b0iet22VIk` to get transcripts, comments, and metadata.
|
||||
|
||||
#### Save your files in markdown using aliases
|
||||
|
||||
@@ -323,6 +323,7 @@ Application Options:
|
||||
-y, --youtube= YouTube video "URL" to grab transcript, comments from it and send to chat
|
||||
--transcript Grab transcript from YouTube video and send to chat (it used per default).
|
||||
--comments Grab comments from YouTube video and send to chat
|
||||
--metadata Grab metadata from YouTube video and send to chat
|
||||
-g, --language= Specify the Language Code for the chat, e.g. -g=en -g=zh
|
||||
-u, --scrape_url= Scrape website URL to markdown using Jina AI
|
||||
-q, --scrape_question= Search question using Jina AI
|
||||
@@ -474,16 +475,18 @@ alias pbpaste='xclip -selection clipboard -o'
|
||||
## Web Interface
|
||||
|
||||
Fabric now includes a built-in web interface that provides a GUI alternative to the command-line interface and an out-of-the-box website for those who want to get started with web development or blogging.
|
||||
You can use this app as a GUI interface for Fabric, a ready to go blog-site, or a website template for your own projects.
|
||||
You can use this app as a GUI interface for Fabric, a ready to go blog-site, or a website template for your own projects.
|
||||
|
||||
The `web/src/lib/content` directory includes starter `.obsidian/` and `templates/` directories, allowing you to open up the `web/src/lib/content/` directory as an [Obsidian.md](https://obsidian.md) vault. You can place your posts in the posts directory when you're ready to publish.
|
||||
|
||||
The `web/src/lib/content` directory includes starter `.obsidian/` and `templates/` directories, allowing you to open up the `web/src/lib/content/` directory as an [Obsidian.md](https://obsidian.md) vault. You can place your posts in the posts directory when you're ready to publish.
|
||||
### Installing
|
||||
|
||||
The GUI can be installed by navigating to the `web` directory and using `npm install`, `pnpm install`, or your favorite package manager. Then simply run the development server to start the app.
|
||||
The GUI can be installed by navigating to the `web` directory and using `npm install`, `pnpm install`, or your favorite package manager. Then simply run the development server to start the app.
|
||||
|
||||
_You will need to run fabric in a separate terminal with the `fabric --serve` command._
|
||||
_You will need to run fabric in a separate terminal with the `fabric --serve` command._
|
||||
|
||||
**From the fabric project `web/` directory:**
|
||||
|
||||
```shell
|
||||
npm run dev
|
||||
|
||||
@@ -491,7 +494,7 @@ npm run dev
|
||||
|
||||
pnpm run dev
|
||||
|
||||
## or your equivalent
|
||||
## or your equivalent
|
||||
```
|
||||
|
||||
### Streamlit UI
|
||||
@@ -507,10 +510,12 @@ streamlit run streamlit.py
|
||||
```
|
||||
|
||||
The Streamlit UI provides a user-friendly interface for:
|
||||
|
||||
- Running and chaining patterns
|
||||
- Managing pattern outputs
|
||||
- Creating and editing patterns
|
||||
- Analyzing pattern results
|
||||
|
||||
## Meta
|
||||
|
||||
> [!NOTE]
|
||||
|
||||
13
cli/cli.go
13
cli/cli.go
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -286,7 +287,7 @@ func Cli(version string) (err error) {
|
||||
func processYoutubeVideo(
|
||||
flags *Flags, registry *core.PluginRegistry, videoId string) (message string, err error) {
|
||||
|
||||
if !flags.YouTubeComments || flags.YouTubeTranscript {
|
||||
if (!flags.YouTubeComments && !flags.YouTubeMetadata) || flags.YouTubeTranscript {
|
||||
var transcript string
|
||||
var language = "en"
|
||||
if flags.Language != "" || registry.Language.DefaultLanguage.Value != "" {
|
||||
@@ -312,6 +313,16 @@ func processYoutubeVideo(
|
||||
|
||||
message = AppendMessage(message, commentsString)
|
||||
}
|
||||
|
||||
if flags.YouTubeMetadata {
|
||||
var metadata *youtube.VideoMetadata
|
||||
if metadata, err = registry.YouTube.GrabMetadata(videoId); err != nil {
|
||||
return
|
||||
}
|
||||
metadataJson, _ := json.MarshalIndent(metadata, "", " ")
|
||||
message = AppendMessage(message, string(metadataJson))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -47,8 +47,9 @@ type Flags struct {
|
||||
ChangeDefaultModel bool `short:"d" long:"changeDefaultModel" description:"Change default model"`
|
||||
YouTube string `short:"y" long:"youtube" description:"YouTube video or play list \"URL\" to grab transcript, comments from it and send to chat or print it put to the console and store it in the output file"`
|
||||
YouTubePlaylist bool `long:"playlist" description:"Prefer playlist over video if both ids are present in the URL"`
|
||||
YouTubeTranscript bool `long:"transcript" description:"Grab transcript from YouTube video and send to chat (it used per default)."`
|
||||
YouTubeTranscript bool `long:"transcript" description:"Grab transcript from YouTube video and send to chat (it is used per default)."`
|
||||
YouTubeComments bool `long:"comments" description:"Grab comments from YouTube video and send to chat"`
|
||||
YouTubeMetadata bool `long:"metadata" description:"Output video metadata"`
|
||||
Language string `short:"g" long:"language" description:"Specify the Language Code for the chat, e.g. -g=en -g=zh" default:""`
|
||||
ScrapeURL string `short:"u" long:"scrape_url" description:"Scrape website URL to markdown using Jina AI"`
|
||||
ScrapeQuestion string `short:"q" long:"scrape_question" description:"Search question using Jina AI"`
|
||||
|
||||
@@ -238,6 +238,13 @@ func (o *YouTube) Grab(url string, options *Options) (ret *VideoInfo, err error)
|
||||
|
||||
ret = &VideoInfo{}
|
||||
|
||||
if options.Metadata {
|
||||
if ret.Metadata, err = o.GrabMetadata(videoId); err != nil {
|
||||
err = fmt.Errorf("error getting video metadata: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if options.Duration {
|
||||
if ret.Duration, err = o.GrabDuration(videoId); err != nil {
|
||||
err = fmt.Errorf("error parsing video duration: %v", err)
|
||||
@@ -369,12 +376,55 @@ type Options struct {
|
||||
Transcript bool
|
||||
Comments bool
|
||||
Lang string
|
||||
Metadata bool
|
||||
}
|
||||
|
||||
type VideoInfo struct {
|
||||
Transcript string `json:"transcript"`
|
||||
Duration int `json:"duration"`
|
||||
Comments []string `json:"comments"`
|
||||
Transcript string `json:"transcript"`
|
||||
Duration int `json:"duration"`
|
||||
Comments []string `json:"comments"`
|
||||
Metadata *VideoMetadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type VideoMetadata struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
PublishedAt string `json:"publishedAt"`
|
||||
ChannelId string `json:"channelId"`
|
||||
ChannelTitle string `json:"channelTitle"`
|
||||
ViewCount uint64 `json:"viewCount"`
|
||||
LikeCount uint64 `json:"likeCount"`
|
||||
}
|
||||
|
||||
func (o *YouTube) GrabMetadata(videoId string) (metadata *VideoMetadata, err error) {
|
||||
if err = o.initService(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
call := o.service.Videos.List([]string{"snippet", "statistics"}).Id(videoId)
|
||||
var response *youtube.VideoListResponse
|
||||
if response, err = call.Do(); err != nil {
|
||||
return nil, fmt.Errorf("error getting video metadata: %v", err)
|
||||
}
|
||||
|
||||
if len(response.Items) == 0 {
|
||||
return nil, fmt.Errorf("no video found with ID: %s", videoId)
|
||||
}
|
||||
|
||||
video := response.Items[0]
|
||||
viewCount := video.Statistics.ViewCount
|
||||
likeCount := video.Statistics.LikeCount
|
||||
|
||||
metadata = &VideoMetadata{
|
||||
Title: video.Snippet.Title,
|
||||
Description: video.Snippet.Description,
|
||||
PublishedAt: video.Snippet.PublishedAt,
|
||||
ChannelId: video.Snippet.ChannelId,
|
||||
ChannelTitle: video.Snippet.ChannelTitle,
|
||||
ViewCount: viewCount,
|
||||
LikeCount: likeCount,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *YouTube) GrabByFlags() (ret *VideoInfo, err error) {
|
||||
@@ -383,6 +433,7 @@ func (o *YouTube) GrabByFlags() (ret *VideoInfo, err error) {
|
||||
flag.BoolVar(&options.Transcript, "transcript", false, "Output only the transcript")
|
||||
flag.BoolVar(&options.Comments, "comments", false, "Output the comments on the video")
|
||||
flag.StringVar(&options.Lang, "lang", "en", "Language for the transcript (default: English)")
|
||||
flag.BoolVar(&options.Metadata, "metadata", false, "Output video metadata")
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() == 0 {
|
||||
|
||||
Reference in New Issue
Block a user