all repos — fixyoutube-go @ 1ed34f89fd58b854daee23c3e8188e071ff5a852

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	"log"
  7
  8	_ "github.com/mattn/go-sqlite3"
  9)
 10
 11const dbConnectionString = "file:cache.sqlite?cache=shared&mode="
 12
 13func getDb(mode string) *sql.DB {
 14	db, err := sql.Open("sqlite3", dbConnectionString+mode)
 15	if err != nil {
 16		log.Println("Could not open DB:", err)
 17		return nil
 18	}
 19	db.SetMaxOpenConns(1)
 20	return db
 21}
 22
 23func InitDB() {
 24	db := getDb("rwc")
 25	defer db.Close()
 26
 27	_, err := db.Exec(createQueryVideos)
 28	if err != nil {
 29		log.Printf("%q: %s\n", err, createQueryVideos)
 30		return
 31	}
 32	_, err = db.Exec(createQueryFormats)
 33	if err != nil {
 34		log.Printf("%q: %s\n", err, createQueryFormats)
 35		return
 36	}
 37}
 38
 39func CacheVideoDB(v Video) {
 40	db := getDb("rw")
 41	defer db.Close()
 42
 43	cacheVideo, err := db.Prepare(cacheVideoQuery)
 44	if err != nil {
 45		log.Println("Could not cache video:", err)
 46		return
 47	}
 48	defer cacheVideo.Close()
 49
 50	_, err = cacheVideo.Exec(v.VideoId, v.Title, v.Description, v.Uploader, v.Duration, v.Expire)
 51	if err != nil {
 52		log.Println("Could not cache video:", err)
 53		return
 54	}
 55
 56	for _, f := range v.Formats {
 57		cacheFormat, err := db.Prepare(cacheFormatQuery)
 58		if err != nil {
 59			log.Println("Could not cache format:", err)
 60			return
 61		}
 62		defer cacheVideo.Close()
 63
 64		_, err = cacheFormat.Exec(v.VideoId, f.Name, f.Height, f.Width, f.Url)
 65		if err != nil {
 66			log.Println("Could not cache format:", err)
 67			return
 68		}
 69	}
 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		log.Println("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		log.Println("Could not get video:", err)
 87		return nil, err
 88	}
 89
 90	if v.Timestamp.After(v.Expire) {
 91		log.Println("Video has expired.")
 92		return nil, fmt.Errorf("expired")
 93	}
 94
 95	getFormat, err := db.Prepare(getFormatQuery)
 96	if err != nil {
 97		log.Println("Could not get video:", err)
 98		return nil, err
 99	}
100	defer getFormat.Close()
101
102	response, err := getFormat.Query(videoId)
103	if err != nil {
104		log.Println("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			log.Println("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		log.Println("Could not clear DB:", err)
129		return
130	}
131	defer stmt.Close()
132
133	_, err = stmt.Exec()
134	if err != nil {
135		log.Println("Could not clear DB:", err)
136		return
137	}
138}