all repos — fixyoutube-go @ f33a2e3dc414259fae3738ea558b32ec1731ba99

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) {
 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
 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
 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
 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
 67		}
 68	}
 69}
 70
 71func GetVideoDB(videoId string) (*Video, error) {
 72	db := getDb("ro")
 73	defer db.Close()
 74
 75	getVideo, err := db.Prepare(getVideoQuery)
 76	if err != nil {
 77		logger.Error("Could not get video:", err)
 78		return nil, err
 79	}
 80	defer getVideo.Close()
 81
 82	v := &Video{}
 83	err = getVideo.QueryRow(videoId).Scan(&v.VideoId, &v.Title, &v.Description, &v.Uploader, &v.Duration, &v.Timestamp, &v.Expire)
 84	if err != nil {
 85		logger.Debug("Could not get video:", err)
 86		return nil, err
 87	}
 88
 89	if v.Timestamp.After(v.Expire) {
 90		logger.Info("Video has expired.")
 91		return nil, fmt.Errorf("expired")
 92	}
 93
 94	getFormat, err := db.Prepare(getFormatQuery)
 95	if err != nil {
 96		logger.Error("Could not get format:", err)
 97		return nil, err
 98	}
 99	defer getFormat.Close()
100
101	response, err := getFormat.Query(videoId)
102	if err != nil {
103		logger.Error("Could not get formats:", err)
104		return nil, err
105	}
106	defer response.Close()
107
108	for response.Next() {
109		f := Format{}
110		err := response.Scan(&f.VideoId, &f.Name, &f.Height, &f.Width, &f.Url)
111		if err != nil {
112			logger.Error("Could not get formats:", err)
113			return nil, err
114		}
115		v.Formats = append(v.Formats, f)
116	}
117
118	return v, nil
119}
120
121func ClearDB() {
122	db := getDb("rw")
123	defer db.Close()
124
125	stmt, err := db.Prepare(clearQuery)
126	if err != nil {
127		logger.Error("Could not clear DB:", err)
128		return
129	}
130	defer stmt.Close()
131
132	_, err = stmt.Exec()
133	if err != nil {
134		logger.Error("Could not clear DB:", err)
135		return
136	}
137}