init 1.2.x

This commit is contained in:
YouROK
2020-11-06 15:40:58 +03:00
parent ce87ecabcb
commit a1e17b1cf3
57 changed files with 670 additions and 4003 deletions

View File

@@ -1,54 +0,0 @@
package settings
import (
"fmt"
"path/filepath"
bolt "go.etcd.io/bbolt"
)
var (
db *bolt.DB
dbViewedName = []byte("Viewed")
dbInfosName = []byte("Infos")
dbTorrentsName = []byte("Torrents")
dbSettingsName = []byte("Settings")
Path string
)
func openDB() error {
if db != nil {
return nil
}
var err error
var ro = Get().ReadOnlyMode
db, err = bolt.Open(filepath.Join(Path, "torrserver.db"), 0666, &bolt.Options{ReadOnly: ro})
if err != nil {
fmt.Println(err)
return err
}
err = db.Update(func(tx *bolt.Tx) error {
_, err = tx.CreateBucketIfNotExists(dbSettingsName)
if err != nil {
return fmt.Errorf("could not create Settings bucket: %v", err)
}
_, err = tx.CreateBucketIfNotExists(dbTorrentsName)
if err != nil {
return fmt.Errorf("could not create Torrents bucket: %v", err)
}
return nil
})
if err != nil {
CloseDB()
}
return err
}
func CloseDB() {
if db != nil {
db.Close()
db = nil
}
}

View File

@@ -1,66 +0,0 @@
package settings
import (
"fmt"
"strings"
bolt "go.etcd.io/bbolt"
)
func AddInfo(hash, info string) error {
err := openDB()
if err != nil {
return err
}
infoe := GetInfo(hash)
if infoe != "{}" {
return nil // already filled
}
hash = strings.ToUpper(hash)
return db.Update(func(tx *bolt.Tx) error {
dbt, err := tx.CreateBucketIfNotExists([]byte(dbInfosName))
if err != nil {
return err
}
dbi, err := dbt.CreateBucketIfNotExists([]byte(hash))
if err != nil {
return err
}
err = dbi.Put([]byte("Info"), []byte(info))
if err != nil {
return fmt.Errorf("error save torrent info %v", err)
}
return nil
})
}
func GetInfo(hash string) string {
err := openDB()
if err != nil {
return "{}"
}
hash = strings.ToUpper(hash)
ret := "{}"
err = db.View(func(tx *bolt.Tx) error {
hdb := tx.Bucket(dbInfosName)
if hdb == nil {
return fmt.Errorf("could not find torrent info")
}
hdb = hdb.Bucket([]byte(hash))
if hdb != nil {
info := hdb.Get([]byte("Info"))
if info == nil {
return fmt.Errorf("error get torrent info")
}
ret = string(info)
return nil
}
return nil
})
return ret
}

View File

@@ -1,125 +0,0 @@
package settings
import (
"encoding/json"
"fmt"
"time"
bolt "go.etcd.io/bbolt"
)
var (
sets *Settings
StartTime time.Time
)
func init() {
sets = new(Settings)
sets.CacheSize = 200 * 1024 * 1024
sets.EnableDebug = false
sets.PreloadBufferSize = 20 * 1024 * 1024
sets.ConnectionsLimit = 20
sets.DhtConnectionLimit = 500
sets.RetrackersMode = 1
sets.TorrentDisconnectTimeout = 30
StartTime = time.Now()
}
type Settings struct {
CacheSize int64 // in byte, def 200 mb
PreloadBufferSize int64 // in byte, buffer for preload
RetrackersMode int //0 - don`t add, 1 - add retrackers, 2 - remove retrackers
//BT Config
EnableIPv6 bool
EnableDebug bool
DisableTCP bool
DisableUTP bool
DisableUPNP bool
DisableDHT bool
DisableUpload bool
ReadOnlyMode bool
Encryption int // 0 - Enable, 1 - disable, 2 - force
DownloadRateLimit int // in kb, 0 - inf
UploadRateLimit int // in kb, 0 - inf
ConnectionsLimit int
DhtConnectionLimit int // 0 - inf
PeersListenPort int
TorrentDisconnectTimeout int // in seconds
}
func Get() *Settings {
return sets
}
func (s *Settings) String() string {
buf, _ := json.MarshalIndent(sets, "", " ")
return string(buf)
}
func ReadSettings() error {
err := openDB()
if err != nil {
return err
}
buf := make([]byte, 0)
err = db.View(func(tx *bolt.Tx) error {
sdb := tx.Bucket(dbSettingsName)
if sdb == nil {
return fmt.Errorf("error load settings")
}
buf = sdb.Get([]byte("json"))
if buf == nil {
return fmt.Errorf("error load settings")
}
return nil
})
err = json.Unmarshal(buf, sets)
if err != nil {
return err
}
if sets.ConnectionsLimit <= 0 {
sets.ConnectionsLimit = 20
}
if sets.DhtConnectionLimit < 0 {
sets.DhtConnectionLimit = 1000
}
if sets.CacheSize < 0 {
sets.CacheSize = 200 * 1024 * 1024
}
if sets.TorrentDisconnectTimeout < 1 {
sets.TorrentDisconnectTimeout = 1
}
return nil
}
func SaveSettings() error {
err := openDB()
if err != nil {
return err
}
buf, err := json.Marshal(sets)
if err != nil {
return err
}
return db.Update(func(tx *bolt.Tx) error {
setsDB, err := tx.CreateBucketIfNotExists(dbSettingsName)
if err != nil {
return err
}
return setsDB.Put([]byte("json"), []byte(buf))
})
}
func SetRDB() {
SaveSettings()
fmt.Println("Enable Read-only DB mode")
CloseDB()
sets.ReadOnlyMode = true
}

