154 lines
3.1 KiB
Go
154 lines
3.1 KiB
Go
package m3u8d
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"github.com/orestonce/cdb"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
)
|
|
|
|
type DbVideoInfo struct {
|
|
VideoId string
|
|
ContentHash string
|
|
FileSize int64 // 加快搜索速度
|
|
OriginReq RunDownload_Req
|
|
}
|
|
|
|
func (this *RunDownload_Req) getVideoId() (id string, err error) {
|
|
b, err := json.Marshal(this)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
tmp1 := sha256.Sum256(b)
|
|
return hex.EncodeToString(tmp1[:]), nil
|
|
}
|
|
|
|
func cacheRead(dir string, id string) (info *DbVideoInfo, err error) {
|
|
value, err := dbRead(dir, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(value) == 0 {
|
|
return nil, nil
|
|
}
|
|
var obj DbVideoInfo
|
|
err = json.Unmarshal(value, &obj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
info = &obj
|
|
return info, nil
|
|
}
|
|
|
|
func (this *DbVideoInfo) SearchVideoInDir(dir string) (latestNameFullPath string, found bool) {
|
|
fileList, err := ioutil.ReadDir(dir)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
for _, one := range fileList {
|
|
if this.FileSize != one.Size() || !one.Mode().IsRegular() {
|
|
continue
|
|
}
|
|
tmp := filepath.Join(dir, one.Name())
|
|
if this.ContentHash == getFileSha256(tmp) {
|
|
return tmp, true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func cacheWrite(dir string, id string, originReq RunDownload_Req, videoNameFullPath string, contentHash string) (err error) {
|
|
var info = &DbVideoInfo{
|
|
VideoId: id,
|
|
OriginReq: originReq,
|
|
ContentHash: contentHash,
|
|
FileSize: 0,
|
|
}
|
|
stat, err := os.Stat(videoNameFullPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
info.FileSize = stat.Size()
|
|
content, err := json.MarshalIndent(info, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return dbWrite(dir, id, content)
|
|
}
|
|
|
|
func dbRead(dir string, key string) (content []byte, err error) {
|
|
db, err := cdb.OpenFile(filepath.Join(dir, "m3u8d_cache.cdb"))
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
defer db.Close()
|
|
content, err = db.GetValue([]byte(key))
|
|
if err != nil {
|
|
if err == cdb.ErrNoData {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return content, nil
|
|
}
|
|
|
|
func dbWrite(dir string, key string, value []byte) (err error) {
|
|
cdbFileName := filepath.Join(dir, "m3u8d_cache.cdb")
|
|
|
|
reader, err := cdb.OpenFile(cdbFileName)
|
|
if err != nil && !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
tmpCdbFileName := cdbFileName + "." + strconv.Itoa(os.Getpid()) + ".tmp"
|
|
writer, err := cdb.NewFileWriter(tmpCdbFileName)
|
|
if err != nil {
|
|
if reader != nil {
|
|
reader.Close()
|
|
}
|
|
return err
|
|
}
|
|
|
|
if reader != nil {
|
|
for it := reader.BeginIterator(); it != nil; {
|
|
tmpKey, tmpValue, err := it.ReadNextKeyValue()
|
|
if err != nil {
|
|
if err == cdb.ErrNoData {
|
|
break
|
|
}
|
|
reader.Close()
|
|
writer.Close()
|
|
os.Remove(tmpCdbFileName)
|
|
return err
|
|
}
|
|
if string(tmpKey) == key {
|
|
continue
|
|
}
|
|
err = writer.WriteKeyValue(tmpKey, tmpValue)
|
|
if err != nil {
|
|
reader.Close()
|
|
writer.Close()
|
|
os.Remove(tmpCdbFileName)
|
|
return err
|
|
}
|
|
}
|
|
reader.Close()
|
|
}
|
|
err = writer.WriteKeyValue([]byte(key), value)
|
|
if err != nil {
|
|
writer.Close()
|
|
return err
|
|
}
|
|
err = writer.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.Rename(tmpCdbFileName, cdbFileName)
|
|
}
|