Use metainfo.Hash for piece and info hashes
This commit is contained in:
parent
00f33c848e
commit
b80bb6393a
40
client.go
40
client.go
|
@ -143,7 +143,7 @@ type Client struct {
|
||||||
utpSock *utp.Socket
|
utpSock *utp.Socket
|
||||||
dHT *dht.Server
|
dHT *dht.Server
|
||||||
ipBlockList iplist.Ranger
|
ipBlockList iplist.Ranger
|
||||||
bannedTorrents map[metainfo.InfoHash]struct{}
|
bannedTorrents map[metainfo.Hash]struct{}
|
||||||
config Config
|
config Config
|
||||||
pruneTimer *time.Timer
|
pruneTimer *time.Timer
|
||||||
extensionBytes peerExtensionBytes
|
extensionBytes peerExtensionBytes
|
||||||
|
@ -158,7 +158,7 @@ type Client struct {
|
||||||
event sync.Cond
|
event sync.Cond
|
||||||
closed missinggo.Event
|
closed missinggo.Event
|
||||||
|
|
||||||
torrents map[metainfo.InfoHash]*Torrent
|
torrents map[metainfo.Hash]*Torrent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *Client) IPBlockList() iplist.Ranger {
|
func (me *Client) IPBlockList() iplist.Ranger {
|
||||||
|
@ -189,7 +189,7 @@ func (me *Client) ListenAddr() (addr net.Addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type hashSorter struct {
|
type hashSorter struct {
|
||||||
Hashes []metainfo.InfoHash
|
Hashes []metainfo.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me hashSorter) Len() int {
|
func (me hashSorter) Len() int {
|
||||||
|
@ -337,7 +337,7 @@ func (cl *Client) initBannedTorrents() error {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
scanner := bufio.NewScanner(f)
|
scanner := bufio.NewScanner(f)
|
||||||
cl.bannedTorrents = make(map[metainfo.InfoHash]struct{})
|
cl.bannedTorrents = make(map[metainfo.Hash]struct{})
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
if strings.HasPrefix(strings.TrimSpace(scanner.Text()), "#") {
|
if strings.HasPrefix(strings.TrimSpace(scanner.Text()), "#") {
|
||||||
continue
|
continue
|
||||||
|
@ -353,7 +353,7 @@ func (cl *Client) initBannedTorrents() error {
|
||||||
if len(ihs) != 20 {
|
if len(ihs) != 20 {
|
||||||
return errors.New("bad infohash")
|
return errors.New("bad infohash")
|
||||||
}
|
}
|
||||||
var ih metainfo.InfoHash
|
var ih metainfo.Hash
|
||||||
missinggo.CopyExact(&ih, ihs)
|
missinggo.CopyExact(&ih, ihs)
|
||||||
cl.bannedTorrents[ih] = struct{}{}
|
cl.bannedTorrents[ih] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ func NewClient(cfg *Config) (cl *Client, err error) {
|
||||||
config: *cfg,
|
config: *cfg,
|
||||||
defaultStorage: cfg.DefaultStorage,
|
defaultStorage: cfg.DefaultStorage,
|
||||||
dopplegangerAddrs: make(map[string]struct{}),
|
dopplegangerAddrs: make(map[string]struct{}),
|
||||||
torrents: make(map[metainfo.InfoHash]*Torrent),
|
torrents: make(map[metainfo.Hash]*Torrent),
|
||||||
}
|
}
|
||||||
missinggo.CopyExact(&cl.extensionBytes, defaultExtensionBytes)
|
missinggo.CopyExact(&cl.extensionBytes, defaultExtensionBytes)
|
||||||
cl.event.L = &cl.mu
|
cl.event.L = &cl.mu
|
||||||
|
@ -576,14 +576,14 @@ func (cl *Client) incomingConnection(nc net.Conn, utp bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a handle to the given torrent, if it's present in the client.
|
// Returns a handle to the given torrent, if it's present in the client.
|
||||||
func (cl *Client) Torrent(ih metainfo.InfoHash) (t *Torrent, ok bool) {
|
func (cl *Client) Torrent(ih metainfo.Hash) (t *Torrent, ok bool) {
|
||||||
cl.mu.Lock()
|
cl.mu.Lock()
|
||||||
defer cl.mu.Unlock()
|
defer cl.mu.Unlock()
|
||||||
t, ok = cl.torrents[ih]
|
t, ok = cl.torrents[ih]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *Client) torrent(ih metainfo.InfoHash) *Torrent {
|
func (me *Client) torrent(ih metainfo.Hash) *Torrent {
|
||||||
return me.torrents[ih]
|
return me.torrents[ih]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,14 +849,14 @@ func (me *peerExtensionBytes) SupportsFast() bool {
|
||||||
type handshakeResult struct {
|
type handshakeResult struct {
|
||||||
peerExtensionBytes
|
peerExtensionBytes
|
||||||
peerID
|
peerID
|
||||||
metainfo.InfoHash
|
metainfo.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// ih is nil if we expect the peer to declare the InfoHash, such as when the
|
// ih is nil if we expect the peer to declare the InfoHash, such as when the
|
||||||
// peer initiated the connection. Returns ok if the handshake was successful,
|
// peer initiated the connection. Returns ok if the handshake was successful,
|
||||||
// and err if there was an unexpected condition other than the peer simply
|
// and err if there was an unexpected condition other than the peer simply
|
||||||
// abandoning the handshake.
|
// abandoning the handshake.
|
||||||
func handshake(sock io.ReadWriter, ih *metainfo.InfoHash, peerID [20]byte, extensions peerExtensionBytes) (res handshakeResult, ok bool, err error) {
|
func handshake(sock io.ReadWriter, ih *metainfo.Hash, peerID [20]byte, extensions peerExtensionBytes) (res handshakeResult, ok bool, err error) {
|
||||||
// Bytes to be sent to the peer. Should never block the sender.
|
// Bytes to be sent to the peer. Should never block the sender.
|
||||||
postCh := make(chan []byte, 4)
|
postCh := make(chan []byte, 4)
|
||||||
// A single error value sent when the writer completes.
|
// A single error value sent when the writer completes.
|
||||||
|
@ -903,7 +903,7 @@ func handshake(sock io.ReadWriter, ih *metainfo.InfoHash, peerID [20]byte, exten
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
missinggo.CopyExact(&res.peerExtensionBytes, b[20:28])
|
missinggo.CopyExact(&res.peerExtensionBytes, b[20:28])
|
||||||
missinggo.CopyExact(&res.InfoHash, b[28:48])
|
missinggo.CopyExact(&res.Hash, b[28:48])
|
||||||
missinggo.CopyExact(&res.peerID, b[48:68])
|
missinggo.CopyExact(&res.peerID, b[48:68])
|
||||||
peerExtensions.Add(hex.EncodeToString(res.peerExtensionBytes[:]), 1)
|
peerExtensions.Add(hex.EncodeToString(res.peerExtensionBytes[:]), 1)
|
||||||
|
|
||||||
|
@ -911,7 +911,7 @@ func handshake(sock io.ReadWriter, ih *metainfo.InfoHash, peerID [20]byte, exten
|
||||||
// could prevent them trying to reconnect, falsely believing there was
|
// could prevent them trying to reconnect, falsely believing there was
|
||||||
// just a problem.
|
// just a problem.
|
||||||
if ih == nil { // We were waiting for the peer to tell us what they wanted.
|
if ih == nil { // We were waiting for the peer to tell us what they wanted.
|
||||||
post(res.InfoHash[:])
|
post(res.Hash[:])
|
||||||
post(peerID[:])
|
post(peerID[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,12 +1020,12 @@ func (cl *Client) receiveHandshakes(c *connection) (t *Torrent, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns !ok if handshake failed for valid reasons.
|
// Returns !ok if handshake failed for valid reasons.
|
||||||
func (cl *Client) connBTHandshake(c *connection, ih *metainfo.InfoHash) (ret metainfo.InfoHash, ok bool, err error) {
|
func (cl *Client) connBTHandshake(c *connection, ih *metainfo.Hash) (ret metainfo.Hash, ok bool, err error) {
|
||||||
res, ok, err := handshake(c.rw, ih, cl.peerID, cl.extensionBytes)
|
res, ok, err := handshake(c.rw, ih, cl.peerID, cl.extensionBytes)
|
||||||
if err != nil || !ok {
|
if err != nil || !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ret = res.InfoHash
|
ret = res.Hash
|
||||||
c.PeerExtensionBytes = res.peerExtensionBytes
|
c.PeerExtensionBytes = res.peerExtensionBytes
|
||||||
c.PeerID = res.peerID
|
c.PeerID = res.peerID
|
||||||
c.completedHandshake = time.Now()
|
c.completedHandshake = time.Now()
|
||||||
|
@ -1187,7 +1187,7 @@ func (cl *Client) requestPendingMetadata(t *Torrent, c *connection) {
|
||||||
func (cl *Client) completedMetadata(t *Torrent) {
|
func (cl *Client) completedMetadata(t *Torrent) {
|
||||||
h := sha1.New()
|
h := sha1.New()
|
||||||
h.Write(t.metadataBytes)
|
h.Write(t.metadataBytes)
|
||||||
var ih metainfo.InfoHash
|
var ih metainfo.Hash
|
||||||
missinggo.CopyExact(&ih, h.Sum(nil))
|
missinggo.CopyExact(&ih, h.Sum(nil))
|
||||||
if ih != t.infoHash {
|
if ih != t.infoHash {
|
||||||
log.Print("bad metadata")
|
log.Print("bad metadata")
|
||||||
|
@ -1678,7 +1678,7 @@ func (me *Client) addPeers(t *Torrent, peers []Peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cl *Client) cachedMetaInfoFilename(ih metainfo.InfoHash) string {
|
func (cl *Client) cachedMetaInfoFilename(ih metainfo.Hash) string {
|
||||||
return filepath.Join(cl.configDir(), "torrents", ih.HexString()+".torrent")
|
return filepath.Join(cl.configDir(), "torrents", ih.HexString()+".torrent")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1725,7 +1725,7 @@ func (cl *Client) setMetaData(t *Torrent, md *metainfo.Info, bytes []byte) (err
|
||||||
// Prepare a Torrent without any attachment to a Client. That means we can
|
// Prepare a Torrent without any attachment to a Client. That means we can
|
||||||
// initialize fields all fields that don't require the Client without locking
|
// initialize fields all fields that don't require the Client without locking
|
||||||
// it.
|
// it.
|
||||||
func newTorrent(ih metainfo.InfoHash) (t *Torrent) {
|
func newTorrent(ih metainfo.Hash) (t *Torrent) {
|
||||||
t = &Torrent{
|
t = &Torrent{
|
||||||
infoHash: ih,
|
infoHash: ih,
|
||||||
chunkSize: defaultChunkSize,
|
chunkSize: defaultChunkSize,
|
||||||
|
@ -1849,7 +1849,7 @@ func (t *Torrent) DownloadAll() {
|
||||||
|
|
||||||
// Returns nil metainfo if it isn't in the cache. Checks that the retrieved
|
// Returns nil metainfo if it isn't in the cache. Checks that the retrieved
|
||||||
// metainfo has the correct infohash.
|
// metainfo has the correct infohash.
|
||||||
func (cl *Client) torrentCacheMetaInfo(ih metainfo.InfoHash) (mi *metainfo.MetaInfo, err error) {
|
func (cl *Client) torrentCacheMetaInfo(ih metainfo.Hash) (mi *metainfo.MetaInfo, err error) {
|
||||||
if cl.config.DisableMetainfoCache {
|
if cl.config.DisableMetainfoCache {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1878,7 +1878,7 @@ func (cl *Client) torrentCacheMetaInfo(ih metainfo.InfoHash) (mi *metainfo.MetaI
|
||||||
type TorrentSpec struct {
|
type TorrentSpec struct {
|
||||||
// The tiered tracker URIs.
|
// The tiered tracker URIs.
|
||||||
Trackers [][]string
|
Trackers [][]string
|
||||||
InfoHash metainfo.InfoHash
|
InfoHash metainfo.Hash
|
||||||
Info *metainfo.InfoEx
|
Info *metainfo.InfoEx
|
||||||
// The name to use if the Name field from the Info isn't available.
|
// The name to use if the Name field from the Info isn't available.
|
||||||
DisplayName string
|
DisplayName string
|
||||||
|
@ -1989,7 +1989,7 @@ func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err e
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *Client) dropTorrent(infoHash metainfo.InfoHash) (err error) {
|
func (me *Client) dropTorrent(infoHash metainfo.Hash) (err error) {
|
||||||
t, ok := me.torrents[infoHash]
|
t, ok := me.torrents[infoHash]
|
||||||
if !ok {
|
if !ok {
|
||||||
err = fmt.Errorf("no such torrent")
|
err = fmt.Errorf("no such torrent")
|
||||||
|
|
|
@ -87,7 +87,7 @@ func TestPieceHashSize(t *testing.T) {
|
||||||
func TestTorrentInitialState(t *testing.T) {
|
func TestTorrentInitialState(t *testing.T) {
|
||||||
dir, mi := testutil.GreetingTestTorrent()
|
dir, mi := testutil.GreetingTestTorrent()
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
tor := newTorrent(func() (ih metainfo.InfoHash) {
|
tor := newTorrent(func() (ih metainfo.Hash) {
|
||||||
missinggo.CopyExact(ih[:], mi.Info.Hash)
|
missinggo.CopyExact(ih[:], mi.Info.Hash)
|
||||||
return
|
return
|
||||||
}())
|
}())
|
||||||
|
|
|
@ -172,7 +172,7 @@ func (me Piece) Offset() int64 {
|
||||||
return int64(me.i) * me.Info.PieceLength
|
return int64(me.i) * me.Info.PieceLength
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me Piece) Hash() (ret InfoHash) {
|
func (me Piece) Hash() (ret Hash) {
|
||||||
missinggo.CopyExact(&ret, me.Info.Pieces[me.i*20:(me.i+1)*20])
|
missinggo.CopyExact(&ret, me.Info.Pieces[me.i*20:(me.i+1)*20])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ func (i *Info) UpvertedFiles() []FileInfo {
|
||||||
// important to Bittorrent.
|
// important to Bittorrent.
|
||||||
type InfoEx struct {
|
type InfoEx struct {
|
||||||
Info
|
Info
|
||||||
Hash *InfoHash
|
Hash *Hash
|
||||||
Bytes []byte
|
Bytes []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ func (this *InfoEx) UnmarshalBencode(data []byte) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
this.Hash = new(InfoHash)
|
this.Hash = new(Hash)
|
||||||
missinggo.CopyExact(this.Hash, h.Sum(nil))
|
missinggo.CopyExact(this.Hash, h.Sum(nil))
|
||||||
return bencode.Unmarshal(data, &this.Info)
|
return bencode.Unmarshal(data, &this.Info)
|
||||||
}
|
}
|
||||||
|
@ -257,16 +257,17 @@ func (mi *MetaInfo) SetDefaults() {
|
||||||
mi.Info.PieceLength = 256 * 1024
|
mi.Info.PieceLength = 256 * 1024
|
||||||
}
|
}
|
||||||
|
|
||||||
type InfoHash [20]byte
|
// 20-byte SHA1 hash used for info and pieces.
|
||||||
|
type Hash [20]byte
|
||||||
|
|
||||||
func (me InfoHash) Bytes() []byte {
|
func (me Hash) Bytes() []byte {
|
||||||
return me[:]
|
return me[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ih *InfoHash) AsString() string {
|
func (ih *Hash) AsString() string {
|
||||||
return string(ih[:])
|
return string(ih[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ih InfoHash) HexString() string {
|
func (ih Hash) HexString() string {
|
||||||
return fmt.Sprintf("%x", ih[:])
|
return fmt.Sprintf("%x", ih[:])
|
||||||
}
|
}
|
||||||
|
|
4
misc.go
4
misc.go
|
@ -21,10 +21,6 @@ const (
|
||||||
minDialTimeout = 5 * time.Second
|
minDialTimeout = 5 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
|
||||||
pieceSum [20]byte
|
|
||||||
)
|
|
||||||
|
|
||||||
func lastChunkSpec(pieceLength, chunkSize pp.Integer) (cs chunkSpec) {
|
func lastChunkSpec(pieceLength, chunkSize pp.Integer) (cs chunkSpec) {
|
||||||
cs.Begin = (pieceLength - 1) / chunkSize * chunkSize
|
cs.Begin = (pieceLength - 1) / chunkSize * chunkSize
|
||||||
cs.Length = pieceLength - cs.Begin
|
cs.Length = pieceLength - cs.Begin
|
||||||
|
|
2
piece.go
2
piece.go
|
@ -30,7 +30,7 @@ const (
|
||||||
|
|
||||||
type piece struct {
|
type piece struct {
|
||||||
// The completed piece SHA1 hash, from the metainfo "pieces" field.
|
// The completed piece SHA1 hash, from the metainfo "pieces" field.
|
||||||
Hash pieceSum
|
Hash metainfo.Hash
|
||||||
t *Torrent
|
t *Torrent
|
||||||
index int
|
index int
|
||||||
// Chunks we've written to since the last check. The chunk offset and
|
// Chunks we've written to since the last check. The chunk offset and
|
||||||
|
|
|
@ -33,7 +33,7 @@ func (me *mmapStorage) OpenTorrent(info *metainfo.InfoEx) (t Torrent, err error)
|
||||||
|
|
||||||
type mmapTorrentStorage struct {
|
type mmapTorrentStorage struct {
|
||||||
span mmap_span.MMapSpan
|
span mmap_span.MMapSpan
|
||||||
completed map[metainfo.InfoHash]bool
|
completed map[metainfo.Hash]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *mmapTorrentStorage) Piece(p metainfo.Piece) Piece {
|
func (me *mmapTorrentStorage) Piece(p metainfo.Piece) Piece {
|
||||||
|
@ -63,7 +63,7 @@ func (me mmapStoragePiece) GetIsComplete() bool {
|
||||||
|
|
||||||
func (me mmapStoragePiece) MarkComplete() error {
|
func (me mmapStoragePiece) MarkComplete() error {
|
||||||
if me.storage.completed == nil {
|
if me.storage.completed == nil {
|
||||||
me.storage.completed = make(map[metainfo.InfoHash]bool)
|
me.storage.completed = make(map[metainfo.Hash]bool)
|
||||||
}
|
}
|
||||||
me.storage.completed[me.p.Hash()] = true
|
me.storage.completed[me.p.Hash()] = true
|
||||||
return nil
|
return nil
|
||||||
|
|
2
t.go
2
t.go
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
// The torrent's infohash. This is fixed and cannot change. It uniquely
|
// The torrent's infohash. This is fixed and cannot change. It uniquely
|
||||||
// identifies a torrent.
|
// identifies a torrent.
|
||||||
func (t *Torrent) InfoHash() metainfo.InfoHash {
|
func (t *Torrent) InfoHash() metainfo.Hash {
|
||||||
return t.infoHash
|
return t.infoHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ type Torrent struct {
|
||||||
// announcing, and communicating with peers.
|
// announcing, and communicating with peers.
|
||||||
ceasingNetworking chan struct{}
|
ceasingNetworking chan struct{}
|
||||||
|
|
||||||
infoHash metainfo.InfoHash
|
infoHash metainfo.Hash
|
||||||
pieces []piece
|
pieces []piece
|
||||||
// Values are the piece indices that changed.
|
// Values are the piece indices that changed.
|
||||||
pieceStateChanges *pubsub.PubSub
|
pieceStateChanges *pubsub.PubSub
|
||||||
|
@ -656,7 +656,7 @@ func (t *Torrent) pieceLength(piece int) (len_ pp.Integer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Torrent) hashPiece(piece int) (ret pieceSum) {
|
func (t *Torrent) hashPiece(piece int) (ret metainfo.Hash) {
|
||||||
hash := pieceHash.New()
|
hash := pieceHash.New()
|
||||||
p := &t.pieces[piece]
|
p := &t.pieces[piece]
|
||||||
p.waitNoPendingWrites()
|
p.waitNoPendingWrites()
|
||||||
|
|
|
@ -27,11 +27,11 @@ type Event struct {
|
||||||
MagnetURI string
|
MagnetURI string
|
||||||
Change
|
Change
|
||||||
TorrentFilePath string
|
TorrentFilePath string
|
||||||
InfoHash metainfo.InfoHash
|
InfoHash metainfo.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
type entity struct {
|
type entity struct {
|
||||||
metainfo.InfoHash
|
metainfo.Hash
|
||||||
MagnetURI string
|
MagnetURI string
|
||||||
TorrentFilePath string
|
TorrentFilePath string
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ type Instance struct {
|
||||||
w *fsnotify.Watcher
|
w *fsnotify.Watcher
|
||||||
dirName string
|
dirName string
|
||||||
Events chan Event
|
Events chan Event
|
||||||
dirState map[metainfo.InfoHash]entity
|
dirState map[metainfo.Hash]entity
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *Instance) Close() {
|
func (me *Instance) Close() {
|
||||||
|
@ -65,7 +65,7 @@ func (me *Instance) handleErrors() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func torrentFileInfoHash(fileName string) (ih metainfo.InfoHash, ok bool) {
|
func torrentFileInfoHash(fileName string) (ih metainfo.Hash, ok bool) {
|
||||||
mi, _ := metainfo.LoadFromFile(fileName)
|
mi, _ := metainfo.LoadFromFile(fileName)
|
||||||
if mi == nil {
|
if mi == nil {
|
||||||
return
|
return
|
||||||
|
@ -75,7 +75,7 @@ func torrentFileInfoHash(fileName string) (ih metainfo.InfoHash, ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
|
func scanDir(dirName string) (ee map[metainfo.Hash]entity) {
|
||||||
d, err := os.Open(dirName)
|
d, err := os.Open(dirName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
@ -87,15 +87,15 @@ func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ee = make(map[metainfo.InfoHash]entity, len(names))
|
ee = make(map[metainfo.Hash]entity, len(names))
|
||||||
addEntity := func(e entity) {
|
addEntity := func(e entity) {
|
||||||
e0, ok := ee[e.InfoHash]
|
e0, ok := ee[e.Hash]
|
||||||
if ok {
|
if ok {
|
||||||
if e0.MagnetURI == "" || len(e.MagnetURI) < len(e0.MagnetURI) {
|
if e0.MagnetURI == "" || len(e.MagnetURI) < len(e0.MagnetURI) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ee[e.InfoHash] = e
|
ee[e.Hash] = e
|
||||||
}
|
}
|
||||||
for _, n := range names {
|
for _, n := range names {
|
||||||
fullName := filepath.Join(dirName, n)
|
fullName := filepath.Join(dirName, n)
|
||||||
|
@ -108,7 +108,7 @@ func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
|
||||||
e := entity{
|
e := entity{
|
||||||
TorrentFilePath: fullName,
|
TorrentFilePath: fullName,
|
||||||
}
|
}
|
||||||
missinggo.CopyExact(&e.InfoHash, ih)
|
missinggo.CopyExact(&e.Hash, ih)
|
||||||
addEntity(e)
|
addEntity(e)
|
||||||
case ".magnet":
|
case ".magnet":
|
||||||
uris, err := magnetFileURIs(fullName)
|
uris, err := magnetFileURIs(fullName)
|
||||||
|
@ -123,7 +123,7 @@ func scanDir(dirName string) (ee map[metainfo.InfoHash]entity) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
addEntity(entity{
|
addEntity(entity{
|
||||||
InfoHash: m.InfoHash,
|
Hash: m.InfoHash,
|
||||||
MagnetURI: uri,
|
MagnetURI: uri,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ func magnetFileURIs(name string) (uris []string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *Instance) torrentRemoved(ih metainfo.InfoHash) {
|
func (me *Instance) torrentRemoved(ih metainfo.Hash) {
|
||||||
me.Events <- Event{
|
me.Events <- Event{
|
||||||
InfoHash: ih,
|
InfoHash: ih,
|
||||||
Change: Removed,
|
Change: Removed,
|
||||||
|
@ -160,7 +160,7 @@ func (me *Instance) torrentRemoved(ih metainfo.InfoHash) {
|
||||||
|
|
||||||
func (me *Instance) torrentAdded(e entity) {
|
func (me *Instance) torrentAdded(e entity) {
|
||||||
me.Events <- Event{
|
me.Events <- Event{
|
||||||
InfoHash: e.InfoHash,
|
InfoHash: e.Hash,
|
||||||
Change: Added,
|
Change: Added,
|
||||||
MagnetURI: e.MagnetURI,
|
MagnetURI: e.MagnetURI,
|
||||||
TorrentFilePath: e.TorrentFilePath,
|
TorrentFilePath: e.TorrentFilePath,
|
||||||
|
@ -203,7 +203,7 @@ func New(dirName string) (i *Instance, err error) {
|
||||||
w: w,
|
w: w,
|
||||||
dirName: dirName,
|
dirName: dirName,
|
||||||
Events: make(chan Event),
|
Events: make(chan Event),
|
||||||
dirState: make(map[metainfo.InfoHash]entity, 0),
|
dirState: make(map[metainfo.Hash]entity, 0),
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
i.refresh()
|
i.refresh()
|
||||||
|
|
Loading…
Reference in New Issue