View File

@@ -1,269 +0,0 @@
package settings
import (
"encoding/binary"
"fmt"
bolt "go.etcd.io/bbolt"
)
type Torrent struct {
Name string
Magnet string
InfoBytes []byte
Hash string
Size int64
Timestamp int64
Files []File
}
type File struct {
Name string
Id int
Size int64
}
func SaveTorrentDB(torrent *Torrent) error {
err := openDB()
if err != nil {
return err
}
return db.Update(func(tx *bolt.Tx) error {
dbt, err := tx.CreateBucketIfNotExists(dbTorrentsName)
if err != nil {
return fmt.Errorf("could not create Torrents bucket: %v", err)
}
fmt.Println("Save torrent:", torrent.Name)
hdb, err := dbt.CreateBucketIfNotExists([]byte(torrent.Hash))
if err != nil {
return fmt.Errorf("could not create Torrent bucket: %v", err)
}
err = hdb.Put([]byte("Name"), []byte(torrent.Name))
if err != nil {
return fmt.Errorf("error save torrent: %v", err)
}
err = hdb.Put([]byte("Link"), []byte(torrent.Magnet))
if err != nil {
return fmt.Errorf("error save torrent: %v", err)
}
err = hdb.Put([]byte("InfoBytes"), torrent.InfoBytes)
if err != nil {
return fmt.Errorf("error save torrent: %v", err)
}
err = hdb.Put([]byte("Size"), i2b(torrent.Size))
if err != nil {
return fmt.Errorf("error save torrent: %v", err)
}
err = hdb.Put([]byte("Timestamp"), i2b(torrent.Timestamp))
if err != nil {
return fmt.Errorf("error save torrent: %v", err)
}
fdb, err := hdb.CreateBucketIfNotExists([]byte("Files"))
if err != nil {
return fmt.Errorf("error save torrent files: %v", err)
}
for _, f := range torrent.Files {
ffdb, err := fdb.CreateBucketIfNotExists([]byte(f.Name))
if err != nil {
return fmt.Errorf("error save torrent files: %v", err)
}
err = ffdb.Put([]byte("Id"), i2b(int64(f.Id)))
if err != nil {
return fmt.Errorf("error save torrent files: %v", err)
}
err = ffdb.Put([]byte("Size"), i2b(f.Size))
if err != nil {
return fmt.Errorf("error save torrent files: %v", err)
}
}
return nil
})
}
func RemoveTorrentDB(hash string) error {
err := openDB()
if err != nil {
return err
}
return db.Update(func(tx *bolt.Tx) error {
dbt := tx.Bucket(dbTorrentsName)
if dbt == nil {
return fmt.Errorf("could not find torrent")
}
return dbt.DeleteBucket([]byte(hash))
})
}
func LoadTorrentDB(hash string) (*Torrent, error) {
err := openDB()
if err != nil {
return nil, err
}
var torr *Torrent
err = db.View(func(tx *bolt.Tx) error {
hdb := tx.Bucket(dbTorrentsName)
if hdb == nil {
return fmt.Errorf("could not find torrent")
}
hdb = hdb.Bucket([]byte(hash))
if hdb != nil {
torr = new(Torrent)
torr.Hash = string(hash)
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("InfoBytes"))
if len(tmp) > 0 {
torr.InfoBytes = tmp
} else {
torr.InfoBytes = nil
}
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)
fdb := hdb.Bucket([]byte("Files"))
if fdb == nil {
return fmt.Errorf("error load torrent files")
}
cf := fdb.Cursor()
for fn, _ := cf.First(); fn != nil; fn, _ = cf.Next() {
file := File{Name: string(fn)}
ffdb := fdb.Bucket(fn)
if ffdb == nil {
return fmt.Errorf("error load torrent files")
}
tmp := ffdb.Get([]byte("Id"))
if tmp == nil {
return fmt.Errorf("error load torrent file")
}
file.Id = int(b2i(tmp))
tmp = ffdb.Get([]byte("Size"))
if tmp == nil {
return fmt.Errorf("error load torrent file")
}
file.Size = b2i(tmp)
torr.Files = append(torr.Files, file)
}
SortFiles(torr.Files)
}
return nil
})
return torr, err
}
func LoadTorrentsDB() ([]*Torrent, error) {
err := openDB()
if err != nil {
return nil, err
}
torrs := make([]*Torrent, 0)
err = db.View(func(tx *bolt.Tx) error {
tdb := tx.Bucket(dbTorrentsName)
c := tdb.Cursor()
for h, _ := c.First(); h != nil; h, _ = c.Next() {
hdb := tdb.Bucket(h)
if hdb != nil {
torr := new(Torrent)
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)
fdb := hdb.Bucket([]byte("Files"))
if fdb == nil {
return fmt.Errorf("error load torrent files")
}
cf := fdb.Cursor()
for fn, _ := cf.First(); fn != nil; fn, _ = cf.Next() {
file := File{Name: string(fn)}
ffdb := fdb.Bucket(fn)
if ffdb == nil {
return fmt.Errorf("error load torrent files")
}
tmp := ffdb.Get([]byte("Id"))
if tmp == nil {
return fmt.Errorf("error load torrent file")
}
file.Id = int(b2i(tmp))
tmp = ffdb.Get([]byte("Size"))
if tmp == nil {
return fmt.Errorf("error load torrent file")
}
file.Size = b2i(tmp)
torr.Files = append(torr.Files, file)
}
SortFiles(torr.Files)
torrs = append(torrs, torr)
}
}
return nil
})
return torrs, err
}
func i2b(v int64) []byte {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(v))
return b
}
func b2i(v []byte) int64 {
return int64(binary.BigEndian.Uint64(v))
}

