mirror of
https://github.com/K3vinb5/Unyo.git
synced 2026-06-13 05:49:42 +00:00
Update dependencies, finished video service and refactored logger to write to files
This commit is contained in:
16
ffigen.yaml
16
ffigen.yaml
@@ -1,16 +0,0 @@
|
||||
# Run with `flutter pub run ffigen --config ffigen.yaml`.
|
||||
name: TorrentLibrary
|
||||
description: Bindings to `lib/ffi/libmtorrentserver.h`.
|
||||
output: 'lib/ffi/generated_bindings.dart'
|
||||
headers:
|
||||
entry-points:
|
||||
- 'ffigen/libmtorrentserver.h'
|
||||
preamble: |
|
||||
// ignore_for_file: always_specify_types
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: unused_field
|
||||
// ignore_for_file: unused_element
|
||||
comments:
|
||||
style: any
|
||||
length: full
|
||||
@@ -1,87 +0,0 @@
|
||||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef size_t GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
#ifdef _MSC_VER
|
||||
#include <complex.h>
|
||||
typedef _Fcomplex GoComplex64;
|
||||
typedef _Dcomplex GoComplex128;
|
||||
#else
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
#endif
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Return type for Start */
|
||||
struct Start_return {
|
||||
GoInt r0;
|
||||
char* r1;
|
||||
};
|
||||
extern struct Start_return Start(char* mcfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"C"
|
||||
"encoding/json"
|
||||
"server"
|
||||
)
|
||||
|
||||
//export Start
|
||||
func Start(mcfg *C.char) (int, *C.char) {
|
||||
var config server.Config
|
||||
json.Unmarshal([]byte(C.GoString(mcfg)), &config)
|
||||
port, err := server.Start(&config)
|
||||
if err != nil {
|
||||
return 0, C.CString(err.Error())
|
||||
}
|
||||
return port, nil
|
||||
}
|
||||
|
||||
func main() {}
|
||||
94
go/go.mod
94
go/go.mod
@@ -1,94 +0,0 @@
|
||||
module server
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/anacrolix/torrent v1.56.1
|
||||
github.com/rs/cors v1.11.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/RoaringBitmap/roaring v1.9.4 // indirect
|
||||
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 // indirect
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
|
||||
github.com/anacrolix/chansync v0.5.1 // indirect
|
||||
github.com/anacrolix/dht/v2 v2.21.1 // indirect
|
||||
github.com/anacrolix/envpprof v1.3.0 // indirect
|
||||
github.com/anacrolix/generics v0.0.2 // indirect
|
||||
github.com/anacrolix/go-libutp v1.3.1 // indirect
|
||||
github.com/anacrolix/log v0.15.2 // indirect
|
||||
github.com/anacrolix/missinggo v1.3.0 // indirect
|
||||
github.com/anacrolix/missinggo/perf v1.0.0 // indirect
|
||||
github.com/anacrolix/missinggo/v2 v2.7.3 // indirect
|
||||
github.com/anacrolix/mmsg v1.0.0 // indirect
|
||||
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7 // indirect
|
||||
github.com/anacrolix/stm v0.5.0 // indirect
|
||||
github.com/anacrolix/sync v0.5.1 // indirect
|
||||
github.com/anacrolix/upnp v0.1.4 // indirect
|
||||
github.com/anacrolix/utp v0.2.0 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/benbjohnson/immutable v0.4.3 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.14.2 // indirect
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.1.0 // indirect
|
||||
github.com/go-llsqlite/adapter v0.1.0 // indirect
|
||||
github.com/go-llsqlite/crawshaw v0.5.5 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/multiformats/go-multihash v0.2.3 // indirect
|
||||
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/pion/datachannel v1.5.9 // indirect
|
||||
github.com/pion/dtls/v2 v2.2.12 // indirect
|
||||
github.com/pion/ice/v2 v2.3.34 // indirect
|
||||
github.com/pion/interceptor v0.1.30 // indirect
|
||||
github.com/pion/logging v0.2.2 // indirect
|
||||
github.com/pion/mdns v0.0.12 // indirect
|
||||
github.com/pion/randutil v0.1.0 // indirect
|
||||
github.com/pion/rtcp v1.2.14 // indirect
|
||||
github.com/pion/rtp v1.8.9 // indirect
|
||||
github.com/pion/sctp v1.8.33 // indirect
|
||||
github.com/pion/sdp/v3 v3.0.9 // indirect
|
||||
github.com/pion/srtp/v2 v2.0.20 // indirect
|
||||
github.com/pion/stun v0.6.1 // indirect
|
||||
github.com/pion/transport/v2 v2.2.10 // indirect
|
||||
github.com/pion/turn/v2 v2.1.6 // indirect
|
||||
github.com/pion/webrtc/v3 v3.3.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/tidwall/btree v1.7.0 // indirect
|
||||
github.com/wlynxg/anet v0.0.4 // indirect
|
||||
go.etcd.io/bbolt v1.3.11 // indirect
|
||||
go.opentelemetry.io/otel v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.29.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/blake3 v1.3.0 // indirect
|
||||
modernc.org/libc v1.60.1 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.32.0 // indirect
|
||||
zombiezen.com/go/sqlite v1.3.0 // indirect
|
||||
)
|
||||
549
go/go.sum
549
go/go.sum
@@ -1,549 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk=
|
||||
crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4=
|
||||
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
|
||||
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
|
||||
github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ=
|
||||
github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0=
|
||||
github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0/go.mod h1:q37NoqncT41qKc048STsifIt69LfUJ8SrWWcz/yam5k=
|
||||
github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk=
|
||||
github.com/alecthomas/assert/v2 v2.0.0-alpha3/go.mod h1:+zD0lmDXTeQj7TgDgCt0ePWxb0hMC1G+PGTsTCv1B9o=
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8=
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2/go.mod h1:zD6QGEyw49HIq19caJDc2NMXAy8rNi9ROrxtMXATfyI=
|
||||
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
|
||||
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anacrolix/chansync v0.5.1 h1:j+R9DtotkXm40VFjZ8rJTSJkg2Gv1ldZt8kl96lyJJ0=
|
||||
github.com/anacrolix/chansync v0.5.1/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
|
||||
github.com/anacrolix/dht/v2 v2.21.1 h1:s1rKkfLLcmBHKv4v/mtMkIeHIEptzEFiB6xVu54+5/o=
|
||||
github.com/anacrolix/dht/v2 v2.21.1/go.mod h1:SDGC+sEs1pnO2sJGYuhvIis7T8749dDHNfcjtdH4e3g=
|
||||
github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/envpprof v1.1.0/go.mod h1:My7T5oSqVfEn4MD4Meczkw/f5lSIndGAKu/0SM/rkf4=
|
||||
github.com/anacrolix/envpprof v1.3.0 h1:WJt9bpuT7A/CDCxPOv/eeZqHWlle/Y0keJUvc6tcJDk=
|
||||
github.com/anacrolix/envpprof v1.3.0/go.mod h1:7QIG4CaX1uexQ3tqd5+BRa/9e2D02Wcertl6Yh0jCB0=
|
||||
github.com/anacrolix/generics v0.0.0-20230113004304-d6428d516633/go.mod h1:ff2rHB/joTV03aMSSn/AZNnaIpUw0h3njetGsaXcMy8=
|
||||
github.com/anacrolix/generics v0.0.2 h1:UbtD+KntUGxeGYMC4RwhsETieL9ixGdSptJQRhdy7No=
|
||||
github.com/anacrolix/generics v0.0.2/go.mod h1:ff2rHB/joTV03aMSSn/AZNnaIpUw0h3njetGsaXcMy8=
|
||||
github.com/anacrolix/go-libutp v1.3.1 h1:idJzreNLl+hNjGC3ZnUOjujEaryeOGgkwHLqSGoige0=
|
||||
github.com/anacrolix/go-libutp v1.3.1/go.mod h1:heF41EC8kN0qCLMokLBVkB8NXiLwx3t8R8810MTNI5o=
|
||||
github.com/anacrolix/log v0.3.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgwU9jwU=
|
||||
github.com/anacrolix/log v0.6.0/go.mod h1:lWvLTqzAnCWPJA08T2HCstZi0L1y2Wyvm3FJgwU9jwU=
|
||||
github.com/anacrolix/log v0.13.1/go.mod h1:D4+CvN8SnruK6zIFS/xPoRJmtvtnxs+CSfDQ+BFxZ68=
|
||||
github.com/anacrolix/log v0.14.2/go.mod h1:1OmJESOtxQGNMlUO5rcv96Vpp9mfMqXXbe2RdinFLdY=
|
||||
github.com/anacrolix/log v0.15.2 h1:LTSf5Wm6Q4GNWPFMBP7NPYV6UBVZzZLKckL+/Lj72Oo=
|
||||
github.com/anacrolix/log v0.15.2/go.mod h1:m0poRtlr41mriZlXBQ9SOVZ8yZBkLjOkDhd5Li5pITA=
|
||||
github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62 h1:P04VG6Td13FHMgS5ZBcJX23NPC/fiC4cp9bXwYujdYM=
|
||||
github.com/anacrolix/lsan v0.0.0-20211126052245-807000409a62/go.mod h1:66cFKPCO7Sl4vbFnAaSq7e4OXtdMhRSBagJGWgmpJbM=
|
||||
github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df/go.mod h1:kwGiTUTZ0+p4vAz3VbAI5a30t2YbvemcmspjKwrAz5s=
|
||||
github.com/anacrolix/missinggo v1.1.0/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo=
|
||||
github.com/anacrolix/missinggo v1.1.2-0.20190815015349-b888af804467/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo=
|
||||
github.com/anacrolix/missinggo v1.2.1/go.mod h1:J5cMhif8jPmFoC3+Uvob3OXXNIhOUikzMt+uUjeM21Y=
|
||||
github.com/anacrolix/missinggo v1.3.0 h1:06HlMsudotL7BAELRZs0yDZ4yVXsHXGi323QBjAVASw=
|
||||
github.com/anacrolix/missinggo v1.3.0/go.mod h1:bqHm8cE8xr+15uVfMG3BFui/TxyB6//H5fwlq/TeqMc=
|
||||
github.com/anacrolix/missinggo/perf v1.0.0 h1:7ZOGYziGEBytW49+KmYGTaNfnwUqP1HBsy6BqESAJVw=
|
||||
github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5urunoLS0Cbvb4V0uMQ=
|
||||
github.com/anacrolix/missinggo/v2 v2.2.0/go.mod h1:o0jgJoYOyaoYQ4E2ZMISVa9c88BbUBVQQW4QeRkNCGY=
|
||||
github.com/anacrolix/missinggo/v2 v2.5.1/go.mod h1:WEjqh2rmKECd0t1VhQkLGTdIWXO6f6NLjp5GlMZ+6FA=
|
||||
github.com/anacrolix/missinggo/v2 v2.7.3 h1:Ee//CmZBMadeNiYB/hHo9ly2PFOEZ4Fhsbnug3rDAIE=
|
||||
github.com/anacrolix/missinggo/v2 v2.7.3/go.mod h1:mIEtp9pgaXqt8VQ3NQxFOod/eQ1H0D1XsZzKUQfwtac=
|
||||
github.com/anacrolix/mmsg v0.0.0-20180515031531-a4a3ba1fc8bb/go.mod h1:x2/ErsYUmT77kezS63+wzZp8E3byYB0gzirM/WMBLfw=
|
||||
github.com/anacrolix/mmsg v1.0.0 h1:btC7YLjOn29aTUAExJiVUhQOuf/8rhm+/nWCMAnL3Hg=
|
||||
github.com/anacrolix/mmsg v1.0.0/go.mod h1:x8kRaJY/dCrY9Al0PEcj1mb/uFHwP6GCJ9fLl4thEPc=
|
||||
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7 h1:lOtCD+LzoD1g7bowhYJNR++uV+FyY5bTZXKwnPex9S8=
|
||||
github.com/anacrolix/multiless v0.3.1-0.20221221005021-2d12701f83f7/go.mod h1:zJv1JF9AqdZiHwxqPgjuOZDGWER6nyE48WBCi/OOrMM=
|
||||
github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
|
||||
github.com/anacrolix/stm v0.5.0 h1:9df1KBpttF0TzLgDq51Z+TEabZKMythqgx89f1FQJt8=
|
||||
github.com/anacrolix/stm v0.5.0/go.mod h1:MOwrSy+jCm8Y7HYfMAwPj7qWVu7XoVvjOiYwJmpeB/M=
|
||||
github.com/anacrolix/sync v0.0.0-20180808010631-44578de4e778/go.mod h1:s735Etp3joe/voe2sdaXLcqDdJSay1O0OPnM0ystjqk=
|
||||
github.com/anacrolix/sync v0.3.0/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
|
||||
github.com/anacrolix/sync v0.5.1 h1:FbGju6GqSjzVoTgcXTUKkF041lnZkG5P0C3T5RL3SGc=
|
||||
github.com/anacrolix/sync v0.5.1/go.mod h1:BbecHL6jDSExojhNtgTFSBcdGerzNc64tz3DCOj/I0g=
|
||||
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
|
||||
github.com/anacrolix/tagflag v1.0.0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
|
||||
github.com/anacrolix/tagflag v1.1.0/go.mod h1:Scxs9CV10NQatSmbyjqmqmeQNwGzlNe0CMUMIxqHIG8=
|
||||
github.com/anacrolix/torrent v1.56.1 h1:QeJMOP0NuhpQ5dATsOqEL0vUO85aPMNMGP2FACNt0Eg=
|
||||
github.com/anacrolix/torrent v1.56.1/go.mod h1:5DMHbeIM1TuC5wTQ99XieKKLiYZYz6iB2lyZpKZEr6w=
|
||||
github.com/anacrolix/upnp v0.1.4 h1:+2t2KA6QOhm/49zeNyeVwDu1ZYS9dB9wfxyVvh/wk7U=
|
||||
github.com/anacrolix/upnp v0.1.4/go.mod h1:Qyhbqo69gwNWvEk1xNTXsS5j7hMHef9hdr984+9fIic=
|
||||
github.com/anacrolix/utp v0.2.0 h1:65Cdmr6q9WSw2KsM+rtJFu7rqDzLl2bdysf4KlNPcFI=
|
||||
github.com/anacrolix/utp v0.2.0/go.mod h1:HGk4GYQw1O/3T1+yhqT/F6EcBd+AAwlo9dYErNy7mj8=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/benbjohnson/immutable v0.2.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI=
|
||||
github.com/benbjohnson/immutable v0.4.3 h1:GYHcksoJ9K6HyAUpGxwZURrbTkXA0Dh4otXGqbhdrjA=
|
||||
github.com/benbjohnson/immutable v0.4.3/go.mod h1:qJIKKSmdqz1tVzNtst1DZzvaqOU1onk1rc03IeM3Owk=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/bits-and-blooms/bitset v1.14.2 h1:YXVoyPndbdvcEVcseEovVfp0qjJp7S+i5+xgp/Nfbdc=
|
||||
github.com/bits-and-blooms/bitset v1.14.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 h1:GKTyiRCL6zVf5wWaqKnf+7Qs6GbEPfd4iMOitWzXJx8=
|
||||
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8/go.mod h1:spo1JLcs67NmW1aVLEgtA8Yy1elc+X8y5SRW1sFW4Og=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
|
||||
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
|
||||
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-llsqlite/adapter v0.1.0 h1:wGSQNsu/rtYeu/lqZNZQMjwUdEF3OW66xTLvsFwJQUw=
|
||||
github.com/go-llsqlite/adapter v0.1.0/go.mod h1:DADrR88ONKPPeSGjFp5iEN55Arx3fi2qXZeKCYDpbmU=
|
||||
github.com/go-llsqlite/crawshaw v0.5.5 h1:sXnRkiV26MBv++lbPbzp+ZzFcTqzVMxftO8yHyFvwUA=
|
||||
github.com/go-llsqlite/crawshaw v0.5.5/go.mod h1:/YJdV7uBQaYDE0fwe4z3wwJIZBJxdYzd38ICggWqtaE=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gortc/stun v1.20.0 h1:7FNyWwjRXVByBItBwpnsv6SZ08UzPfmByLjKmOnpb14=
|
||||
github.com/gortc/stun v1.20.0/go.mod h1:/XeODKxk0b1P5pYtdD/ZlOncR7+6XgU4zb9CzJIFJBs=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
|
||||
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
|
||||
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA=
|
||||
github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE=
|
||||
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
|
||||
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
|
||||
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
|
||||
github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM=
|
||||
github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ=
|
||||
github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA=
|
||||
github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc=
|
||||
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
|
||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||
github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
|
||||
github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
|
||||
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
|
||||
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
|
||||
github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
|
||||
github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
|
||||
github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
|
||||
github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk=
|
||||
github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
|
||||
github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw=
|
||||
github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM=
|
||||
github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
|
||||
github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
|
||||
github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk=
|
||||
github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
|
||||
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
|
||||
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
|
||||
github.com/pion/stun v1.17.3 h1:JioTPckDp7PdfoF1FYSz1/sOWrXimbjyfZzvg2QIinU=
|
||||
github.com/pion/stun v1.17.3/go.mod h1:4iy9kiYvpncdXoYYJoAvZ4YFybb4/gQmZxUNaU2680Y=
|
||||
github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA=
|
||||
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
|
||||
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
|
||||
github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
|
||||
github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q=
|
||||
github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=
|
||||
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
|
||||
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
|
||||
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
|
||||
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
|
||||
github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
|
||||
github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
|
||||
github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I=
|
||||
github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 h1:18kd+8ZUlt/ARXhljq+14TwAoKa61q6dX8jtwOf6DH8=
|
||||
github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI=
|
||||
github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||
github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw=
|
||||
github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
|
||||
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
|
||||
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
|
||||
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
|
||||
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
|
||||
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
|
||||
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
|
||||
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
|
||||
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4=
|
||||
modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M=
|
||||
modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/libc v1.60.1 h1:at373l8IFRTkJIkAU85BIuUoBM4T1b51ds0E1ovPG2s=
|
||||
modernc.org/libc v1.60.1/go.mod h1:xJuobKuNxKH3RUatS7GjR+suWj+5c2K7bi4m/S5arOY=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s=
|
||||
modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
zombiezen.com/go/sqlite v1.3.0 h1:98g1gnCm+CNz6AuQHu0gqyw7gR2WU3O3PJufDOStpUs=
|
||||
zombiezen.com/go/sqlite v1.3.0/go.mod h1:yRl27//s/9aXU3RWs8uFQwjkTG9gYNGEls6+6SvrclY=
|
||||
531
go/server.go
531
go/server.go
@@ -1,531 +0,0 @@
|
||||
package server
|
||||
|
||||
//credits: https://github.com/glblduh/StreamRest
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
var torrentCli *torrent.Client
|
||||
var torrentcliCfg *torrent.ClientConfig
|
||||
|
||||
func Start(config *Config) (int, error) {
|
||||
|
||||
torrentcliCfg = torrent.NewDefaultClientConfig()
|
||||
|
||||
torrentcliCfg.DataDir = filepath.Clean(config.Path)
|
||||
|
||||
log.Printf("[INFO] Download directory is set to: %s\n", torrentcliCfg.DataDir)
|
||||
|
||||
var torrentCliErr error
|
||||
torrentCli, torrentCliErr = torrent.NewClient(torrentcliCfg)
|
||||
if torrentCliErr != nil {
|
||||
log.Fatalf("[ERROR] Creation of BitTorrent client failed: %s\n", torrentCliErr)
|
||||
}
|
||||
|
||||
dnsResolve()
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigs
|
||||
log.Println("[INFO] Termination detected. Removing torrents")
|
||||
for _, t := range torrentCli.Torrents() {
|
||||
log.Printf("[INFO] Removing torrent: [%s]\n", t.Name())
|
||||
t.Drop()
|
||||
rmaErr := os.RemoveAll(filepath.Join(torrentcliCfg.DataDir, t.Name()))
|
||||
if rmaErr != nil {
|
||||
log.Printf("[ERROR] Failed to remove files of torrent: [%s]: %s\n", t.Name(), rmaErr)
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/torrent/addmagnet", addMagnet)
|
||||
mux.HandleFunc("/torrent/stream", streamTorrent)
|
||||
mux.HandleFunc("/torrent/remove", removeTorrent)
|
||||
mux.HandleFunc("/torrent/torrents", listTorrents)
|
||||
mux.HandleFunc("/torrent/play", playTorrent)
|
||||
mux.HandleFunc("/torrent/add", AddTorrent)
|
||||
mux.HandleFunc("/", Init)
|
||||
|
||||
c := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"*"},
|
||||
AllowedMethods: []string{"GET", "POST", "DELETE"},
|
||||
AllowCredentials: true,
|
||||
})
|
||||
|
||||
listener, err := net.Listen("tcp", config.Address)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
addr := listener.Addr().(*net.TCPAddr)
|
||||
|
||||
log.Printf("[INFO] Listening on %s\n", addr.AddrPort())
|
||||
|
||||
go func() {
|
||||
if err := http.Serve(listener, c.Handler(mux)); err != nil && err != http.ErrServerClosed {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
return addr.Port, nil
|
||||
}
|
||||
|
||||
func safenDisplayPath(displayPath string) string {
|
||||
fileNameArray := strings.Split(displayPath, "/")
|
||||
return strings.Join(fileNameArray, " ")
|
||||
}
|
||||
|
||||
func appendFilePlaylist(scheme string, host string, infohash string, name string) string {
|
||||
playList := "#EXTINF:-1," + safenDisplayPath(name) + "\n"
|
||||
playList += scheme + "://" + host + "/torrent/stream?infohash=" + infohash + "&file=" + url.QueryEscape(name) + "\n"
|
||||
return playList
|
||||
}
|
||||
|
||||
func nameCheck(str string, substr string) bool {
|
||||
splittedSubStr := strings.Split(substr, " ")
|
||||
for _, curWord := range splittedSubStr {
|
||||
if !strings.Contains(str, curWord) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getTorrentFile(files []*torrent.File, filename string, exactName bool) *torrent.File {
|
||||
var tFile *torrent.File = nil
|
||||
for _, file := range files {
|
||||
if exactName && file.DisplayPath() == filename {
|
||||
tFile = file
|
||||
}
|
||||
if !exactName && filename != "" && nameCheck(strings.ToLower(file.DisplayPath()), strings.ToLower(filename)) {
|
||||
tFile = file
|
||||
}
|
||||
if tFile != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return tFile
|
||||
}
|
||||
|
||||
// https://github.com/YouROK/TorrServer/blob/681fc5c343f6d2782dee0c015d2ba2dfd210f88f/server/cmd/main.go#L114
|
||||
func dnsResolve() {
|
||||
addrs, err := net.LookupHost("www.google.com")
|
||||
if len(addrs) == 0 {
|
||||
log.Printf("Check dns failed", addrs, err)
|
||||
|
||||
fn := func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
d := net.Dialer{}
|
||||
return d.DialContext(ctx, "udp", "1.1.1.1:53")
|
||||
}
|
||||
|
||||
net.DefaultResolver = &net.Resolver{
|
||||
Dial: fn,
|
||||
}
|
||||
|
||||
addrs, err = net.LookupHost("www.google.com")
|
||||
log.Printf("Check cloudflare dns", addrs, err)
|
||||
} else {
|
||||
log.Printf("Check dns OK", addrs, err)
|
||||
}
|
||||
}
|
||||
|
||||
func makePlayStreamURL(infohash string, filename string, isStream bool) string {
|
||||
endPoint := "play"
|
||||
if isStream {
|
||||
endPoint = "stream"
|
||||
}
|
||||
URL := "/torrent/" + endPoint + "?infohash=" + infohash
|
||||
if filename != "" {
|
||||
URL += "&file=" + url.QueryEscape(filename)
|
||||
}
|
||||
return URL
|
||||
}
|
||||
|
||||
func httpJSONError(w http.ResponseWriter, error string, code int) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(code)
|
||||
if json.NewEncoder(w).Encode(errorRes{
|
||||
Error: error,
|
||||
}) != nil {
|
||||
http.Error(w, error, code)
|
||||
}
|
||||
}
|
||||
|
||||
func parseRequestBody(w http.ResponseWriter, r *http.Request, v any) error {
|
||||
err := json.NewDecoder(r.Body).Decode(v)
|
||||
if err != nil {
|
||||
httpJSONError(w, "Request JSON body decode error", http.StatusInternalServerError)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func makeJSONResponse(w http.ResponseWriter, v any) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(v)
|
||||
if err != nil {
|
||||
httpJSONError(w, "Response JSON body encode error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func getInfo(t *torrent.Torrent) {
|
||||
if t != nil {
|
||||
<-t.GotInfo()
|
||||
}
|
||||
}
|
||||
|
||||
func initMagnet(w http.ResponseWriter, magnet string, alldn []string, alltr []string) *torrent.Torrent {
|
||||
var t *torrent.Torrent = nil
|
||||
var err error
|
||||
magnetString := magnet
|
||||
for _, dn := range alldn {
|
||||
magnetString += "&dn=" + url.QueryEscape(dn)
|
||||
}
|
||||
for _, tr := range alltr {
|
||||
magnetString += "&tr=" + url.QueryEscape(tr)
|
||||
}
|
||||
t, err = torrentCli.AddMagnet(magnetString)
|
||||
if err != nil {
|
||||
httpJSONError(w, "Torrent add error", http.StatusInternalServerError)
|
||||
}
|
||||
getInfo(t)
|
||||
return t
|
||||
}
|
||||
|
||||
func getTorrent(w http.ResponseWriter, infoHash string) *torrent.Torrent {
|
||||
var t *torrent.Torrent = nil
|
||||
var tOk bool
|
||||
if len(infoHash) != 40 {
|
||||
httpJSONError(w, "InfoHash not valid", http.StatusInternalServerError)
|
||||
return t
|
||||
}
|
||||
t, tOk = torrentCli.Torrent(metainfo.NewHashFromHex(infoHash))
|
||||
if !tOk {
|
||||
httpJSONError(w, "Torrent not found", http.StatusNotFound)
|
||||
}
|
||||
getInfo(t)
|
||||
return t
|
||||
}
|
||||
|
||||
func parseTorrentStats(t *torrent.Torrent) torrentStatsRes {
|
||||
var tsRes torrentStatsRes
|
||||
|
||||
tsRes.InfoHash = t.InfoHash().String()
|
||||
tsRes.Name = t.Name()
|
||||
tsRes.TotalPeers = t.Stats().TotalPeers
|
||||
tsRes.ActivePeers = t.Stats().ActivePeers
|
||||
tsRes.HalfOpenPeers = t.Stats().HalfOpenPeers
|
||||
tsRes.PendingPeers = t.Stats().PendingPeers
|
||||
|
||||
if t.Info() == nil {
|
||||
return tsRes
|
||||
}
|
||||
|
||||
for _, tFile := range t.Files() {
|
||||
tsRes.Files.OnTorrent = append(tsRes.Files.OnTorrent, torrentStatsFilesOnTorrent{
|
||||
FileName: tFile.DisplayPath(),
|
||||
FileSizeBytes: int(tFile.Length()),
|
||||
})
|
||||
if tFile.BytesCompleted() != 0 {
|
||||
tsRes.Files.OnDisk = append(tsRes.Files.OnDisk, torrentStatsFilesOnDisk{
|
||||
FileName: tFile.DisplayPath(),
|
||||
StreamURL: makePlayStreamURL(t.InfoHash().String(), tFile.DisplayPath(), true),
|
||||
BytesDownloaded: int(tFile.BytesCompleted()),
|
||||
FileSizeBytes: int(tFile.Length()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return tsRes
|
||||
}
|
||||
|
||||
func addMagnet(w http.ResponseWriter, r *http.Request) {
|
||||
var amBody addMagnetBody
|
||||
var amRes addMagnetRes
|
||||
|
||||
if parseRequestBody(w, r, &amBody) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if amBody.Magnet == "" {
|
||||
httpJSONError(w, "Magnet link is not provided", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
t := initMagnet(w, amBody.Magnet, []string{}, []string{})
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
|
||||
amRes.InfoHash = t.InfoHash().String()
|
||||
amRes.Name = t.Name()
|
||||
|
||||
if amBody.AllFiles {
|
||||
amRes.PlaylistURL = makePlayStreamURL(t.InfoHash().String(), "", false)
|
||||
for _, tFile := range t.Files() {
|
||||
amRes.Files = append(amRes.Files, addMagnetFiles{
|
||||
FileName: tFile.DisplayPath(),
|
||||
StreamURL: makePlayStreamURL(t.InfoHash().String(), tFile.DisplayPath(), true),
|
||||
FileSizeBytes: int(tFile.Length()),
|
||||
})
|
||||
}
|
||||
makeJSONResponse(w, &amRes)
|
||||
return
|
||||
}
|
||||
|
||||
if len(amBody.Files) > 0 {
|
||||
amRes.PlaylistURL = makePlayStreamURL(t.InfoHash().String(), "", false)
|
||||
for _, selFile := range amBody.Files {
|
||||
tFile := getTorrentFile(t.Files(), selFile, false)
|
||||
if tFile == nil {
|
||||
continue
|
||||
}
|
||||
amRes.PlaylistURL += "&file=" + url.QueryEscape(tFile.DisplayPath())
|
||||
amRes.Files = append(amRes.Files, addMagnetFiles{
|
||||
FileName: tFile.DisplayPath(),
|
||||
StreamURL: makePlayStreamURL(t.InfoHash().String(), tFile.DisplayPath(), true),
|
||||
FileSizeBytes: int(tFile.Length()),
|
||||
})
|
||||
}
|
||||
makeJSONResponse(w, &amRes)
|
||||
return
|
||||
}
|
||||
|
||||
for _, tFile := range t.Files() {
|
||||
amRes.Files = append(amRes.Files, addMagnetFiles{
|
||||
FileName: tFile.DisplayPath(),
|
||||
FileSizeBytes: int(tFile.Length()),
|
||||
})
|
||||
}
|
||||
makeJSONResponse(w, &amRes)
|
||||
}
|
||||
|
||||
func streamTorrent(w http.ResponseWriter, r *http.Request) {
|
||||
infoHash, ihOk := r.URL.Query()["infohash"]
|
||||
fileName, fnOk := r.URL.Query()["file"]
|
||||
|
||||
if !ihOk || !fnOk {
|
||||
httpJSONError(w, "InfoHash or File is not provided", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
t := getTorrent(w, infoHash[0])
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
|
||||
tFile := getTorrentFile(t.Files(), fileName[0], true)
|
||||
if tFile == nil {
|
||||
httpJSONError(w, "File not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
fileRead := tFile.NewReader()
|
||||
defer fileRead.Close()
|
||||
fileRead.SetReadahead(tFile.Length() / 100)
|
||||
http.ServeContent(w, r, tFile.DisplayPath(), time.Now(), fileRead)
|
||||
}
|
||||
|
||||
func removeTorrent(w http.ResponseWriter, r *http.Request) {
|
||||
infoHash, ihOk := r.URL.Query()["infohash"]
|
||||
if !ihOk {
|
||||
httpJSONError(w, "InfoHash is not provided", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
t := getTorrent(w, infoHash[0])
|
||||
if t == nil {
|
||||
httpJSONError(w, "Torrent not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
t.Drop()
|
||||
|
||||
if os.RemoveAll(filepath.Join(torrentcliCfg.DataDir, t.Name())) != nil {
|
||||
|
||||
httpJSONError(w, "ERROR WHEN REMOVING FILE", http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func listTorrents(w http.ResponseWriter, r *http.Request) {
|
||||
infoHash, ihOk := r.URL.Query()["infohash"]
|
||||
var ltRes listTorrentsRes
|
||||
|
||||
allTorrents := torrentCli.Torrents()
|
||||
|
||||
if ihOk {
|
||||
allTorrents = nil
|
||||
t := getTorrent(w, infoHash[0])
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
allTorrents = append(allTorrents, t)
|
||||
}
|
||||
|
||||
for _, t := range allTorrents {
|
||||
ltRes.Torrents = append(ltRes.Torrents, parseTorrentStats(t))
|
||||
}
|
||||
|
||||
if !ihOk && len(ltRes.Torrents) < 1 {
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
|
||||
makeJSONResponse(w, <Res)
|
||||
}
|
||||
|
||||
func AddTorrent(w http.ResponseWriter, request *http.Request) {
|
||||
|
||||
a, _, error := request.FormFile("file")
|
||||
if error != nil {
|
||||
log.Printf("error upload torrent")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
metainf, er_ := metainfo.Load(a)
|
||||
if er_ != nil {
|
||||
log.Printf("error error when loading MetaInfo")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
torrent, err := torrentCli.AddTorrent(metainf)
|
||||
if err != nil {
|
||||
log.Print(err.Error())
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(torrent.InfoHash().HexString()))
|
||||
|
||||
}
|
||||
func Init(w http.ResponseWriter, request *http.Request) {
|
||||
|
||||
w.Write([]byte("Torrent server is running"))
|
||||
|
||||
}
|
||||
|
||||
func playTorrent(w http.ResponseWriter, r *http.Request) {
|
||||
infoHash, ihOk := r.URL.Query()["infohash"]
|
||||
magnet, magOk := r.URL.Query()["magnet"]
|
||||
displayName := r.URL.Query()["dn"]
|
||||
trackers := r.URL.Query()["tr"]
|
||||
files, fOk := r.URL.Query()["file"]
|
||||
|
||||
if !magOk && !ihOk {
|
||||
httpJSONError(w, "Magnet link or InfoHash is not provided", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
var t *torrent.Torrent
|
||||
if magOk && !ihOk {
|
||||
t = initMagnet(w, magnet[0], displayName, trackers)
|
||||
}
|
||||
|
||||
if ihOk && !magOk {
|
||||
t = getTorrent(w, infoHash[0])
|
||||
}
|
||||
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=\""+t.InfoHash().String()+".m3u\"")
|
||||
playList := "#EXTM3U\n"
|
||||
|
||||
httpScheme := "http"
|
||||
if r.Header.Get("X-Forwarded-Proto") != "" {
|
||||
httpScheme = r.Header.Get("X-Forwarded-Proto")
|
||||
}
|
||||
|
||||
if !fOk {
|
||||
for _, tFile := range t.Files() {
|
||||
playList += appendFilePlaylist(httpScheme, r.Host, t.InfoHash().String(), tFile.DisplayPath())
|
||||
}
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
tFile := getTorrentFile(t.Files(), file, false)
|
||||
if tFile == nil {
|
||||
continue
|
||||
}
|
||||
playList += appendFilePlaylist(httpScheme, r.Host, t.InfoHash().String(), tFile.DisplayPath())
|
||||
}
|
||||
|
||||
w.Write([]byte(playList))
|
||||
}
|
||||
|
||||
type errorRes struct {
|
||||
Error string
|
||||
}
|
||||
|
||||
type addMagnetBody struct {
|
||||
Magnet string
|
||||
AllFiles bool
|
||||
Files []string
|
||||
}
|
||||
|
||||
type addMagnetRes struct {
|
||||
InfoHash string
|
||||
Name string
|
||||
PlaylistURL string
|
||||
Files []addMagnetFiles
|
||||
}
|
||||
|
||||
type addMagnetFiles struct {
|
||||
FileName string
|
||||
StreamURL string
|
||||
FileSizeBytes int
|
||||
}
|
||||
|
||||
type listTorrentsRes struct {
|
||||
Torrents []torrentStatsRes
|
||||
}
|
||||
|
||||
type torrentStatsRes struct {
|
||||
InfoHash string
|
||||
Name string
|
||||
TotalPeers int
|
||||
ActivePeers int
|
||||
PendingPeers int
|
||||
HalfOpenPeers int
|
||||
Files torrentStatsFiles
|
||||
}
|
||||
|
||||
type torrentStatsFiles struct {
|
||||
OnTorrent []torrentStatsFilesOnTorrent
|
||||
OnDisk []torrentStatsFilesOnDisk
|
||||
}
|
||||
|
||||
type torrentStatsFilesOnTorrent struct {
|
||||
FileName string
|
||||
FileSizeBytes int
|
||||
}
|
||||
|
||||
type torrentStatsFilesOnDisk struct {
|
||||
FileName string
|
||||
StreamURL string
|
||||
BytesDownloaded int
|
||||
FileSizeBytes int
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Address string `json:"address"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import 'package:unyo/domain/entities/anime.dart';
|
||||
import 'package:unyo/domain/entities/anime_details.dart';
|
||||
import 'package:unyo/domain/entities/episode_info.dart';
|
||||
import 'package:unyo/domain/entities/extension.dart';
|
||||
import 'package:unyo/domain/entities/extension/video.dart' as ext;
|
||||
import 'package:unyo/domain/entities/media_list.dart';
|
||||
import 'package:unyo/domain/entities/media_list_entry.dart';
|
||||
import 'package:unyo/domain/entities/settings.dart';
|
||||
@@ -521,7 +522,7 @@ class AnimeDetailsCubit extends Cubit<AnimeDetailsState> with EffectMixin<AnimeD
|
||||
selectedExtension,
|
||||
);
|
||||
if (videoResults.isNotEmpty) {
|
||||
emit(state.copyWith(extensionVideoResults: videoResults));
|
||||
emit(state.copyWith(extensionVideoResults: videoResults.map((jVideo) => ext.Video.fromJVideo(jVideo)).toList()));
|
||||
return true;
|
||||
} else {
|
||||
showSnackBarEffect(
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:logger/logger.dart';
|
||||
import 'package:unyo/application/cubits/effect_mixin.dart';
|
||||
import 'package:unyo/application/effects/app_effects.dart';
|
||||
import 'package:unyo/application/states/tabs_state.dart';
|
||||
import 'package:unyo/core/di/locator.dart';
|
||||
import 'package:unyo/core/enums/selected_menu_option.dart';
|
||||
import 'package:unyo/core/notification/menu_bar_notifier.dart';
|
||||
import 'package:unyo/core/notification/user_notifier.dart';
|
||||
@@ -15,7 +16,7 @@ class TabsCubit extends Cubit<TabsState>
|
||||
with EffectMixin<TabsState> {
|
||||
final UserNotifier _loggedUserNotifier;
|
||||
final MenuBarNotifier _menuBarNotifier;
|
||||
final Logger _logger = Logger();
|
||||
final Logger _logger = sl<Logger>();
|
||||
late StreamSubscription<User> _newLoggedUserSubscription;
|
||||
late StreamSubscription<bool> _showMenuBarSubscription;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jsanime.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jsepisode.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jvideo.dart';
|
||||
import 'package:unyo/application/cubits/effect_mixin.dart';
|
||||
import 'package:unyo/application/effects/app_effects.dart';
|
||||
import 'package:unyo/domain/entities/anime.dart';
|
||||
import 'package:unyo/domain/entities/episode_info.dart';
|
||||
import 'package:unyo/domain/entities/extension.dart';
|
||||
import 'package:unyo/domain/entities/extension/video.dart' as ext;
|
||||
import 'package:unyo/domain/entities/media_character.dart';
|
||||
import 'package:unyo/domain/entities/media_list.dart';
|
||||
import 'package:unyo/domain/entities/media_list_entry.dart';
|
||||
@@ -34,7 +34,7 @@ abstract class AnimeDetailsState with _$AnimeDetailsState implements HasEffects{
|
||||
// voice actors
|
||||
required List<JSAnime> extensionAnimeResults,
|
||||
required List<JSEpisode> extensionEpisodeResults,
|
||||
required List<JVideo> extensionVideoResults,
|
||||
required List<ext.Video> extensionVideoResults,
|
||||
@Default(<AppEffect>[]) List<AppEffect> effects,
|
||||
}) = _AnimeDetailsState;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ mixin _$AnimeDetailsState {
|
||||
|
||||
User get loggedUser; MediaList get selectedMediaList; Anime get selectedAnime; MediaListEntry get mediaListEntry; (bool, List<MediaCharacter>) get characters; (bool, List<Anime>) get recommendations; List<EpisodeInfo> get episodesInfo; List<String> get banners; String get alternateImage; Set<Extension> get installedExtensions; bool get userLoaded; bool get animeServerDialogReady; Extension? get selectedExtension;// relations
|
||||
// voice actors
|
||||
List<JSAnime> get extensionAnimeResults; List<JSEpisode> get extensionEpisodeResults; List<JVideo> get extensionVideoResults; List<AppEffect> get effects;
|
||||
List<JSAnime> get extensionAnimeResults; List<JSEpisode> get extensionEpisodeResults; List<ext.Video> get extensionVideoResults; List<AppEffect> get effects;
|
||||
/// Create a copy of AnimeDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -47,7 +47,7 @@ abstract mixin class $AnimeDetailsStateCopyWith<$Res> {
|
||||
factory $AnimeDetailsStateCopyWith(AnimeDetailsState value, $Res Function(AnimeDetailsState) _then) = _$AnimeDetailsStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<JVideo> extensionVideoResults, List<AppEffect> effects
|
||||
User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<ext.Video> extensionVideoResults, List<AppEffect> effects
|
||||
});
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ as bool,selectedExtension: freezed == selectedExtension ? _self.selectedExtensio
|
||||
as Extension?,extensionAnimeResults: null == extensionAnimeResults ? _self.extensionAnimeResults : extensionAnimeResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<JSAnime>,extensionEpisodeResults: null == extensionEpisodeResults ? _self.extensionEpisodeResults : extensionEpisodeResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<JSEpisode>,extensionVideoResults: null == extensionVideoResults ? _self.extensionVideoResults : extensionVideoResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<JVideo>,effects: null == effects ? _self.effects : effects // ignore: cast_nullable_to_non_nullable
|
||||
as List<ext.Video>,effects: null == effects ? _self.effects : effects // ignore: cast_nullable_to_non_nullable
|
||||
as List<AppEffect>,
|
||||
));
|
||||
}
|
||||
@@ -168,7 +168,7 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<JVideo> extensionVideoResults, List<AppEffect> effects)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<ext.Video> extensionVideoResults, List<AppEffect> effects)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeDetailsState() when $default != null:
|
||||
return $default(_that.loggedUser,_that.selectedMediaList,_that.selectedAnime,_that.mediaListEntry,_that.characters,_that.recommendations,_that.episodesInfo,_that.banners,_that.alternateImage,_that.installedExtensions,_that.userLoaded,_that.animeServerDialogReady,_that.selectedExtension,_that.extensionAnimeResults,_that.extensionEpisodeResults,_that.extensionVideoResults,_that.effects);case _:
|
||||
@@ -189,7 +189,7 @@ return $default(_that.loggedUser,_that.selectedMediaList,_that.selectedAnime,_th
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<JVideo> extensionVideoResults, List<AppEffect> effects) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<ext.Video> extensionVideoResults, List<AppEffect> effects) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeDetailsState():
|
||||
return $default(_that.loggedUser,_that.selectedMediaList,_that.selectedAnime,_that.mediaListEntry,_that.characters,_that.recommendations,_that.episodesInfo,_that.banners,_that.alternateImage,_that.installedExtensions,_that.userLoaded,_that.animeServerDialogReady,_that.selectedExtension,_that.extensionAnimeResults,_that.extensionEpisodeResults,_that.extensionVideoResults,_that.effects);case _:
|
||||
@@ -209,7 +209,7 @@ return $default(_that.loggedUser,_that.selectedMediaList,_that.selectedAnime,_th
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<JVideo> extensionVideoResults, List<AppEffect> effects)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<ext.Video> extensionVideoResults, List<AppEffect> effects)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeDetailsState() when $default != null:
|
||||
return $default(_that.loggedUser,_that.selectedMediaList,_that.selectedAnime,_that.mediaListEntry,_that.characters,_that.recommendations,_that.episodesInfo,_that.banners,_that.alternateImage,_that.installedExtensions,_that.userLoaded,_that.animeServerDialogReady,_that.selectedExtension,_that.extensionAnimeResults,_that.extensionEpisodeResults,_that.extensionVideoResults,_that.effects);case _:
|
||||
@@ -224,7 +224,7 @@ return $default(_that.loggedUser,_that.selectedMediaList,_that.selectedAnime,_th
|
||||
|
||||
|
||||
class _AnimeDetailsState extends AnimeDetailsState {
|
||||
const _AnimeDetailsState({required this.loggedUser, required this.selectedMediaList, required this.selectedAnime, required this.mediaListEntry, required this.characters, required this.recommendations, required final List<EpisodeInfo> episodesInfo, required final List<String> banners, required this.alternateImage, required final Set<Extension> installedExtensions, required this.userLoaded, required this.animeServerDialogReady, required this.selectedExtension, required final List<JSAnime> extensionAnimeResults, required final List<JSEpisode> extensionEpisodeResults, required final List<JVideo> extensionVideoResults, final List<AppEffect> effects = const <AppEffect>[]}): _episodesInfo = episodesInfo,_banners = banners,_installedExtensions = installedExtensions,_extensionAnimeResults = extensionAnimeResults,_extensionEpisodeResults = extensionEpisodeResults,_extensionVideoResults = extensionVideoResults,_effects = effects,super._();
|
||||
const _AnimeDetailsState({required this.loggedUser, required this.selectedMediaList, required this.selectedAnime, required this.mediaListEntry, required this.characters, required this.recommendations, required final List<EpisodeInfo> episodesInfo, required final List<String> banners, required this.alternateImage, required final Set<Extension> installedExtensions, required this.userLoaded, required this.animeServerDialogReady, required this.selectedExtension, required final List<JSAnime> extensionAnimeResults, required final List<JSEpisode> extensionEpisodeResults, required final List<ext.Video> extensionVideoResults, final List<AppEffect> effects = const <AppEffect>[]}): _episodesInfo = episodesInfo,_banners = banners,_installedExtensions = installedExtensions,_extensionAnimeResults = extensionAnimeResults,_extensionEpisodeResults = extensionEpisodeResults,_extensionVideoResults = extensionVideoResults,_effects = effects,super._();
|
||||
|
||||
|
||||
@override final User loggedUser;
|
||||
@@ -276,8 +276,8 @@ class _AnimeDetailsState extends AnimeDetailsState {
|
||||
return EqualUnmodifiableListView(_extensionEpisodeResults);
|
||||
}
|
||||
|
||||
final List<JVideo> _extensionVideoResults;
|
||||
@override List<JVideo> get extensionVideoResults {
|
||||
final List<ext.Video> _extensionVideoResults;
|
||||
@override List<ext.Video> get extensionVideoResults {
|
||||
if (_extensionVideoResults is EqualUnmodifiableListView) return _extensionVideoResults;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_extensionVideoResults);
|
||||
@@ -321,7 +321,7 @@ abstract mixin class _$AnimeDetailsStateCopyWith<$Res> implements $AnimeDetailsS
|
||||
factory _$AnimeDetailsStateCopyWith(_AnimeDetailsState value, $Res Function(_AnimeDetailsState) _then) = __$AnimeDetailsStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<JVideo> extensionVideoResults, List<AppEffect> effects
|
||||
User loggedUser, MediaList selectedMediaList, Anime selectedAnime, MediaListEntry mediaListEntry, (bool, List<MediaCharacter>) characters, (bool, List<Anime>) recommendations, List<EpisodeInfo> episodesInfo, List<String> banners, String alternateImage, Set<Extension> installedExtensions, bool userLoaded, bool animeServerDialogReady, Extension? selectedExtension, List<JSAnime> extensionAnimeResults, List<JSEpisode> extensionEpisodeResults, List<ext.Video> extensionVideoResults, List<AppEffect> effects
|
||||
});
|
||||
|
||||
|
||||
@@ -356,7 +356,7 @@ as bool,selectedExtension: freezed == selectedExtension ? _self.selectedExtensio
|
||||
as Extension?,extensionAnimeResults: null == extensionAnimeResults ? _self._extensionAnimeResults : extensionAnimeResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<JSAnime>,extensionEpisodeResults: null == extensionEpisodeResults ? _self._extensionEpisodeResults : extensionEpisodeResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<JSEpisode>,extensionVideoResults: null == extensionVideoResults ? _self._extensionVideoResults : extensionVideoResults // ignore: cast_nullable_to_non_nullable
|
||||
as List<JVideo>,effects: null == effects ? _self._effects : effects // ignore: cast_nullable_to_non_nullable
|
||||
as List<ext.Video>,effects: null == effects ? _self._effects : effects // ignore: cast_nullable_to_non_nullable
|
||||
as List<AppEffect>,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -42,10 +42,14 @@ import 'package:unyo/application/cubits/home_cubit.dart';
|
||||
|
||||
final sl = GetIt.instance;
|
||||
|
||||
void setupLocator() {
|
||||
void setupLocator() async{
|
||||
// Singletons
|
||||
sl.registerLazySingleton<Logger>(() => getLogger());
|
||||
|
||||
sl.registerSingletonAsync<Directory>(
|
||||
() => getApplicationSupportDirectory(),
|
||||
instanceName: config.applicationSupportDirectory,
|
||||
);
|
||||
await sl.isReady<Directory>(instanceName: config.applicationSupportDirectory);
|
||||
sl.registerSingleton<Logger>(getLogger());
|
||||
// Services
|
||||
sl.registerLazySingleton<HttpService>(() => HttpService());
|
||||
sl.registerLazySingleton<GraphQLService>(
|
||||
@@ -55,10 +59,6 @@ void setupLocator() {
|
||||
sl.registerLazySingleton<AppEffectHandler>(() => AppEffectHandler());
|
||||
sl.registerSingleton<ThemeService>(ThemeService());
|
||||
sl.registerLazySingleton<ColorImageService>(() => ColorImageService());
|
||||
sl.registerLazySingletonAsync<Directory>(
|
||||
() => getApplicationSupportDirectory(),
|
||||
instanceName: config.applicationSupportDirectory,
|
||||
);
|
||||
sl.registerSingleton<AniyomiBridge>(AniyomiBridge());
|
||||
sl.registerSingleton<TorrentService>(TorrentService());
|
||||
// Notifiers
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:unyo/config/config.dart' as config;
|
||||
import 'package:unyo/core/di/locator.dart';
|
||||
|
||||
Logger getLogger() {
|
||||
Directory supportDirectory = sl<Directory>(instanceName: config.applicationSupportDirectory);
|
||||
File newLogFile = File('${supportDirectory.path}/logs/${DateTime.now().millisecondsSinceEpoch}.log');
|
||||
newLogFile.create(recursive: true);
|
||||
List<FileSystemEntity> logFiles = supportDirectory.listSync().where((file) => file.path.endsWith('.log')).toList();
|
||||
if (logFiles.length > 20) {
|
||||
logFiles.sort((a, b) => a.statSync().modified.compareTo(b.statSync().modified));
|
||||
for (int i = 0; i < logFiles.length - 20; i++) {
|
||||
logFiles[i].deleteSync();
|
||||
}
|
||||
}
|
||||
return Logger(
|
||||
printer: PrettyPrinter(methodCount: 20),
|
||||
printer: PrettyPrinter(methodCount: 15),
|
||||
level: Level.debug,
|
||||
// output: FileOutput(),
|
||||
output: MultiOutput([
|
||||
ConsoleOutput(),
|
||||
FileOutput(file: newLogFile, overrideExisting: true),
|
||||
]),
|
||||
filter: ProductionFilter(),
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class ApiResponse<T> {
|
||||
final T data;
|
||||
final Uint8List bodyBytes;
|
||||
final int statusCode;
|
||||
final Map<String, String> headers;
|
||||
|
||||
ApiResponse({
|
||||
required this.data,
|
||||
required this.bodyBytes,
|
||||
required this.statusCode,
|
||||
required this.headers,
|
||||
});
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:retry/retry.dart';
|
||||
// Internal dependencies
|
||||
import 'package:unyo/config/config.dart' as config;
|
||||
import 'package:unyo/core/di/locator.dart';
|
||||
import 'package:unyo/core/services/api/http/empty_api_response.dart';
|
||||
import 'api_response.dart';
|
||||
import 'http_exception.dart';
|
||||
|
||||
@@ -237,6 +236,7 @@ class HttpService {
|
||||
_logger.d("Response body is empty, returning empty ApiResponse");
|
||||
return ApiResponse(
|
||||
data: fromJson({}),
|
||||
bodyBytes: response.bodyBytes,
|
||||
statusCode: status,
|
||||
headers: response.headers,
|
||||
);
|
||||
@@ -245,6 +245,7 @@ class HttpService {
|
||||
final jsonList = json.decode(response.body) as List<dynamic>;
|
||||
return ApiResponse(
|
||||
data: fromJson({'list': jsonList}),
|
||||
bodyBytes: response.bodyBytes,
|
||||
statusCode: status,
|
||||
headers: response.headers
|
||||
);
|
||||
@@ -252,6 +253,7 @@ class HttpService {
|
||||
final jsonMap = json.decode(response.body) as Map<String, dynamic>;
|
||||
return ApiResponse(
|
||||
data: fromJson(jsonMap),
|
||||
bodyBytes: response.bodyBytes,
|
||||
statusCode: status,
|
||||
headers: response.headers,
|
||||
);
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:path/path.dart' as path;
|
||||
import 'package:unyo/config/config.dart' as config;
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:system_info3/system_info3.dart';
|
||||
import 'package:unyo/core/di/locator.dart';
|
||||
import 'package:unyo/core/services/api/http/api_response.dart';
|
||||
@@ -21,12 +20,12 @@ class TorrentService {
|
||||
Process? torrentProcess;
|
||||
|
||||
TorrentService() {
|
||||
initTorrentServer();
|
||||
_initTorrentServer();
|
||||
}
|
||||
|
||||
Future<void> initTorrentServer() async {
|
||||
Future<void> _initTorrentServer() async {
|
||||
await stopServer();
|
||||
Directory supportDirectory = await getApplicationSupportDirectory();
|
||||
Directory supportDirectory = sl<Directory>(instanceName: config.applicationSupportDirectory);
|
||||
String torrServerPath = await _loadTorrServerIfNeeded(supportDirectory);
|
||||
_startServer(torrServerPath);
|
||||
}
|
||||
@@ -108,5 +107,4 @@ class TorrentService {
|
||||
}
|
||||
torrentProcess?.kill();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
272
lib/core/services/video/video_service.dart
Normal file
272
lib/core/services/video/video_service.dart
Normal file
@@ -0,0 +1,272 @@
|
||||
// External dependencies
|
||||
import 'dart:convert';
|
||||
import 'package:fvp/mdk.dart' as mdk;
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
// Internal dependencies
|
||||
import 'package:unyo/domain/entities/extension/headers.dart' as ext;
|
||||
import 'package:unyo/domain/entities/extension/track.dart' as ext;
|
||||
import 'package:unyo/domain/entities/extension/video.dart' as ext;
|
||||
import 'package:unyo/core/services/api/http/api_response.dart';
|
||||
import 'package:unyo/core/services/api/http/empty_api_response.dart';
|
||||
import 'package:unyo/core/services/api/http/http_service.dart';
|
||||
import 'package:unyo/core/di/locator.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
class VideoService {
|
||||
// Services
|
||||
final Logger _logger = sl<Logger>();
|
||||
final HttpService _httpService = sl<HttpService>();
|
||||
|
||||
// Properties
|
||||
ext.Video _video;
|
||||
int _playlistIndex;
|
||||
late final mdk.Player _player;
|
||||
final List<ext.Track> captionTracks = [];
|
||||
final List<ext.Track> audioTracks = [];
|
||||
ClosedCaptionFile? _currentCaptionFile;
|
||||
ext.Track? _currentCaptionTrack;
|
||||
ext.Track? _currentAudioTrack;
|
||||
bool _isBuffering = true;
|
||||
|
||||
VideoService({required ext.Video video, required int playlistIndex}) : _playlistIndex = playlistIndex, _video = video {
|
||||
_player = mdk.Player();
|
||||
// TODO handle magnets
|
||||
// Set player media properties
|
||||
_player.setMedia(_video.videoUrl, mdk.MediaType.video);
|
||||
_player.loop = 0; // No loop
|
||||
_player.state = mdk.PlaybackState.paused;
|
||||
// Set player ffmpeg properties
|
||||
_configurePlayer();
|
||||
// Set player HTTP headers
|
||||
_setPlayerHttpHeaders(_video.headers);
|
||||
// Set player logs handler
|
||||
_setPlayerLogsHandler();
|
||||
// Waits for video to be ready and initializes embedded tracks
|
||||
_player.onMediaStatus((mdk.MediaStatus oldStatus, mdk.MediaStatus newStatus) {
|
||||
if (newStatus.rawValue == mdk.MediaStatus.loaded) {
|
||||
_initEmbeddedCaptionsAndAudiotracks();
|
||||
}
|
||||
if (newStatus.rawValue == mdk.MediaStatus.buffering) {
|
||||
_isBuffering = true;
|
||||
}
|
||||
if (newStatus.rawValue == mdk.MediaStatus.buffered) {
|
||||
_isBuffering = false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Getters
|
||||
Duration get position => Duration(milliseconds: _player.position);
|
||||
|
||||
Duration get duration => Duration(milliseconds: _player.mediaInfo.duration);
|
||||
|
||||
double get percentagePlayed => (position.inMilliseconds / duration.inMilliseconds);
|
||||
|
||||
double get volume => _player.volume;
|
||||
|
||||
bool get isPlaying => _player.state == mdk.PlaybackState.playing;
|
||||
|
||||
bool get isBuffering => _isBuffering;
|
||||
|
||||
Future<bool> get isFullscreen async => await windowManager.isFullScreen();
|
||||
|
||||
double get aspectRatio {
|
||||
final streams = _player.mediaInfo.video;
|
||||
if (streams != null && streams.isNotEmpty) {
|
||||
final codec = streams.first.codec;
|
||||
// codec.width and codec.height are ints
|
||||
return codec.width / codec.height;
|
||||
}
|
||||
return 16 / 9;
|
||||
}
|
||||
|
||||
// Setters
|
||||
void play() {
|
||||
if (_isBuffering) return;
|
||||
_player.state = mdk.PlaybackState.playing;
|
||||
}
|
||||
|
||||
void pause() {
|
||||
if (_isBuffering) return;
|
||||
_player.state = mdk.PlaybackState.paused;
|
||||
}
|
||||
|
||||
void setLooping(bool loop) {
|
||||
loop ? _player.loop = -1 : _player.loop = 0;
|
||||
}
|
||||
|
||||
void setVolume(double volume) {
|
||||
_player.volume = volume;
|
||||
}
|
||||
|
||||
void setPlaybackSpeed(double newPlayBackSpeed) {
|
||||
_player.playbackRate = newPlayBackSpeed;
|
||||
}
|
||||
|
||||
void seekTo(Duration newDuration) {
|
||||
_player.seek(position: newDuration.inMilliseconds);
|
||||
}
|
||||
|
||||
void setCaptionOffset(Duration duration) {
|
||||
throw UnimplementedError("CaptionOffset not yet implemented");
|
||||
}
|
||||
|
||||
Future<void> setCaption(int captionIndex) async {
|
||||
if (captionIndex < 0 || captionIndex >= captionTracks.length) {
|
||||
_currentCaptionTrack = null;
|
||||
return;
|
||||
}
|
||||
_currentCaptionTrack = captionTracks[captionIndex];
|
||||
if (_currentCaptionTrack!.embedded) {
|
||||
_player.activeSubtitleTracks = [
|
||||
_currentCaptionTrack?.embeddedIndex ?? 0
|
||||
];
|
||||
} else {
|
||||
_currentCaptionFile = await _loadExternalCaption(_currentCaptionTrack!);
|
||||
}
|
||||
}
|
||||
|
||||
void setAudioTrack(int audioTrackIndex) {
|
||||
if (audioTrackIndex < 0 || audioTrackIndex >= audioTracks.length) {
|
||||
_currentAudioTrack = null;
|
||||
return;
|
||||
}
|
||||
_currentAudioTrack = audioTracks[audioTrackIndex];
|
||||
if (_currentAudioTrack!.embedded) {
|
||||
_player.activeAudioTracks = [
|
||||
_currentAudioTrack?.embeddedIndex ?? 0
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
void setFullscreen(bool fullscreen) {
|
||||
windowManager.setFullScreen(fullscreen);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_player.state = mdk.PlaybackState.stopped;
|
||||
_player.dispose();
|
||||
}
|
||||
|
||||
// Utilities
|
||||
void _configurePlayer() {
|
||||
// Note might want to use avformat.user_agent
|
||||
_player.setProperty('avformat.extension_picky', '0');
|
||||
_player.setProperty('avformat.http_persistent', '1'); // NOTE: Not sure
|
||||
_player.setProperty('avformat.reconnect', '1');
|
||||
_player.setProperty('avformat.reconnect_streamed', '1');
|
||||
_player.setProperty('avformat.reconnect_delay_max', '5');
|
||||
_player.setProperty(
|
||||
'avformat.protocol_whitelist',
|
||||
'file,http,https,tcp,tls,udp,rtp,rtmp,rtmpe,rtmps,rtmpt,rtmpte,crypto,data',
|
||||
); // NOTE: Not sure
|
||||
}
|
||||
|
||||
void _setPlayerHttpHeaders(ext.Headers? headers) {
|
||||
if (headers != null && headers.headersMap.isNotEmpty) {
|
||||
final formattedHeaders = headers.headersMap.entries.map((e) => '${e.key}: ${e.value}').join('\r\n');
|
||||
_player.setProperty('headers', formattedHeaders);
|
||||
_player.setProperty('avio.headers', formattedHeaders);
|
||||
}
|
||||
}
|
||||
|
||||
void _setPlayerLogsHandler() {
|
||||
mdk.setLogHandler((mdk.LogLevel level, String message) {
|
||||
if (!message.contains("unloaded media's position")) {
|
||||
switch (level) {
|
||||
case mdk.LogLevel.debug:
|
||||
_logger.d("MDK Log: $message");
|
||||
case mdk.LogLevel.info:
|
||||
_logger.i("MDK Log: $message");
|
||||
case mdk.LogLevel.warning:
|
||||
_logger.w("MDK Log: $message");
|
||||
case mdk.LogLevel.error:
|
||||
_logger.e("MDK Log: $message");
|
||||
case mdk.LogLevel.off:
|
||||
break;
|
||||
case mdk.LogLevel.all:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _initEmbeddedCaptionsAndAudiotracks() async {
|
||||
if (_player.mediaInfo.subtitle != null && _player.mediaInfo.subtitle!.isNotEmpty) {
|
||||
for (mdk.SubtitleStreamInfo subtitleStreamInfo in _player.mediaInfo.subtitle!) {
|
||||
captionTracks.add(
|
||||
ext.Track(
|
||||
url: "",
|
||||
lang:
|
||||
"${subtitleStreamInfo.metadata["title"] ?? ""} (${subtitleStreamInfo.metadata["language"]} - Embedded)",
|
||||
embedded: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (_player.mediaInfo.audio != null && _player.mediaInfo.audio!.length > 1) {
|
||||
for (mdk.AudioStreamInfo audioStreamInfo in _player.mediaInfo.audio!) {
|
||||
audioTracks.add(
|
||||
ext.Track(
|
||||
url: "",
|
||||
lang:
|
||||
"${audioStreamInfo.metadata["title"] ?? ""} (${audioStreamInfo.metadata["language"]} - Embedded)",
|
||||
embedded: true,
|
||||
embeddedIndex: audioStreamInfo.index
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<ClosedCaptionFile> _loadExternalCaption(ext.Track captionTrack) async {
|
||||
if (captionTrack.url.isEmpty) {
|
||||
throw Exception("Caption track URL is empty");
|
||||
}
|
||||
ApiResponse<EmptyApiResponse> response = await _httpService.get(
|
||||
captionTrack.url,
|
||||
fromJson: EmptyApiResponse.fromJson,
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception(
|
||||
"Failed to load captions from ${captionTrack.url} with status code ${response.statusCode}",
|
||||
);
|
||||
}
|
||||
var bytes = response.bodyBytes;
|
||||
String content = String.fromCharCodes(bytes);
|
||||
return WebVTTCaptionFile(_formatCaptions(_getUtf8Text(content)));
|
||||
}
|
||||
|
||||
String _getUtf8Text(String text) {
|
||||
List<int> bytes = text.codeUnits;
|
||||
return utf8.decode(bytes);
|
||||
}
|
||||
|
||||
String _formatCaptions(String captions) {
|
||||
// Split the captions into pieces based on empty lines
|
||||
List<String> pieces = captions.split('\n\n');
|
||||
List<String> formattedPieces = [];
|
||||
for (int i = 0; i < pieces.length; i++) {
|
||||
formattedPieces.add(_replaceSecondNewLine(pieces[i], "\n", " "));
|
||||
}
|
||||
// Join the formatted pieces back together with empty lines
|
||||
String formattedCaptions = formattedPieces.join('\n\n');
|
||||
|
||||
return formattedCaptions;
|
||||
}
|
||||
|
||||
String _replaceSecondNewLine(String original, String pattern, String replacement) {
|
||||
int firstIndex = original.indexOf(pattern);
|
||||
if (firstIndex != -1) {
|
||||
int secondIndex = original.indexOf(pattern, firstIndex + 1);
|
||||
if (secondIndex != -1) {
|
||||
return original.replaceFirst(pattern, replacement, secondIndex);
|
||||
}
|
||||
}
|
||||
return original;
|
||||
}
|
||||
}
|
||||
46
lib/domain/entities/extension/anime.dart.old
Normal file
46
lib/domain/entities/extension/anime.dart.old
Normal file
@@ -0,0 +1,46 @@
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jsanime.dart';
|
||||
|
||||
class Anime {
|
||||
final String url;
|
||||
final String title;
|
||||
final String? thumbnailUrl;
|
||||
final String? artist;
|
||||
final String? author;
|
||||
final String? description;
|
||||
final String? genre;
|
||||
final List<String>? genres;
|
||||
final bool initialized;
|
||||
final double seasonNumber;
|
||||
final int status;
|
||||
|
||||
const Anime({
|
||||
required this.url,
|
||||
required this.title,
|
||||
required this.thumbnailUrl,
|
||||
required this.artist,
|
||||
required this.author,
|
||||
required this.description,
|
||||
required this.genre,
|
||||
required this.genres,
|
||||
required this.initialized,
|
||||
required this.seasonNumber,
|
||||
required this.status,
|
||||
});
|
||||
|
||||
factory Anime.fromJSAnime(JSAnime jsAnime) {
|
||||
jObjIsNotNull(jObj) => jObj != null;
|
||||
return Anime(
|
||||
url: jsAnime.getUrl().toDartString(),
|
||||
title: jsAnime.getTitle().toDartString(),
|
||||
thumbnailUrl: jsAnime.getThumbnail_url()?.toDartString(),
|
||||
artist: jsAnime.getArtist()?.toDartString(),
|
||||
author: jsAnime.getAuthor()?.toDartString(),
|
||||
description: jsAnime.getDescription()?.toDartString(),
|
||||
genre: jsAnime.getGenre()?.toDartString(),
|
||||
genres: jsAnime.getGenres()?.where(jObjIsNotNull).map((jObj) => jObj.toDartString()).toList(),
|
||||
initialized: jsAnime.getInitialized(),
|
||||
seasonNumber: jsAnime.getSeason_number(),
|
||||
status: jsAnime.getStatus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
0
lib/domain/entities/extension/chapter.dart.old
Normal file
0
lib/domain/entities/extension/chapter.dart.old
Normal file
28
lib/domain/entities/extension/episode.dart.old
Normal file
28
lib/domain/entities/extension/episode.dart.old
Normal file
@@ -0,0 +1,28 @@
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jsepisode.dart';
|
||||
|
||||
class Episode {
|
||||
|
||||
final String url;
|
||||
final String title;
|
||||
final String? scanlator;
|
||||
final double episodeNumber;
|
||||
final int dateUploaded;
|
||||
|
||||
const Episode({
|
||||
required this.url,
|
||||
required this.title,
|
||||
required this.scanlator,
|
||||
required this.episodeNumber,
|
||||
required this.dateUploaded,
|
||||
});
|
||||
|
||||
factory Episode.fromJSEpisode(JSEpisode jsEpisode) {
|
||||
return Episode(
|
||||
url: jsEpisode.getUrl().toDartString(),
|
||||
title: jsEpisode.getName().toDartString(),
|
||||
scanlator: jsEpisode.getScanlator()?.toDartString(),
|
||||
episodeNumber: jsEpisode.getEpisode_number(),
|
||||
dateUploaded: jsEpisode.getDate_upload()
|
||||
);
|
||||
}
|
||||
}
|
||||
16
lib/domain/entities/extension/headers.dart
Normal file
16
lib/domain/entities/extension/headers.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jheaders.dart';
|
||||
|
||||
class Headers {
|
||||
final Map<String, String> headersMap;
|
||||
|
||||
const Headers({required this.headersMap});
|
||||
|
||||
factory Headers.fromJHeaders(JHeaders? jHeaders) {
|
||||
if (jHeaders == null) {
|
||||
return const Headers(headersMap: {});
|
||||
}
|
||||
return Headers(
|
||||
headersMap: jHeaders.toMultimap().map((key, value) => MapEntry(key.toDartString(), value.join(","))),
|
||||
);
|
||||
}
|
||||
}
|
||||
0
lib/domain/entities/extension/manga.dart.old
Normal file
0
lib/domain/entities/extension/manga.dart.old
Normal file
0
lib/domain/entities/extension/page.dart
Normal file
0
lib/domain/entities/extension/page.dart
Normal file
23
lib/domain/entities/extension/track.dart
Normal file
23
lib/domain/entities/extension/track.dart
Normal file
@@ -0,0 +1,23 @@
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jtrack.dart';
|
||||
|
||||
class Track {
|
||||
final String url;
|
||||
final String lang;
|
||||
final bool embedded;
|
||||
final int? embeddedIndex;
|
||||
|
||||
const Track({
|
||||
required this.url,
|
||||
required this.lang,
|
||||
required this.embedded,
|
||||
this.embeddedIndex,
|
||||
});
|
||||
|
||||
factory Track.fromJTrack(JTrack jTrack) {
|
||||
return Track(
|
||||
url: jTrack.getUrl().toDartString(),
|
||||
lang: jTrack.getLang().toDartString(),
|
||||
embedded: false
|
||||
);
|
||||
}
|
||||
}
|
||||
57
lib/domain/entities/extension/video.dart
Normal file
57
lib/domain/entities/extension/video.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jheaders.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jtrack.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jvideo.dart';
|
||||
import 'package:unyo/domain/entities/extension/headers.dart';
|
||||
import 'package:unyo/domain/entities/extension/track.dart';
|
||||
|
||||
class Video {
|
||||
final String url;
|
||||
final String title;
|
||||
final String quality;
|
||||
final String videoUrl;
|
||||
final Headers? headers;
|
||||
final bool initialized;
|
||||
final List<Track> audioTracks;
|
||||
final List<Track> subtitleTracks;
|
||||
final int? bitrate;
|
||||
final int? resolution;
|
||||
|
||||
const Video({
|
||||
required this.url,
|
||||
required this.title,
|
||||
required this.quality,
|
||||
required this.videoUrl,
|
||||
required this.headers,
|
||||
required this.initialized,
|
||||
required this.audioTracks,
|
||||
required this.subtitleTracks,
|
||||
required this.bitrate,
|
||||
required this.resolution,
|
||||
});
|
||||
|
||||
factory Video.fromJVideo(JVideo jVideo) {
|
||||
jObjIsNotNull(jObj) => jObj != null;
|
||||
return Video(
|
||||
url: jVideo.getUrl().toDartString(),
|
||||
title: jVideo.getVideoTitle().toDartString(),
|
||||
quality: jVideo.getQuality().toDartString(),
|
||||
videoUrl: jVideo.getVideoUrl().toDartString(),
|
||||
headers: Headers.fromJHeaders(jVideo.getHeaders()?.as<JHeaders>(JHeaders.type)),
|
||||
initialized: jVideo.getInitialized(),
|
||||
audioTracks:
|
||||
jVideo
|
||||
.getAudioTracks()
|
||||
.where(jObjIsNotNull)
|
||||
.map((jObj) => Track.fromJTrack(jObj.as<JTrack>(JTrack.type)))
|
||||
.toList(),
|
||||
subtitleTracks:
|
||||
jVideo
|
||||
.getSubtitleTracks()
|
||||
.where(jObjIsNotNull)
|
||||
.map((jObj) => Track.fromJTrack(jObj.as<JTrack>(JTrack.type)))
|
||||
.toList(),
|
||||
bitrate: jVideo.getBitrate()?.intValue(),
|
||||
resolution: jVideo.getResolution()?.intValue(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jvideo.dart';
|
||||
import 'package:unyo/application/cubits/anime_details_cubit.dart';
|
||||
import 'package:unyo/application/states/anime_details_state.dart';
|
||||
import 'package:unyo/domain/entities/extension/video.dart' as ext;
|
||||
import 'package:unyo/presentation/views/loading_view.dart';
|
||||
import 'package:unyo/presentation/widgets/styled/unyo_server_button.dart';
|
||||
|
||||
@@ -59,7 +59,7 @@ class _AnimeServerSelectionDialogState extends State<AnimeServerSelectionDialog>
|
||||
padding: EdgeInsets.symmetric(horizontal: 15.0.w),
|
||||
children: [
|
||||
...state.extensionVideoResults.map(
|
||||
(JVideo video) => Column(
|
||||
(ext.Video video) => Column(
|
||||
children: [SizedBox(height: 25.0.h), UnyoServerButton(videoServer: video)],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -4,8 +4,8 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class UnyoAnimatedImageBanner extends StatefulWidget {
|
||||
final imageUrl;
|
||||
const UnyoAnimatedImageBanner({super.key, this.imageUrl});
|
||||
final String imageUrl;
|
||||
const UnyoAnimatedImageBanner({super.key, required this.imageUrl});
|
||||
|
||||
@override
|
||||
State<UnyoAnimatedImageBanner> createState() =>
|
||||
|
||||
@@ -114,7 +114,6 @@ class _UnyoDropdownState extends State<UnyoDropdown> {
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
].toList(),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -40,7 +40,6 @@ class _UnyoMultiSelectDropdownState extends State<UnyoMultiSelectDropdown> {
|
||||
@override
|
||||
void didUpdateWidget(covariant UnyoMultiSelectDropdown oldWidget) {
|
||||
if (oldWidget.selectedValues != _selectedItems ) {
|
||||
print("Needs rebuild of selected items");
|
||||
setState(() {
|
||||
_selectedItems = List.from(widget.selectedValues);
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:k3vinb5_aniyomi_bridge/jmodels/jvideo.dart';
|
||||
import 'package:unyo/domain/entities/extension/video.dart' as ext;
|
||||
|
||||
class UnyoServerButton extends StatelessWidget {
|
||||
final JVideo videoServer;
|
||||
final ext.Video videoServer;
|
||||
|
||||
const UnyoServerButton({super.key, required this.videoServer});
|
||||
|
||||
@@ -32,13 +32,13 @@ class UnyoServerButton extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
videoServer.getQuality().toDartString(),
|
||||
videoServer.quality,
|
||||
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
RegExp(r'(720|1080)[pP]?').hasMatch(videoServer.getQuality().toDartString())
|
||||
RegExp(r'(720|1080)[pP]?').hasMatch(videoServer.quality)
|
||||
? Icons.hd
|
||||
: Icons.sd,
|
||||
color: ColorScheme.of(context).tertiary,
|
||||
|
||||
@@ -67,7 +67,7 @@ class _UnyoSortWidgetState extends State<UnyoSortWidget> {
|
||||
child: CompositedTransformFollower(
|
||||
link: _layerLink,
|
||||
showWhenUnlinked: false,
|
||||
offset: Offset(0, 54),
|
||||
offset: const Offset(0, 54),
|
||||
child: Material(
|
||||
elevation: 4,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
|
||||
42
pubspec.yaml
42
pubspec.yaml
@@ -6,7 +6,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 1.0.0
|
||||
|
||||
environment:
|
||||
sdk: ^3.7.2
|
||||
sdk: ^3.10.0
|
||||
|
||||
# List your package dependencies below. Run `flutter pub outdated` to check for updates.
|
||||
dependencies:
|
||||
@@ -14,11 +14,11 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
# State management
|
||||
bloc: ^9.0.0
|
||||
bloc: ^9.2.0
|
||||
flutter_bloc: ^9.1.1
|
||||
rxdart: ^0.28.0
|
||||
# Dependency Injection
|
||||
get_it: ^8.0.3
|
||||
get_it: ^9.2.0
|
||||
# Logging
|
||||
logger: ^2.6.0
|
||||
# Code generation
|
||||
@@ -26,47 +26,49 @@ dependencies:
|
||||
freezed_annotation: ^3.1.0
|
||||
json_annotation: ^4.9.0
|
||||
# HTTP requests
|
||||
http: ^1.4.0
|
||||
http: ^1.6.0
|
||||
retry: ^3.1.2
|
||||
# Routing and Navigation
|
||||
auto_route: ^10.1.0+1
|
||||
auto_route_generator: ^10.1.0
|
||||
auto_route: ^11.1.0
|
||||
auto_route_generator: ^10.4.0
|
||||
# UI and Layout
|
||||
flutter_screenutil: ^5.9.3
|
||||
loading_animation_widget: ^1.3.0
|
||||
awesome_snackbar_content: ^0.1.6
|
||||
flutter_svg: ^2.2.0
|
||||
fl_chart: ^1.0.0
|
||||
dynamic_color: ^1.7.0
|
||||
awesome_snackbar_content: ^0.1.8
|
||||
flutter_svg: ^2.2.3
|
||||
fl_chart: ^1.1.1
|
||||
dynamic_color: ^1.8.1
|
||||
material_color_utilities: ^0.11.1
|
||||
palette_generator: ^0.3.3+7
|
||||
# Platform Integration
|
||||
window_manager: ^0.5.1
|
||||
url_launcher: ^6.3.1
|
||||
url_launcher: ^6.3.2
|
||||
flutter_discord_rpc: ^1.1.0
|
||||
# Media
|
||||
smooth_video_progress: ^0.0.4
|
||||
fvp: ^0.33.0
|
||||
fvp: ^0.35.2
|
||||
video_player: ^2.10.1
|
||||
# Backend/Server
|
||||
shelf: ^1.4.2
|
||||
# Storage
|
||||
path_provider: ^2.1.5
|
||||
hive_ce: ^2.11.3
|
||||
hive_ce: ^2.16.0
|
||||
path: ^1.9.1
|
||||
crypto: ^3.0.7
|
||||
# Asset Management
|
||||
icons_launcher: ^3.0.1
|
||||
icons_launcher: ^3.0.3
|
||||
# Utilities
|
||||
collection: ^1.19.1
|
||||
html: ^0.15.6
|
||||
cast: ^2.1.0
|
||||
# Localization
|
||||
easy_localization: ^3.0.7+1
|
||||
easy_localization: ^3.0.8
|
||||
# FFI/Native Integration
|
||||
system_info3: ^4.0.2
|
||||
ffi: ^2.1.4
|
||||
ffigen: ^19.0.0
|
||||
meta: ^1.16.0
|
||||
jni: ^0.14.2
|
||||
# ffi: ^2.1.4
|
||||
# ffigen: ^19.0.0
|
||||
meta: ^1.17.0
|
||||
jwt_decoder: ^2.0.1
|
||||
k3vinb5_aniyomi_bridge:
|
||||
path: ../k3vinb5_aniyomi_bridge
|
||||
@@ -77,13 +79,13 @@ dev_dependencies:
|
||||
sdk: flutter
|
||||
# Linting and code quality
|
||||
flutter_lints: ^6.0.0
|
||||
bloc_lint: ^0.2.0
|
||||
bloc_lint: ^0.3.5
|
||||
# Testing
|
||||
bloc_test: ^10.0.0
|
||||
# Code generation
|
||||
hive_ce_generator: ^1.9.2
|
||||
json_serializable: ^6.9.5
|
||||
build_runner: ^2.5.4
|
||||
build_runner: ^2.10.4
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
|
||||
Reference in New Issue
Block a user