mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
192 lines
4.4 KiB
Go
192 lines
4.4 KiB
Go
package settings
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
|
|
"server/log"
|
|
"server/web/api/utils"
|
|
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
var dbTorrentsName = []byte("Torrents")
|
|
|
|
type torrentOldDB struct {
|
|
Name string
|
|
Magnet string
|
|
InfoBytes []byte
|
|
Hash string
|
|
Size int64
|
|
Timestamp int64
|
|
}
|
|
|
|
// Migrate from torrserver.db to config.db
|
|
func Migrate1() {
|
|
if _, err := os.Lstat(filepath.Join(Path, "torrserver.db")); os.IsNotExist(err) {
|
|
return
|
|
}
|
|
|
|
db, err := bolt.Open(filepath.Join(Path, "torrserver.db"), 0o666, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
torrs := make([]*torrentOldDB, 0)
|
|
err = db.View(func(tx *bolt.Tx) error {
|
|
tdb := tx.Bucket(dbTorrentsName)
|
|
if tdb == nil {
|
|
return nil
|
|
}
|
|
c := tdb.Cursor()
|
|
for h, _ := c.First(); h != nil; h, _ = c.Next() {
|
|
hdb := tdb.Bucket(h)
|
|
if hdb != nil {
|
|
torr := new(torrentOldDB)
|
|
torr.Hash = string(h)
|
|
tmp := hdb.Get([]byte("Name"))
|
|
if tmp == nil {
|
|
return fmt.Errorf("error load torrent")
|
|
}
|
|
torr.Name = string(tmp)
|
|
|
|
tmp = hdb.Get([]byte("Link"))
|
|
if tmp == nil {
|
|
return fmt.Errorf("error load torrent")
|
|
}
|
|
torr.Magnet = string(tmp)
|
|
|
|
tmp = hdb.Get([]byte("Size"))
|
|
if tmp == nil {
|
|
return fmt.Errorf("error load torrent")
|
|
}
|
|
torr.Size = b2i(tmp)
|
|
|
|
tmp = hdb.Get([]byte("Timestamp"))
|
|
if tmp == nil {
|
|
return fmt.Errorf("error load torrent")
|
|
}
|
|
torr.Timestamp = b2i(tmp)
|
|
|
|
torrs = append(torrs, torr)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
db.Close()
|
|
if err == nil && len(torrs) > 0 {
|
|
for _, torr := range torrs {
|
|
spec, err := utils.ParseLink(torr.Magnet)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
title := torr.Name
|
|
if len(spec.DisplayName) > len(title) {
|
|
title = spec.DisplayName
|
|
}
|
|
log.TLogln("Migrate torrent", torr.Name, torr.Hash, torr.Size)
|
|
AddTorrent(&TorrentDB{
|
|
TorrentSpec: spec,
|
|
Title: title,
|
|
Timestamp: torr.Timestamp,
|
|
Size: torr.Size,
|
|
})
|
|
}
|
|
}
|
|
os.Remove(filepath.Join(Path, "torrserver.db"))
|
|
}
|
|
|
|
func b2i(v []byte) int64 {
|
|
return int64(binary.BigEndian.Uint64(v))
|
|
}
|
|
|
|
/*
|
|
=== Migrate 2 ===
|
|
|
|
Migrate 'Settings' and 'Viewed' buckets from BBolt ('config.db')
|
|
to separate JSON files ('settings.json' and 'viewed.json')
|
|
|
|
'Torrents' data continues to remain in the BBolt database ('config.db')
|
|
due to the fact that BLOBs are stored there
|
|
|
|
To make user be able to roll settings back, no data is deleted from 'config.db' file.
|
|
*/
|
|
func Migrate2(bboltDB, jsonDB TorrServerDB) error {
|
|
var err error = nil
|
|
|
|
const XPATH_SETTINGS = "Settings"
|
|
const NAME_BITTORR = "BitTorr"
|
|
const XPATH_VIEWED = "Viewed"
|
|
|
|
if BTsets != nil {
|
|
msg := "Migrate0002 MUST be called before initializing BTSets"
|
|
log.TLogln(msg)
|
|
os.Exit(1)
|
|
}
|
|
|
|
isByteArraysEqualJson := func(a, b []byte) (bool, error) {
|
|
var objectA interface{}
|
|
var objectB interface{}
|
|
var err error = nil
|
|
if err = json.Unmarshal(a, &objectA); err == nil {
|
|
if err = json.Unmarshal(b, &objectB); err == nil {
|
|
return reflect.DeepEqual(objectA, objectB), nil
|
|
} else {
|
|
err = fmt.Errorf("Error unmashalling B: %s", err.Error())
|
|
}
|
|
} else {
|
|
err = fmt.Errorf("Error unmashalling A: %s", err.Error())
|
|
}
|
|
return false, err
|
|
}
|
|
|
|
migrateXPath := func(xPath, name string) error {
|
|
if jsonDB.Get(xPath, name) == nil {
|
|
bboltDBBlob := bboltDB.Get(xPath, name)
|
|
if bboltDBBlob != nil {
|
|
log.TLogln(fmt.Sprintf("Attempting to migrate %s->%s from TDB to JsonDB", xPath, name))
|
|
jsonDB.Set(xPath, name, bboltDBBlob)
|
|
jsonDBBlob := jsonDB.Get(xPath, name)
|
|
if isEqual, err := isByteArraysEqualJson(bboltDBBlob, jsonDBBlob); err == nil {
|
|
if isEqual {
|
|
log.TLogln(fmt.Sprintf("Migrated %s->%s successful", xPath, name))
|
|
} else {
|
|
msg := fmt.Sprintf("Failed to migrate %s->%s TDB to JsonDB: equality check failed", xPath, name)
|
|
log.TLogln(msg)
|
|
return errors.New(msg)
|
|
}
|
|
} else {
|
|
msg := fmt.Sprintf("Failed to migrate %s->%s TDB to JsonDB: %s", xPath, name, err)
|
|
log.TLogln(msg)
|
|
return errors.New(msg)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if err = migrateXPath(XPATH_SETTINGS, NAME_BITTORR); err != nil {
|
|
return err
|
|
}
|
|
|
|
jsonDBViewedNames := jsonDB.List(XPATH_VIEWED)
|
|
if len(jsonDBViewedNames) <= 0 {
|
|
bboltDBViewedNames := bboltDB.List(XPATH_VIEWED)
|
|
if len(bboltDBViewedNames) > 0 {
|
|
for _, name := range bboltDBViewedNames {
|
|
err = migrateXPath(XPATH_VIEWED, name)
|
|
if err != nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|