View File

@@ -1,88 +0,0 @@
package settings
import (
"path/filepath"
"sort"
"strings"
)
var (
uFiles = map[string]interface{}{
".3g2": nil,
".3gp": nil,
".aaf": nil,
".asf": nil,
".avchd": nil,
".avi": nil,
".drc": nil,
".flv": nil,
".m2v": nil,
".m4p": nil,
".m4v": nil,
".mkv": nil,
".mng": nil,
".mov": nil,
".mp2": nil,
".mp4": nil,
".mpe": nil,
".mpeg": nil,
".mpg": nil,
".mpv": nil,
".mxf": nil,
".nsv": nil,
".ogg": nil,
".ogv": nil,
".ts": nil,
".m2ts": nil,
".mts": nil,
".qt": nil,
".rm": nil,
".rmvb": nil,
".roq": nil,
".svi": nil,
".vob": nil,
".webm": nil,
".wmv": nil,
".yuv": nil,
".aac": nil,
".aiff": nil,
".ape": nil,
".au": nil,
".flac": nil,
".gsm": nil,
".it": nil,
".m3u": nil,
".m4a": nil,
".mid": nil,
".mod": nil,
".mp3": nil,
".mpa": nil,
".pls": nil,
".ra": nil,
".s3m": nil,
".sid": nil,
".wav": nil,
".wma": nil,
".xm": nil,
}
)
func SortFiles(files []File) {
sort.Slice(files, func(i, j int) bool {
if haveUsable(files[i].Name) && !haveUsable(files[j].Name) {
return true
}
if !haveUsable(files[i].Name) && haveUsable(files[j].Name) {
return false
}
return files[i].Name < files[j].Name
})
}
func haveUsable(name string) bool {
ext := strings.ToLower(filepath.Ext(name))
_, ok := uFiles[ext]
return ok
}

