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}