* [WIP] Torrent Generation on not found error As asked in #1517, it allows on-the-fly torrent generation. Since it uses magnet links, it needs some time to connect to peers. So it can't be instant generation, we need the user to wait and try after a minute at least. * Replace Fatal by simple error * attempt at fixing travis * del * Add Anacrolyx dependency * Add back difflib * Remove .torrent suffix in the url example * Add some explanations when file missing page shown * Ignore downloads directory * Either use cache (third-party site) or own download directory * Wrong import * If there is an error then it means we aren't generating a torrent file May it be "torrent not found" or "We do not store torrent files" which are the two only existing errors for this page * hash is never empty * TorrentLink may be empty at times So we add a /download/:hash link if it is * Update README.md * Made a mistake here, need to check if false * Update en-us.all.json * Update CHANGELOG.md * Torrent file generation can be triggered by click on button if JS enabled * Update download.go * Update download.go * Use c.JSON instead of text/template * Return to default behavior if we don't generate the file * Don't do the query if returned to default behavior * Add "Could not generate torrent file" error * Fix JS condition & lower delay until button updates * Start download automatically once torrent file is generated * Fix torrentFileExists() constantly returning false if external torrent download URL * torrent-view-data is two tables instead of one This allows the removal of useless things without any problem (e.g Website link), but also a better responsibe design since the previous one separated stats after a certain res looking very wonky * CSS changes to go along * Remove useless <b></b> * Update main.css * In torrentFileExists, check if filestorage path exists instead of looking at the domain in torrent link When checking if the file is stored on another server i used to simply check if the domain name was inside the torrent link, but we can straight up check for filestorage length * Fix JS of on-demand stat fetching * ScrapeAge variable accessible through view.jet.html Contains last scraped time in hours, is at -1 is torrent has never been scraped Stats will get updated if it's either at -1 or above 1460 (2 months old) * Refresh stats if older than two months OR unknown and older than 24h Show last scraped date even if stats are unknown * Add StatsObsolete variable to torrent Indicating if: - They can be shown - They need to be updated * Update scraped data even if Unknown, prevent users from trying to fetch stats every seconds * Torrent file stored locally by default * no need to do all of that if no filestorage * fix filestorage path * Fix torrent download button stuck on "Generating torrent file" at rare times * fix some css rules that didn't work on IE * Fix panic error Seems like this error is a known bug from anacrolyx torrent https://github.com/anacrolix/torrent/issues/83 To prevent it, I'm creating a single client and modifying the socket.go to make it not raise a panic but a simple error log.
116 lignes
3,6 Kio
Go
116 lignes
3,6 Kio
Go
// Copyright 2011 Evan Shaw. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// This file defines the common package interface and contains a little bit of
|
|
// factored out logic.
|
|
|
|
// Package mmap allows mapping files into memory. It tries to provide a simple, reasonably portable interface,
|
|
// but doesn't go out of its way to abstract away every little platform detail.
|
|
// This specifically means:
|
|
// * forked processes may or may not inherit mappings
|
|
// * a file's timestamp may or may not be updated by writes through mappings
|
|
// * specifying a size larger than the file's actual size can increase the file's size
|
|
// * If the mapped file is being modified by another process while your program's running, don't expect consistent results between platforms
|
|
package mmap
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"reflect"
|
|
"unsafe"
|
|
)
|
|
|
|
const (
|
|
// RDONLY maps the memory read-only.
|
|
// Attempts to write to the MMap object will result in undefined behavior.
|
|
RDONLY = 0
|
|
// RDWR maps the memory as read-write. Writes to the MMap object will update the
|
|
// underlying file.
|
|
RDWR = 1 << iota
|
|
// COPY maps the memory as copy-on-write. Writes to the MMap object will affect
|
|
// memory, but the underlying file will remain unchanged.
|
|
COPY
|
|
// If EXEC is set, the mapped memory is marked as executable.
|
|
EXEC
|
|
)
|
|
|
|
const (
|
|
// If the ANON flag is set, the mapped memory will not be backed by a file.
|
|
ANON = 1 << iota
|
|
)
|
|
|
|
// MMap represents a file mapped into memory.
|
|
type MMap []byte
|
|
|
|
// Map maps an entire file into memory.
|
|
// If ANON is set in flags, f is ignored.
|
|
func Map(f *os.File, prot, flags int) (MMap, error) {
|
|
return MapRegion(f, -1, prot, flags, 0)
|
|
}
|
|
|
|
// MapRegion maps part of a file into memory.
|
|
// The offset parameter must be a multiple of the system's page size.
|
|
// If length < 0, the entire file will be mapped.
|
|
// If ANON is set in flags, f is ignored.
|
|
func MapRegion(f *os.File, length int, prot, flags int, offset int64) (MMap, error) {
|
|
if offset%int64(os.Getpagesize()) != 0 {
|
|
return nil, errors.New("offset parameter must be a multiple of the system's page size")
|
|
}
|
|
|
|
var fd uintptr
|
|
if flags&ANON == 0 {
|
|
fd = uintptr(f.Fd())
|
|
if length < 0 {
|
|
fi, err := f.Stat()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
length = int(fi.Size())
|
|
}
|
|
} else {
|
|
if length <= 0 {
|
|
return nil, errors.New("anonymous mapping requires non-zero length")
|
|
}
|
|
fd = ^uintptr(0)
|
|
}
|
|
return mmap(length, uintptr(prot), uintptr(flags), fd, offset)
|
|
}
|
|
|
|
func (m *MMap) header() *reflect.SliceHeader {
|
|
return (*reflect.SliceHeader)(unsafe.Pointer(m))
|
|
}
|
|
|
|
// Lock keeps the mapped region in physical memory, ensuring that it will not be
|
|
// swapped out.
|
|
func (m MMap) Lock() error {
|
|
dh := m.header()
|
|
return lock(dh.Data, uintptr(dh.Len))
|
|
}
|
|
|
|
// Unlock reverses the effect of Lock, allowing the mapped region to potentially
|
|
// be swapped out.
|
|
// If m is already unlocked, aan error will result.
|
|
func (m MMap) Unlock() error {
|
|
dh := m.header()
|
|
return unlock(dh.Data, uintptr(dh.Len))
|
|
}
|
|
|
|
// Flush synchronizes the mapping's contents to the file's contents on disk.
|
|
func (m MMap) Flush() error {
|
|
dh := m.header()
|
|
return flush(dh.Data, uintptr(dh.Len))
|
|
}
|
|
|
|
// Unmap deletes the memory mapped region, flushes any remaining changes, and sets
|
|
// m to nil.
|
|
// Trying to read or write any remaining references to m after Unmap is called will
|
|
// result in undefined behavior.
|
|
// Unmap should only be called on the slice value that was originally returned from
|
|
// a call to Map. Calling Unmap on a derived slice may cause errors.
|
|
func (m *MMap) Unmap() error {
|
|
dh := m.header()
|
|
err := unmap(dh.Data, uintptr(dh.Len))
|
|
*m = nil
|
|
return err
|
|
}
|