View File

@@ -1,103 +0,0 @@
package settings
import (
"fmt"
bolt "go.etcd.io/bbolt"
)
func SetViewed(hash, filename string) error {
err := openDB()
if err != nil {
return err
}
return db.Update(func(tx *bolt.Tx) error {
dbt, err := tx.CreateBucketIfNotExists(dbViewedName)
if err != nil {
return fmt.Errorf("error save viewed %v", err)
}
hdb, err := dbt.CreateBucketIfNotExists([]byte(hash))
if err != nil {
return fmt.Errorf("error save viewed %v", err)
}
err = hdb.Put([]byte(filename), []byte{1})
if err != nil {
return fmt.Errorf("error save viewed %v", err)
}
return nil
})
}
func RemTorrentViewed(hash string) error {
err := openDB()
if err != nil {
return err
}
return db.Update(func(tx *bolt.Tx) error {
dbt := tx.Bucket(dbViewedName)
if dbt == nil {
return nil
}
err = dbt.DeleteBucket([]byte(hash))
if err == nil || err == bolt.ErrBucketNotFound {
return nil
}
return err
})
}
func GetViewed(hash, filename string) bool {
err := openDB()
if err != nil {
return false
}
viewed := false
err = db.View(func(tx *bolt.Tx) error {
hdb := tx.Bucket(dbViewedName)
if hdb == nil {
return fmt.Errorf("error get viewed")
}
hdb = hdb.Bucket([]byte(hash))
if hdb != nil {
vw := hdb.Get([]byte(filename))
viewed = vw != nil && vw[0] == 1
}
return nil
})
return viewed
}
func GetViewedList() map[string][]string {
err := openDB()
if err != nil {
return nil
}
var list = make(map[string][]string)
err = db.View(func(tx *bolt.Tx) error {
rdb := tx.Bucket(dbViewedName)
if rdb == nil {
return fmt.Errorf("could not find torrent")
}
rdb.ForEach(func(hash, _ []byte) error {
hdb := rdb.Bucket(hash)
fdb := hdb.Bucket([]byte("Files"))
fdb.ForEach(func(fileName, _ []byte) error {
vw := fdb.Get(fileName)
if vw != nil && vw[0] == 1 {
list[string(hash)] = append(list[string(hash)], string(fileName))
}
return nil
})
return nil
})
return nil
})
return list
}

179
src/server/settings/db.go Normal file
View File

