all repos — fixyoutube-go @ 50c43a7eba19e6652a1c88bc3b129281f1ede12a

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

invidious/cache.go (view raw)

  1package invidious
  2
  3import (
  4	"database/sql"
  5	"fmt"
  6
  7	_ "github.com/mattn/go-sqlite3"
  8)
  9
 10const dbConnectionString = "file:cache.sqlite?cache=shared&mode="
 11
 12func getDb(mode string) *sql.DB {
 13	db, err := sql.Open("sqlite3", dbConnectionString+mode)
 14	if err != nil {
 15		logger.Error("Could not open DB:", err)
 16		return nil
 17	}
 18	db.SetMaxOpenConns(1)
 19	return db
 20}
 21
 22func InitDB() {
 23	db := getDb("rwc")
 24	defer db.Close()
 25
 26	_, err := db.Exec(createQueryVideos)
 27	if err != nil {
 28		logger.Errorf("%q: %s\n", err, createQueryVideos)
 29		return
 30	}
 31	_, err = db.Exec(createQueryFormats)
 32	if err != nil {
 33		logger.Errorf("%q: %s\n", err, createQueryFormats)
 34		return
 35	}
 36}
 37
 38func CacheVideoDB(v Video) error {
 39	db := getDb("rw")
 40	defer db.Close()
 41
 42	cacheVideo, err := db.Prepare(cacheVideoQuery)
 43	if err != nil {
 44		logger.Error("Could not cache video: ", err)
 45		return err
 46	}
 47	defer cacheVideo.Close()
 48
 49	_, err = cacheVideo.Exec(v.VideoId, v.Title, v.Description, v.Uploader, v.Duration, v.Expire)
 50	if err != nil {
 51		logger.Error("Could not cache video: ", err)
 52		return err
 53	}
 54
 55	for _, f := range v.Formats {
 56		cacheFormat, err := db.Prepare(cacheFormatQuery)
 57		if err != nil {
 58			logger.Error("Could not cache format: ", err)
 59			return err
 60		}
 61		defer cacheVideo.Close()
 62
 63		_, err = cacheFormat.Exec(v.VideoId, f.Name, f.Height, f.Width, f.Url)
 64		if err != nil {
 65			logger.Error("Could not cache format: ", err)
 66			return err
 67		}
 68	}
 69	return nil
 70}
 71
 72func GetVideoDB(videoId string) (*Video, error) {
 73	db := getDb("ro")
 74	defer db.Close()
 75
 76	getVideo, err := db.Prepare(getVideoQuery)
 77	if err != nil {
 78		logger.Error("Could not get video: ", err)
 79		return nil, err
 80	}
 81	defer getVideo.Close()
 82
 83	v := &Video{}
 84	err = getVideo.QueryRow(videoId).Scan(&v.VideoId, &v.Title, &v.Description, &v.Uploader, &v.Duration, &v.Timestamp, &v.Expire)
 85	if err != nil {
 86		logger.Debug("Could not get video:", err)
 87		return nil, err
 88	}
 89
 90	if v.Timestamp.After(v.Expire) {
 91		logger.Info("Video has expired.")
 92		return nil, fmt.Errorf("expired")
 93	}
 94
 95	getFormat, err := db.Prepare(getFormatQuery)
 96	if err != nil {
 97		logger.Error("Could not get format: ", err)
 98		return nil, err
 99	}
100	defer getFormat.Close()
101
102	response, err := getFormat.Query(videoId)
103	if err != nil {
104		logger.Error("Could not get formats: ", err)
105		return nil, err
106	}
107	defer response.Close()
108
109	for response.Next() {
110		f := Format{}
111		err := response.Scan(&f.VideoId, &f.Name, &f.Height, &f.Width, &f.Url)
112		if err != nil {
113			logger.Error("Could not get formats: ", err)
114			return nil, err
115		}
116		v.Formats = append(v.Formats, f)
117	}
118
119	return v, nil
120}
121
122func ClearDB() {
123	db := getDb("rw")
124	defer db.Close()
125
126	stmt, err := db.Prepare(clearQuery)
127	if err != nil {
128		logger.Error("Could not clear DB:", err)
129		return
130	}
131	defer stmt.Close()
132
133	_, err = stmt.Exec()
134	if err != nil {
135		logger.Error("Could not clear DB:", err)
136		return
137	}
138}