all repos — fixyoutube-go @ a2de1ac53930095b77cb2248757e24c5624f30ff

A better way to embed YouTube videos everywhere (inspired by FixTweet).

major bug fix
Marco Andronaco andronacomarco@gmail.com
Mon, 01 Jan 2024 23:24:48 +0100
commit

a2de1ac53930095b77cb2248757e24c5624f30ff

parent

48d10f3f94a07a0491c6dbd2bab6b28316162e66

4 files changed, 27 insertions(+), 15 deletions(-)

jump to
M fixyoutube.gofixyoutube.go

@@ -78,7 +78,7 @@ }

video, err := invidiousClient.GetVideo(videoId) if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + http.Error(w, "Wrong Video ID.", http.StatusBadRequest) return }
M invidious/cache.goinvidious/cache.go

@@ -2,8 +2,8 @@ package invidious

import ( "database/sql" + "fmt" "log" - "time" _ "github.com/mattn/go-sqlite3" )

@@ -47,7 +47,7 @@ return

} defer cacheVideo.Close() - _, err = cacheVideo.Exec(v.VideoId, v.Title, v.Description, v.Uploader, v.Duration) + _, err = cacheVideo.Exec(v.VideoId, v.Title, v.Description, v.Uploader, v.Duration, v.Expire) if err != nil { log.Println("Could not cache video:", err) return

@@ -81,11 +81,15 @@ }

defer getVideo.Close() v := &Video{} - sixHoursAgo := time.Now().Add(-6 * time.Hour) - err = getVideo.QueryRow(videoId, sixHoursAgo).Scan(&v.VideoId, &v.Title, &v.Description, &v.Uploader, &v.Duration, &sql.NullString{}) + err = getVideo.QueryRow(videoId).Scan(&v.VideoId, &v.Title, &v.Description, &v.Uploader, &v.Duration, &v.Timestamp, &v.Expire) if err != nil { log.Println("Could not get video:", err) return nil, err + } + + if v.Timestamp.After(v.Expire) { + log.Println("Video has expired.") + return nil, fmt.Errorf("expired") } getFormat, err := db.Prepare(getFormatQuery)
M invidious/invidious.goinvidious/invidious.go

@@ -8,8 +8,8 @@ "log"

"net/http" "net/url" "os" + "regexp" "strconv" - "strings" "time" )

@@ -17,7 +17,7 @@ const maxSizeMB = 50

const instancesEndpoint = "https://api.invidious.io/instances.json?sort_by=api,type" const videosEndpoint = "https://%s/api/v1/videos/%s?fields=videoId,title,description,author,lengthSeconds,size,formatStreams" -var timeToLive, _ = time.ParseDuration("6h") +var expireRegex = regexp.MustCompile(`(?i)expire=(\d+)`) type Client struct { http *http.Client

@@ -42,6 +42,7 @@ Uploader string `json:"author"`

Duration int `json:"lengthSeconds"` Formats []Format `json:"formatStreams"` Timestamp time.Time + Expire time.Time FormatIndex int }

@@ -95,11 +96,13 @@

mp4Test := func(f Format) bool { return f.Container == "mp4" } res.Formats = filter(res.Formats, mp4Test) - for _, f := range res.Formats { - s := strings.Split(f.Size, "x") - f.Width = parseOrZero(s[0]) - f.Height = parseOrZero(s[1]) + expireString := expireRegex.FindStringSubmatch(res.Formats[0].Url) + expireTimestamp, err := strconv.ParseInt(expireString[1], 10, 64) + if err != nil { + fmt.Println("Error:", err) + return nil, err } + res.Expire = time.Unix(expireTimestamp, 0) return res, err }

@@ -114,12 +117,16 @@ return video, nil

} video, err = c.fetchVideo(videoId) + if err != nil { + if err.Error() == "{}" { + return nil, err + } log.Println(err) err = c.NewInstance() if err != nil { log.Fatal("Could not get a new instance: ", err) - time.Sleep(10) + time.Sleep(10 * time.Second) } return c.GetVideo(videoId) }
M invidious/queries.goinvidious/queries.go

@@ -7,7 +7,8 @@ title TEXT NOT NULL,

description TEXT NOT NULL, uploader TEXT NOT NULL, duration int NOT NULL, - timestamp_column DATETIME DEFAULT (datetime('now')) + timestamp DATETIME DEFAULT (datetime('now')), + expire DATETIME NOT NULL );` const createQueryFormats = `

@@ -21,10 +22,10 @@ PRIMARY KEY (videoId, name),

FOREIGN KEY(videoId) REFERENCES videos(videoId) );` -const getVideoQuery = "SELECT * FROM videos WHERE videoId = (?) AND timestamp_column > ?;" +const getVideoQuery = "SELECT * FROM videos WHERE videoId = (?);" const getFormatQuery = "SELECT * FROM formats WHERE videoId = (?)" -const cacheVideoQuery = "INSERT OR REPLACE INTO videos (videoId, title, description, uploader, duration) VALUES (?, ?, ?, ?, ?);" +const cacheVideoQuery = "INSERT OR REPLACE INTO videos (videoId, title, description, uploader, duration, expire) VALUES (?, ?, ?, ?, ?, ?);" const cacheFormatQuery = "INSERT OR REPLACE INTO formats (videoId, name, height, width, url) VALUES (?, ?, ?, ?, ?);" const clearQuery = "DELETE FROM videos;"