@@ -0,0 +1,179 @@
package settings
import (
"path/filepath"
"strings"
bolt "go.etcd.io/bbolt"
"server/log"
)
type TDB struct {
Path string
ReadOnly bool
db *bolt.DB
}
func NewTDB(path string, readOnly bool) *TDB {
db, err := bolt.Open(filepath.Join(path, "config.db"), 0666, nil)
if err != nil {
log.TLogln(err)
return nil
}
tdb := new(TDB)
tdb.db = db
tdb.Path = path
tdb.ReadOnly = readOnly
return tdb
}
func (v *TDB) CloseDB() {
if v.db != nil {
v.db.Close()
v.db = nil
}
}
func (v *TDB) Get(xpath, name string) []byte {
spath := strings.Split(xpath, "/")
if len(spath) == 0 {
return nil
}
var ret []byte
err := v.db.View(func(tx *bolt.Tx) error {
buckt := tx.Bucket([]byte(spath[0]))
if buckt == nil {
return nil
}
for i, p := range spath {
if i == 0 {
continue
}
buckt = buckt.Bucket([]byte(p))
if buckt == nil {
return nil
}
}
ret = buckt.Get([]byte(name))
return nil
})
if err != nil {
log.TLogln("Error get sets", xpath+"/"+name, ", error:", err)
}
return ret
}
func (v *TDB) Set(xpath, name string, value []byte) {
if v.ReadOnly {
return
}
spath := strings.Split(xpath, "/")
if len(spath) == 0 {
return
}
err := v.db.Update(func(tx *bolt.Tx) error {
buckt, err := tx.CreateBucketIfNotExists([]byte(spath[0]))
if err != nil {
return err
}
for i, p := range spath {
if i == 0 {
continue
}
buckt, err = buckt.CreateBucketIfNotExists([]byte(p))
if err != nil {
return err
}
}
return buckt.Put([]byte(name), value)
})
if err != nil {
log.TLogln("Error put sets", xpath+"/"+name, ", error:", err)
log.TLogln("value:", value)
}
return
}
func (v *TDB) List(xpath string) []string {
spath := strings.Split(xpath, "/")
if len(spath) == 0 {
return nil
}
var ret []string
err := v.db.View(func(tx *bolt.Tx) error {
buckt := tx.Bucket([]byte(spath[0]))
if buckt == nil {
return nil
}
for i, p := range spath {
if i == 0 {
continue
}
buckt = buckt.Bucket([]byte(p))
if buckt == nil {
return nil
}
}
buckt.ForEach(func(_, v []byte) error {
if len(v) > 0 {
ret = append(ret, string(v))
}
return nil
})
return nil
})
if err != nil {
log.TLogln("Error list sets", xpath, ", error:", err)
}
return ret
}
func (v *TDB) Rem(xpath, name string) {
if v.ReadOnly {
return
}
spath := strings.Split(xpath, "/")
if len(spath) == 0 {
return
}
err := v.db.Update(func(tx *bolt.Tx) error {
buckt := tx.Bucket([]byte(spath[0]))
if buckt == nil {
return nil
}
for i, p := range spath {
if i == 0 {
continue
}
buckt = buckt.Bucket([]byte(p))
if buckt == nil {
return nil
}
}
return buckt.Delete([]byte(name))
})
if err != nil {
log.TLogln("Error rem sets", xpath+"/"+name, ", error:", err)
}
return
}

View File

@@ -0,0 +1,16 @@
package settings
var (
tdb *TDB
Path string
)
func InitSets(path string, readOnly bool) {
Path = path
tdb = NewTDB(path, readOnly)
loadBTSets()
}
func CloseDB() {
tdb.CloseDB()
}

View File

@@ -0,0 +1,77 @@
package settings
import (
"encoding/json"
"server/log"
)
type BTSets struct {
CacheSize int64 // in byte, def 200 mb
PreloadBufferSize int64 // in byte, buffer for preload
SaveOnDisk bool // save on disk?
ContentPath string // path to save content
RetrackersMode int // 0 - don`t add, 1 - add retrackers (def), 2 - remove retrackers 3 - replace retrackers
TorrentDisconnectTimeout int // in seconds
EnableDebug bool // print logs
// BT Config
EnableIPv6 bool
DisableTCP bool
DisableUTP bool
DisableUPNP bool
DisableDHT bool
DisableUpload bool
Encryption int // ???? 0 - Enable, 1 - disable, 2 - force
DownloadRateLimit int // in kb, 0 - inf
UploadRateLimit int // in kb, 0 - inf
ConnectionsLimit int
DhtConnectionLimit int // 0 - inf
PeersListenPort int
}
func (v *BTSets) String() string {
buf, _ := json.Marshal(v)
return string(buf)
}
var (
BTsets = loadBTSets()
)
func SetBTSets(sets *BTSets) {
if tdb.ReadOnly {
return
}
BTsets = sets
buf, err := json.Marshal(BTsets)
if err != nil {
log.TLogln("Error marshal btsets", err)
return
}
tdb.Set("Settings", "BitTorr", buf)
}
func loadBTSets() *BTSets {
buf := tdb.Get("Settings", "BitTorr")
if len(buf) > 0 {
err := json.Unmarshal(buf, &BTsets)
if err == nil {
return BTsets
}
log.TLogln("Error unmarshal btsets", err)
}
sets := new(BTSets)
sets.EnableDebug = false
sets.CacheSize = 200 * 1024 * 1024 // 200mb
sets.PreloadBufferSize = 20 * 1024 * 1024
sets.ConnectionsLimit = 20
sets.DhtConnectionLimit = 500
sets.RetrackersMode = 1
sets.TorrentDisconnectTimeout = 30
return sets
}