#(plugin id can be found at https://plugins.jetbrains.com)
27 |
28 | #Specify Qodana linter for analysis (Applied in CI/CD pipeline)
29 | linter: jetbrains/qodana-go:latest
30 |
--------------------------------------------------------------------------------
/services/abuse_store/client.go:
--------------------------------------------------------------------------------
1 | package abuse_store
2 |
3 | import (
4 | "fmt"
5 | "google.golang.org/grpc/credentials/insecure"
6 | "sync"
7 |
8 | "github.com/urfave/cli"
9 | as "github.com/webtor-io/abuse-store/proto"
10 | "google.golang.org/grpc"
11 | )
12 |
13 | const (
14 | HostFlag = "abuse-host"
15 | PortFlag = "abuse-port"
16 | UseFlag = "use-abuse"
17 | )
18 |
19 | func RegisterFlags(f []cli.Flag) []cli.Flag {
20 | return append(f,
21 | cli.StringFlag{
22 | Name: HostFlag,
23 | Usage: "abuse store host",
24 | Value: "",
25 | EnvVar: "ABUSE_STORE_SERVICE_HOST",
26 | },
27 | cli.IntFlag{
28 | Name: PortFlag,
29 | Usage: "port of the redis service",
30 | Value: 50051,
31 | EnvVar: "ABUSE_STORE_SERVICE_PORT",
32 | },
33 | cli.BoolFlag{
34 | Name: UseFlag,
35 | Usage: "use abuse",
36 | EnvVar: "USE_ABUSE_STORE",
37 | },
38 | )
39 | }
40 |
41 | type Client struct {
42 | once sync.Once
43 | cl as.AbuseStoreClient
44 | err error
45 | host string
46 | port int
47 | conn *grpc.ClientConn
48 | }
49 |
50 | func New(c *cli.Context) *Client {
51 | if !c.Bool(UseFlag) {
52 | return nil
53 | }
54 | return &Client{
55 | host: c.String(HostFlag),
56 | port: c.Int(PortFlag),
57 | }
58 | }
59 |
60 | func (s *Client) Get() (as.AbuseStoreClient, error) {
61 | s.once.Do(func() {
62 | addr := fmt.Sprintf("%s:%d", s.host, s.port)
63 | conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
64 | if err != nil {
65 | s.err = err
66 | return
67 | }
68 | if err != nil {
69 | s.err = err
70 | return
71 | }
72 | s.conn = conn
73 | s.cl = as.NewAbuseStoreClient(conn)
74 | })
75 | return s.cl, s.err
76 | }
77 |
78 | func (s *Client) Close() {
79 | if s.conn != nil {
80 | _ = s.conn.Close()
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/services/claims/client.go:
--------------------------------------------------------------------------------
1 | package claims
2 |
3 | import (
4 | "fmt"
5 | "google.golang.org/grpc/credentials/insecure"
6 | "sync"
7 |
8 | "github.com/urfave/cli"
9 | proto "github.com/webtor-io/claims-provider/proto"
10 | "google.golang.org/grpc"
11 | )
12 |
13 | const (
14 | claimsProviderHostFlag = "claims-provider-host"
15 | claimsProviderPortFlag = "claims-provider-port"
16 | )
17 |
18 | func RegisterClientFlags(f []cli.Flag) []cli.Flag {
19 | return append(f,
20 | cli.StringFlag{
21 | Name: claimsProviderHostFlag,
22 | Usage: "claims provider host",
23 | Value: "",
24 | EnvVar: "CLAIMS_PROVIDER_SERVICE_HOST",
25 | },
26 | cli.IntFlag{
27 | Name: claimsProviderPortFlag,
28 | Usage: "claims provider port",
29 | Value: 50051,
30 | EnvVar: "CLAIMS_PROVIDER_SERVICE_PORT",
31 | },
32 | )
33 | }
34 |
35 | type Client struct {
36 | once sync.Once
37 | cl proto.ClaimsProviderClient
38 | err error
39 | host string
40 | port int
41 | conn *grpc.ClientConn
42 | }
43 |
44 | func NewClient(c *cli.Context) *Client {
45 | return &Client{
46 | host: c.String(claimsProviderHostFlag),
47 | port: c.Int(claimsProviderPortFlag),
48 | }
49 | }
50 |
51 | func (s *Client) Get() (proto.ClaimsProviderClient, error) {
52 | s.once.Do(func() {
53 | addr := fmt.Sprintf("%s:%d", s.host, s.port)
54 | conn, err := grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
55 | if err != nil {
56 | s.err = err
57 | return
58 | }
59 | s.conn = conn
60 | s.cl = proto.NewClaimsProviderClient(conn)
61 | })
62 | return s.cl, s.err
63 | }
64 |
65 | func (s *Client) Close() {
66 | if s.conn != nil {
67 | _ = s.conn.Close()
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/services/common.go:
--------------------------------------------------------------------------------
1 | package services
2 |
3 | import (
4 | "regexp"
5 |
6 | "github.com/urfave/cli"
7 | )
8 |
9 | var SHA1R = regexp.MustCompile("(?i)[0-9a-f]{5,40}")
10 |
11 | var (
12 | DomainFlag = "domain"
13 | DemoMagnetFlag = "demo-magnet"
14 | DemoTorrentFlag = "demo-torrent"
15 | SMTPHostFlag = "smtp-host"
16 | SMTPUserFlag = "smtp-user"
17 | SMTPPassFlag = "smtp-pass"
18 | SMTPPortFlag = "smtp-port"
19 | SMTPSecureFlag = "smtp-secure"
20 | )
21 |
22 | func RegisterFlags(f []cli.Flag) []cli.Flag {
23 | f = append(f,
24 | cli.StringFlag{
25 | Name: DomainFlag,
26 | Usage: "domain",
27 | Value: "http://localhost:8080",
28 | EnvVar: "DOMAIN",
29 | },
30 | cli.StringFlag{
31 | Name: DemoMagnetFlag,
32 | Usage: "demo magnet",
33 | Value: "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10",
34 | EnvVar: "DEMO_MAGNET",
35 | },
36 | cli.StringFlag{
37 | Name: DemoTorrentFlag,
38 | Usage: "demo torrent",
39 | Value: "https://webtorrent.io/torrents/sintel.torrent",
40 | EnvVar: "DEMO_TORRENT",
41 | },
42 | cli.StringFlag{
43 | Name: SMTPHostFlag,
44 | Usage: "smtp host",
45 | EnvVar: "SMTP_HOST",
46 | },
47 | cli.StringFlag{
48 | Name: SMTPUserFlag,
49 | Usage: "smtp user",
50 | EnvVar: "SMTP_USER",
51 | },
52 | cli.StringFlag{
53 | Name: SMTPPassFlag,
54 | Usage: "smtp pass",
55 | EnvVar: "SMTP_PASS",
56 | },
57 | cli.IntFlag{
58 | Name: SMTPPortFlag,
59 | Usage: "smtp port",
60 | EnvVar: "SMTP_PORT",
61 | Value: 465,
62 | },
63 | cli.BoolTFlag{
64 | Name: SMTPSecureFlag,
65 | Usage: "smtp secure",
66 | EnvVar: "SMTP_SECURE",
67 | },
68 | )
69 |
70 | return f
71 | }
72 |
73 | const AccessTokenParamName = "token"
74 |
--------------------------------------------------------------------------------
/services/embed/domain_settings.go:
--------------------------------------------------------------------------------
1 | package embed
2 |
3 | import (
4 | "github.com/pkg/errors"
5 | "github.com/webtor-io/web-ui/models"
6 | "time"
7 |
8 | "github.com/go-pg/pg/v10"
9 | cs "github.com/webtor-io/common-services"
10 | "github.com/webtor-io/lazymap"
11 | "github.com/webtor-io/web-ui/services/claims"
12 | )
13 |
14 | type DomainSettings struct {
15 | lazymap.LazyMap[*DomainSettingsData]
16 | pg *cs.PG
17 | claims *claims.Claims
18 | }
19 | type DomainSettingsData struct {
20 | Ads bool `json:"ads"`
21 | }
22 |
23 | func NewDomainSettings(pg *cs.PG, claims *claims.Claims) *DomainSettings {
24 | return &DomainSettings{
25 | pg: pg,
26 | claims: claims,
27 | LazyMap: lazymap.New[*DomainSettingsData](&lazymap.Config{
28 | Expire: time.Minute,
29 | ErrorExpire: 10 * time.Second,
30 | }),
31 | }
32 | }
33 |
34 | func (s *DomainSettings) Get(domain string) (*DomainSettingsData, error) {
35 | return s.LazyMap.Get(domain, func() (*DomainSettingsData, error) {
36 | if s.pg == nil || s.pg.Get() == nil || s.claims == nil {
37 | return &DomainSettingsData{}, nil
38 | }
39 | db := s.pg.Get()
40 | em := &models.EmbedDomain{}
41 | err := db.Model(em).
42 | Relation("User").
43 | Where("embed_domain.domain = ?", domain).
44 | Select()
45 | if errors.Is(err, pg.ErrNoRows) {
46 | return &DomainSettingsData{Ads: true}, nil
47 | } else if err != nil {
48 | return nil, err
49 | }
50 | cl, err := s.claims.Get(em.User.Email)
51 | if err != nil {
52 | return nil, err
53 | }
54 | return &DomainSettingsData{Ads: em.Ads || !cl.Claims.Embed.NoAds}, nil
55 | })
56 | }
57 |
--------------------------------------------------------------------------------
/services/geoip/helper.go:
--------------------------------------------------------------------------------
1 | package geoip
2 |
3 | type Helper struct{}
4 |
5 | func NewHelper() *Helper {
6 | return &Helper{}
7 | }
8 |
9 | func (h *Helper) InCountries(data *Data, countries ...string) bool {
10 | if data == nil {
11 | return false
12 | }
13 | for _, country := range countries {
14 | if data.Country == country {
15 | return true
16 |
17 | }
18 | }
19 | return false
20 | }
21 |
--------------------------------------------------------------------------------
/services/job/storage.go:
--------------------------------------------------------------------------------
1 | package job
2 |
3 | import (
4 | "context"
5 | "time"
6 |
7 | cs "github.com/webtor-io/common-services"
8 | )
9 |
10 | type State struct {
11 | ID string
12 | TTL time.Duration
13 | }
14 |
15 | type Storage interface {
16 | Pub(ctx context.Context, id string, l LogItem) error
17 | Sub(ctx context.Context, id string) (res chan LogItem, err error)
18 | GetState(ctx context.Context, id string) (state *State, ok bool, err error)
19 | Drop(ctx context.Context, id string) (err error)
20 | }
21 |
22 | type NilStorage struct{}
23 |
24 | func (s *NilStorage) Pub(_ context.Context, _ string, _ LogItem) error {
25 | return nil
26 | }
27 |
28 | func (s *NilStorage) Drop(_ context.Context, _ string) (err error) {
29 | return
30 | }
31 |
32 | func (s *NilStorage) Sub(_ context.Context, _ string) (res chan LogItem, err error) {
33 | return
34 | }
35 |
36 | func (s *NilStorage) GetState(_ context.Context, _ string) (state *State, ok bool, err error) {
37 | return nil, false, nil
38 | }
39 |
40 | var _ Storage = (*NilStorage)(nil)
41 |
42 | func NewStorage(rc *cs.RedisClient, prefix string) Storage {
43 | cl := rc.Get()
44 | if cl == nil {
45 | return &NilStorage{}
46 | }
47 | return NewRedis(cl, prefix)
48 | }
49 |
--------------------------------------------------------------------------------
/services/obfuscator/helpers.go:
--------------------------------------------------------------------------------
1 | package obfuscator
2 |
3 | import "math/rand"
4 |
5 | func randomRange(lower, upper int) int {
6 | return lower + rand.Intn(upper-lower+1)
7 | }
8 |
9 | func strShuffle(str string) string {
10 | inRune := []rune(str)
11 | rand.Shuffle(len(inRune), func(i, j int) {
12 | inRune[i], inRune[j] = inRune[j], inRune[i]
13 | })
14 |
15 | return string(inRune)
16 | }
17 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/field_type.go:
--------------------------------------------------------------------------------
1 | package parsetorrentname
2 |
3 | type FieldType string
4 |
5 | const (
6 | FieldTypeTitle FieldType = "title"
7 | FieldTypeExtraTitle FieldType = "extra_title"
8 | FieldTypeSeason FieldType = "season"
9 | FieldTypeEpisode FieldType = "episode"
10 | FieldTypeYear FieldType = "year"
11 | FieldTypeResolution FieldType = "resolution"
12 | FieldTypeBitrate FieldType = "bitrate"
13 | FieldTypeColorDepth FieldType = "color_depth"
14 | FieldTypeQuality FieldType = "quality"
15 | FieldTypeCodec FieldType = "codec"
16 | FieldTypeAudio FieldType = "audio"
17 | FieldTypeRegion FieldType = "region"
18 | FieldTypeSize FieldType = "size"
19 | FieldTypeWebsite FieldType = "website"
20 | FieldTypeLanguage FieldType = "language"
21 | FieldTypeSBS FieldType = "sbs"
22 | FieldTypeContainer FieldType = "container"
23 | FieldTypeGroup FieldType = "group"
24 | FieldTypeStudio FieldType = "studio"
25 | FieldTypeExtended FieldType = "extended"
26 | FieldTypeHardcoded FieldType = "hardcoded"
27 | FieldTypeProper FieldType = "proper"
28 | FieldTypeRepack FieldType = "repack"
29 | FieldTypeWidescreen FieldType = "widescreen"
30 | FieldTypeUnrated FieldType = "unrated"
31 | FieldType3D FieldType = "threed"
32 | FieldTypeAVC FieldType = "avc"
33 | FieldTypePorn FieldType = "porn"
34 | FieldTypeSplitScenes FieldType = "split_scenes"
35 | FieldTypeScene FieldType = "scene"
36 | FieldTypeDubbing FieldType = "dubbing"
37 | FieldTypeUnknown FieldType = "unknown"
38 | )
39 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_000.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Walking Dead",
3 | "season": 5,
4 | "episode": 3,
5 | "resolution": "720p",
6 | "quality": "HDTV",
7 | "codec": "x264",
8 | "group": "ASAP[ettv]"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_001.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Hercules",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "BrRip",
6 | "codec": "H264"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_002.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Dawn of the Planet of the Apes",
3 | "year": 2014,
4 | "quality": "HDRip",
5 | "codec": "XViD",
6 | "group": "EVO"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_003.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Big Bang Theory",
3 | "season": 8,
4 | "episode": 6,
5 | "quality": "HDTV",
6 | "codec": "XviD",
7 | "group": "LOL [eztv]"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_004.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "22 Jump Street",
3 | "year": 2014,
4 | "resolution": "720p",
5 | "quality": "BrRip",
6 | "codec": "x264"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_005.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Hercules",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "WEB-DL",
6 | "codec": "H264",
7 | "audio": "DD5.1",
8 | "group": "RARBG",
9 | "extended": true
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_006.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Hercules",
3 | "year": 2014,
4 | "quality": "HDRip",
5 | "codec": "XViD",
6 | "group": "juggs[ETRG]",
7 | "extended": true
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_007.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Hercules",
3 | "year": 2014,
4 | "quality": "WEBDL",
5 | "codec": "XviD",
6 | "group": "MAX"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_008.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "WWE Hell in a Cell",
3 | "year": 2014,
4 | "quality": "PPV WEB-DL",
5 | "codec": "x264",
6 | "group": "WD -={SPARROW}=-"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_009.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "UFC 179",
3 | "quality": "PPV.HDTV",
4 | "codec": "x264",
5 | "group": "Ebi[rartv]"
6 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_010.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Marvels Agents of S H I E L D",
3 | "season": 2,
4 | "episode": 5,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "KILLERS [eztv]"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_011.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "X-Men Days of Future Past",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "WEB-DL",
6 | "codec": "H264",
7 | "audio": "DD5.1",
8 | "group": "RARBG"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_012.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Guardians Of The Galaxy",
3 | "year": 2014,
4 | "resolution": "720p",
5 | "quality": "HDCAM",
6 | "codec": "x264",
7 | "group": "JYK",
8 | "region": "6"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_013.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Marvel's Agents of S H I E L D",
3 | "season": 2,
4 | "episode": 1,
5 | "resolution": "1080p",
6 | "quality": "WEB-DL",
7 | "audio": "DD5.1"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_014.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Marvels Agents of S H I E L D",
3 | "season": 2,
4 | "episode": 6,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "KILLERS[ettv]"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_015.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Guardians of the Galaxy",
3 | "year": 2014,
4 | "quality": "CamRip"
5 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_016.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Walking Dead",
3 | "season": 5,
4 | "episode": 3,
5 | "resolution": "1080p",
6 | "quality": "WEB-DL",
7 | "codec": "H.264",
8 | "audio": "DD5.1",
9 | "group": "Cyphanix[rartv]"
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_017.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Brave",
3 | "year": 2012,
4 | "quality": "DVDRip",
5 | "codec": "XViD",
6 | "audio": "LiNE",
7 | "group": "UNiQUE",
8 | "region": "5"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_018.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Lets Be Cops",
3 | "year": 2014,
4 | "quality": "BRRip",
5 | "codec": "XViD",
6 | "group": "juggs[ETRG]"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_019.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "These Final Hours",
3 | "year": 2013,
4 | "quality": "WBBRip",
5 | "codec": "XViD"
6 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_020.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Downton Abbey",
3 | "season": 5,
4 | "episode": 6,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "FoV [eztv]"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_021.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Annabelle",
3 | "year": 2014,
4 | "quality": "HDRip",
5 | "codec": "XViD",
6 | "audio": "AC3",
7 | "group": "juggs[ETRG]",
8 | "hardcoded": true
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_022.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Lucy",
3 | "year": 2014,
4 | "quality": "HDRip",
5 | "codec": "XViD",
6 | "group": "juggs[ETRG]",
7 | "hardcoded": true
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_023.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Flash",
3 | "season": 1,
4 | "episode": 4,
5 | "year": 2014,
6 | "quality": "HDTV",
7 | "codec": "x264",
8 | "group": "FUM[ettv]"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_024.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "South Park",
3 | "season": 18,
4 | "episode": 5,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "KILLERS [eztv]"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_025.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Flash",
3 | "season": 1,
4 | "episode": 3,
5 | "year": 2014,
6 | "quality": "HDTV",
7 | "codec": "x264",
8 | "group": "LOL[ettv]"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_026.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Flash",
3 | "season": 1,
4 | "episode": 1,
5 | "year": 2014,
6 | "quality": "HDTV",
7 | "codec": "x264",
8 | "group": "LOL[ettv]"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_027.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Lucy",
3 | "year": 2014,
4 | "quality": "WEBRip",
5 | "audio": "Dual-Audio",
6 | "size": "1400Mb"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_028.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Teenage Mutant Ninja Turtles",
3 | "year": 2014,
4 | "quality": "HdRip"
5 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_029.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Teenage Mutant Ninja Turtles",
3 | "year": 2014
4 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_030.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Simpsons",
3 | "season": 26,
4 | "episode": 5,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "LOL [eztv]",
8 | "proper": true
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_031.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "2047 - Sights of Death",
3 | "year": 2014,
4 | "resolution": "720p",
5 | "quality": "BrRip",
6 | "codec": "x264"
7 | }
8 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_032.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Two and a Half Men",
3 | "season": 12,
4 | "episode": 1,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "LOL [eztv]",
8 | "repack": true
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_033.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Dinosaur 13",
3 | "year": 2014,
4 | "quality": "WEBrip",
5 | "codec": "XviD",
6 | "audio": "AC3"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_034.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Teenage Mutant Ninja Turtles",
3 | "year": 2014,
4 | "quality": "HDRip",
5 | "codec": "XviD",
6 | "audio": "MP3",
7 | "group": "RARBG"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_035.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Dawn Of The Planet of The Apes",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "WEB-DL",
6 | "codec": "H264",
7 | "audio": "DD51",
8 | "group": "RARBG"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_036.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Teenage Mutant Ninja Turtles",
3 | "year": 2014,
4 | "resolution": "720p",
5 | "quality": "HDRip",
6 | "codec": "x264",
7 | "audio": "AC3.5.1",
8 | "group": "RARBG"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_037.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Gotham",
3 | "season": 1,
4 | "episode": 5,
5 | "quality": "WEB-DL",
6 | "codec": "x264",
7 | "audio": "AAC"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_038.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Into The Storm",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "WEB-DL",
6 | "codec": "H264",
7 | "audio": "AAC2.0",
8 | "group": "RARBG"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_039.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Lucy",
3 | "year": 2014,
4 | "resolution": "720p",
5 | "quality": "WEBRip",
6 | "audio": "Dual-Audio"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_040.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Into The Storm",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "BRRip",
6 | "codec": "x264",
7 | "audio": "DTS",
8 | "group": "JYK"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_041.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Sin City A Dame to Kill For",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "BluRay",
6 | "codec": "x264",
7 | "group": "SPARKS"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_042.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "WWE Monday Night Raw 3rd Nov",
3 | "year": 2014,
4 | "quality": "HDTV",
5 | "codec": "x264",
6 | "group": "Sir Paul"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_043.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Jack And The Cuckoo-Clock Heart",
3 | "year": 2013,
4 | "quality": "BRRip",
5 | "codec": "XViD"
6 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_044.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "WWE Hell in a Cell",
3 | "year": 2014,
4 | "quality": "HDTV",
5 | "codec": "x264"
6 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_045.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Dracula Untold",
3 | "year": 2014,
4 | "quality": "TS",
5 | "codec": "XViD",
6 | "audio": "AC3",
7 | "group": "SiMPLE"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_046.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Missing",
3 | "season": 1,
4 | "episode": 1,
5 | "quality": "HDTV",
6 | "codec": "x264",
7 | "group": "FoV [eztv]"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_047.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Doctor Who",
3 | "season": 8,
4 | "episode": 11,
5 | "year": 2005,
6 | "resolution": "720p",
7 | "quality": "HDTV",
8 | "codec": "x264",
9 | "group": "FoV[rartv]"
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_048.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Gotham",
3 | "season": 1,
4 | "episode": 7,
5 | "quality": "WEB-DL",
6 | "codec": "x264",
7 | "audio": "AAC"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_049.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "One Shot",
3 | "year": 2014,
4 | "quality": "DVDRip",
5 | "codec": "XViD",
6 | "group": "ViCKY"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_050.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Shaukeens",
3 | "year": 2014,
4 | "quality": "DvDScr",
5 | "codec": "x264",
6 | "audio": "AAC"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_051.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Shaukeens",
3 | "year": 2014,
4 | "quality": "DvDScr",
5 | "codec": "x264"
6 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_052.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Annabelle",
3 | "year": 2014,
4 | "resolution": "1080p",
5 | "quality": "WEBRip",
6 | "codec": "x264",
7 | "audio": "AAC.2.0",
8 | "group": "RARBG",
9 | "hardcoded": true,
10 | "proper": true
11 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_053.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Interstellar",
3 | "year": 2014,
4 | "quality": "CAM",
5 | "codec": "x264",
6 | "audio": "AAC",
7 | "group": "CPG"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_054.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Guardians of the Galaxy",
3 | "year": 2014,
4 | "quality": "DVDRip",
5 | "audio": "Dual Audio",
6 | "container": "AVI"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_055.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Eliza Graves",
3 | "year": 2014,
4 | "resolution": "720p",
5 | "quality": "WEB-DL",
6 | "codec": "x264",
7 | "audio": "Dual Audio",
8 | "container": "MKV"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_056.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "WWE Monday Night Raw",
3 | "year": 2014,
4 | "quality": "PDTV",
5 | "codec": "x264",
6 | "group": "RKOFAN1990 -={SPARR",
7 | "widescreen": true
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_057.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Sons of Anarchy",
3 | "season": 1,
4 | "episode": 3
5 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_058.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "doctor who",
3 | "season": 8,
4 | "episode": 12,
5 | "year": 2005,
6 | "resolution": "720p",
7 | "quality": "hdtv",
8 | "codec": "x264",
9 | "group": "fov"
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_059.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "breaking bad",
3 | "season": 1,
4 | "episode": 1,
5 | "resolution": "720p",
6 | "quality": "bluray",
7 | "codec": "x264",
8 | "group": "reward"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_060.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Game of Thrones",
3 | "season": 4,
4 | "episode": 3
5 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_061.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "sons of anarchy",
3 | "season": 5,
4 | "episode": 10,
5 | "resolution": "480p",
6 | "quality": "BluRay",
7 | "codec": "x264",
8 | "group": "GAnGSteR",
9 | "website": "720pMkv.Com"
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_062.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Sons of Anarchy",
3 | "season": 7,
4 | "episode": 7,
5 | "resolution": "720p",
6 | "quality": "HDTV",
7 | "codec": "X264",
8 | "group": "DIMENSION",
9 | "website": "www.Speed.cd"
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_063.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Community",
3 | "season": 2,
4 | "episode": 20,
5 | "resolution": "720p",
6 | "language": "rus.eng"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_064.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Jungle Book",
3 | "year": 2016,
4 | "resolution": "1080p",
5 | "quality": "BRRip",
6 | "codec": "x264",
7 | "audio": "AAC",
8 | "group": "ETRG",
9 | "sbs": "SBS",
10 | "3d": true
11 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_065.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Ant-Man",
3 | "year": 2015,
4 | "resolution": "1080p",
5 | "quality": "BRRip",
6 | "codec": "x264",
7 | "audio": "AAC",
8 | "group": "m2g",
9 | "sbs": "Half-SBS",
10 | "3d": true
11 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_066.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Ice Age Collision Course",
3 | "year": 2016,
4 | "resolution": "720p",
5 | "quality": "HDRIP",
6 | "codec": "X264",
7 | "audio": "AC3"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_067.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Red Sonja Queen Of Plagues",
3 | "year": 2016,
4 | "quality": "BDRip",
5 | "codec": "x264",
6 | "group": "W4F[PRiME]"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_068.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Purge: Election Year",
3 | "year": 2016,
4 | "resolution": "720p",
5 | "quality": "HDRiP",
6 | "hardcoded": true,
7 | "size": "900MB"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_069.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "War Dogs",
3 | "year": 2016,
4 | "quality": "HDTS",
5 | "size": "600MB"
6 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_070.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Hateful Eight",
3 | "year": 2015,
4 | "resolution": "720p",
5 | "quality": "BluRay",
6 | "codec": "x265",
7 | "size": "999MB"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_071.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Boss",
3 | "year": 2016,
4 | "resolution": "720p",
5 | "quality": "BRRip",
6 | "codec": "x264",
7 | "audio": "AAC",
8 | "group": "ETRG",
9 | "unrated": true
10 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_072.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Return To Snowy River",
3 | "year": 1988,
4 | "quality": "DVDRip",
5 | "codec": "x264",
6 | "group": "W4F[PRiME]"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_073.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Akira",
3 | "year": 2016,
4 | "resolution": "720p",
5 | "codec": "x264",
6 | "audio": "AC3 - 5.1"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_074.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Ben Hur",
3 | "year": 2016,
4 | "quality": "TELESYNC",
5 | "codec": "x264",
6 | "audio": "AC3"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_075.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "The Secret Life of Pets",
3 | "year": 2016,
4 | "quality": "HDRiP",
5 | "codec": "x264",
6 | "audio": "AAC-LC",
7 | "group": "LEGi0N"
8 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_076.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Clockwork Planet",
3 | "episode": 10,
4 | "resolution": "480p",
5 | "container": "mkv",
6 | "website": "HorribleSubs"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_077.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Detective Conan",
3 | "episode": 862,
4 | "resolution": "1080p",
5 | "container": "mkv",
6 | "website": "HorribleSubs"
7 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_078.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "thomas and friends",
3 | "season": 19,
4 | "episode": 9,
5 | "quality": "hdtv",
6 | "codec": "x264",
7 | "group": "w4f[eztv]",
8 | "container": "mkv"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_079.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Blade Runner 2049",
3 | "year": 2017,
4 | "resolution": "1080p",
5 | "quality": "WEB-DL",
6 | "codec": "H264",
7 | "audio": "DD5.1",
8 | "group": "[rarbg.to]"
9 | }
10 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_080.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "2012",
3 | "year": 2009,
4 | "resolution": "1080p",
5 | "audio": "Dual Audio"
6 | }
7 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_081.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "2012",
3 | "year": 2009,
4 | "resolution": "1080p",
5 | "quality": "BrRip",
6 | "codec": "x264",
7 | "size": "1.7GB"
8 | }
9 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_082.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "2012",
3 | "year": 2009,
4 | "resolution": "720p",
5 | "quality": "BluRay",
6 | "codec": "x264",
7 | "audio": "Dual Audio"
8 | }
9 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_083.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Little Girls Love Big Ducks 11",
3 | "scene": 1,
4 | "year": 2024,
5 | "resolution": "540p",
6 | "quality": "WEB-DL",
7 | "studio": "Crave Media",
8 | "porn": true,
9 | "split_scenes": true
10 | }
11 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_084.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Deadpool & Wolverine",
3 | "year": 2024,
4 | "resolution": "4K",
5 | "quality": "WEB-DL",
6 | "bitrate": "768Kbps",
7 | "color_depth": "SDR",
8 | "audio": "AAC",
9 | "container": "mkv",
10 | "website": "www.1TamilMV.tf"
11 | }
12 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_085.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Delicious",
3 | "year": 2025,
4 | "quality": "WEB-DLRip",
5 | "container": "mkv",
6 | "codec": "x264",
7 | "studio": "NF",
8 | "dubbing": "MVO"
9 | }
10 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_086.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Bolshaya dvadcatka",
3 | "year": 2025,
4 | "quality": "WEB-DLRip",
5 | "container": "mkv",
6 | "studio": "AMZN",
7 | "avc": true
8 | }
9 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_087.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "How to Lose a Guy in 10 Days",
3 | "extra_title": "Как отделаться от парня за 10 дней",
4 | "year": 2003,
5 | "quality": "BDRip",
6 | "container": "mkv"
7 | }
8 |
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_088.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Этернавт - The Eternaut",
3 | "season": 1,
4 | "episode": 1,
5 | "year": 2025,
6 | "resolution": "1080p",
7 | "quality": "WEB-DL",
8 | "container": "mkv"
9 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_089.json:
--------------------------------------------------------------------------------
1 | {
2 | "Title": "Havoc",
3 | "year": 2025,
4 | "resolution": "1080p",
5 | "bitrate": "768Kbps",
6 | "codec": "x264",
7 | "website": "www.1TamilBlasters.moi",
8 | "size": "8.2GB",
9 | "container": "mkv",
10 | "avc": true
11 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/testdata/golden_file_090.json:
--------------------------------------------------------------------------------
1 | {
2 | "website": "designcode.io"
3 | }
--------------------------------------------------------------------------------
/services/parse_torrent_name/transformer.go:
--------------------------------------------------------------------------------
1 | package parsetorrentname
2 |
3 | import "strings"
4 |
5 | type Transformer interface {
6 | Transform(val string) (string, error)
7 | }
8 |
9 | type ReplaceTransformer struct {
10 | replacements map[string]string
11 | trimSuffixes []string
12 | trimPrefixes []string
13 | }
14 |
15 | func (t *ReplaceTransformer) Transform(val string) (string, error) {
16 | for k, v := range t.replacements {
17 | val = strings.Replace(val, k, v, -1)
18 | }
19 | for _, s := range t.trimSuffixes {
20 | val = strings.TrimSuffix(val, s)
21 | }
22 | for _, p := range t.trimPrefixes {
23 | val = strings.TrimPrefix(val, p)
24 | }
25 | val = strings.TrimSpace(val)
26 | return val, nil
27 | }
28 |
29 | func NewReplaceTransformer(replacements map[string]string, trimSuffixes []string, trimPrefixes []string) *ReplaceTransformer {
30 | return &ReplaceTransformer{
31 | replacements: replacements,
32 | trimSuffixes: trimSuffixes,
33 | trimPrefixes: trimPrefixes,
34 | }
35 | }
36 |
37 | var titleTransformer = NewReplaceTransformer(map[string]string{
38 | "_": " ",
39 | ".": " ",
40 | }, []string{
41 | "(",
42 | "[",
43 | "-",
44 | "--",
45 | "---",
46 | }, []string{
47 | ")",
48 | "]",
49 | "-",
50 | "--",
51 | "---",
52 | })
53 |
--------------------------------------------------------------------------------
/services/umami/helper.go:
--------------------------------------------------------------------------------
1 | package umami
2 |
3 | import (
4 | "github.com/urfave/cli"
5 | )
6 |
7 | var (
8 | UseFlag = "umami-use"
9 | SrcFlag = "umami-src"
10 | WebsiteIDFlag = "umami-website-id"
11 | HostUrlFlag = "umami-host-url"
12 | )
13 |
14 | func RegisterFlags(f []cli.Flag) []cli.Flag {
15 | return append(f,
16 | cli.BoolFlag{
17 | Name: UseFlag,
18 | Usage: "use umami",
19 | EnvVar: "USE_UMAMI",
20 | },
21 | cli.StringFlag{
22 | Name: WebsiteIDFlag,
23 | Usage: "umami website-id",
24 | EnvVar: "UMAMI_WEBSITE_ID",
25 | },
26 | cli.StringFlag{
27 | Name: HostUrlFlag,
28 | Usage: "umami host url",
29 | EnvVar: "UMAMI_HOST_URL",
30 | },
31 | )
32 | }
33 |
34 | type Helper struct {
35 | use bool
36 | WebsiteID string `json:"website_id,omitempty"`
37 | HostURL string `json:"host_url,omitempty"`
38 | }
39 |
40 | func NewHelper(cli *cli.Context) *Helper {
41 | return &Helper{
42 | use: cli.Bool(UseFlag),
43 | WebsiteID: cli.String(WebsiteIDFlag),
44 | HostURL: cli.String(HostUrlFlag),
45 | }
46 | }
47 |
48 | func (s *Helper) UseUmami() bool {
49 | return s.use
50 | }
51 |
52 | func (s *Helper) UmamiConfig() *Helper {
53 | return s
54 | }
55 |
--------------------------------------------------------------------------------
/services/web/context.go:
--------------------------------------------------------------------------------
1 | package web
2 |
3 | import (
4 | "github.com/gin-gonic/gin"
5 | "github.com/webtor-io/web-ui/handlers/geo"
6 | "github.com/webtor-io/web-ui/handlers/session"
7 | "github.com/webtor-io/web-ui/services/api"
8 | "github.com/webtor-io/web-ui/services/auth"
9 | "github.com/webtor-io/web-ui/services/claims"
10 | "github.com/webtor-io/web-ui/services/geoip"
11 | )
12 |
13 | type Context struct {
14 | Data any
15 | CSRF string
16 | SessionID string
17 | Err error
18 | User *auth.User
19 | Claims *claims.Data
20 | Geo *geoip.Data
21 | ApiClaims *api.Claims
22 | ginCtx *gin.Context
23 | }
24 |
25 | func (c *Context) WithData(obj any) *Context {
26 | nc := *c
27 | nc.Data = obj
28 | return &nc
29 | }
30 |
31 | func (c *Context) WithErr(err error) *Context {
32 | nc := *c
33 | nc.Err = err
34 | return &nc
35 | }
36 |
37 | func (s *Context) GetGinContext() *gin.Context {
38 | return s.ginCtx
39 | }
40 |
41 | func NewContext(c *gin.Context) *Context {
42 | user := auth.GetUserFromContext(c)
43 | cl := claims.GetFromContext(c)
44 | sess := session.GetFromContext(c)
45 | geoData := geo.GetFromContext(c)
46 | aCl := api.GetClaimsFromContext(c)
47 |
48 | return &Context{
49 | CSRF: sess.CSRF,
50 | User: user,
51 | Claims: cl,
52 | ApiClaims: aCl,
53 | SessionID: sess.ID,
54 | Geo: geoData,
55 | ginCtx: c,
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/services/web/web.go:
--------------------------------------------------------------------------------
1 | package web
2 |
3 | import (
4 | "fmt"
5 | "net"
6 | "net/http"
7 |
8 | "github.com/gin-gonic/gin"
9 | "github.com/pkg/errors"
10 | "github.com/urfave/cli"
11 |
12 | log "github.com/sirupsen/logrus"
13 | )
14 |
15 | const (
16 | webHostFlag = "host"
17 | webPortFlag = "port"
18 | )
19 |
20 | func RegisterFlags(f []cli.Flag) []cli.Flag {
21 | return append(f,
22 | cli.StringFlag{
23 | Name: webHostFlag,
24 | Usage: "listening host",
25 | Value: "",
26 | EnvVar: "WEB_HOST",
27 | },
28 | cli.IntFlag{
29 | Name: webPortFlag,
30 | Usage: "http listening port",
31 | Value: 8080,
32 | EnvVar: "WEB_PORT",
33 | },
34 | )
35 | }
36 |
37 | type Web struct {
38 | host string
39 | port int
40 | ln net.Listener
41 | r *gin.Engine
42 | }
43 |
44 | func (s *Web) Serve() error {
45 | addr := fmt.Sprintf("%s:%d", s.host, s.port)
46 | ln, err := net.Listen("tcp", addr)
47 | s.ln = ln
48 | if err != nil {
49 | return errors.Wrap(err, "failed to web listen to tcp connection")
50 | }
51 | log.Infof("serving web at %v", addr)
52 | return http.Serve(s.ln, s.r)
53 | }
54 |
55 | func (s *Web) Close() {
56 | log.Info("closing web")
57 | defer func() {
58 | log.Info("web closed")
59 | }()
60 | if s.ln != nil {
61 | _ = s.ln.Close()
62 | }
63 | }
64 |
65 | func New(c *cli.Context, r *gin.Engine) (*Web, error) {
66 | r.UseRawPath = true
67 |
68 | return &Web{
69 | host: c.String(webHostFlag),
70 | port: c.Int(webPortFlag),
71 | r: r,
72 | }, nil
73 | }
74 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | purge: ['./templates/**/*.html', './assets/src/**/*.js'],
4 | content: [],
5 | theme: {
6 | fontFamily: {
7 | 'baskerville': ['Libre Baskerville', 'serif'],
8 | },
9 | extend: {
10 | minWidth: {
11 | '80': '20rem',
12 | },
13 | },
14 | },
15 | }
16 |
--------------------------------------------------------------------------------
/templates/layouts/embed/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Webtor Player SDK Example
5 |
6 |
7 |
8 |
17 |
18 |
19 | {{ template "main" . }}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/templates/partials/button.html:
--------------------------------------------------------------------------------
1 | {{ define "button" }}
2 |
10 | {{ end }}
11 |
--------------------------------------------------------------------------------
/templates/partials/extend_base.html:
--------------------------------------------------------------------------------
1 | {{ define "head_extra" }}{{ end }}
2 | {{ define "get_extra" }}{{ end }}
3 | {{ define "embed_extra" }}{{ end }}
4 | {{ define "promo" }}{{ end }}
5 | {{ define "promo_example" }}
6 | ✨✨✨Get 25% off on ad removal and extra bandwidth until January 1, 2025.✨✨✨
7 | {{ end }}
8 | {{ define "get_ads" }}{{ end }}
9 | {{ define "embed_ads" }}{{ end }}
10 |
--------------------------------------------------------------------------------
/templates/partials/file.html:
--------------------------------------------------------------------------------
1 | {{ define "file" }}
2 | {{ with .Data }}
3 | # {{ .Item.Name }}
4 |
5 | {{ template "stream_button" $ }}
6 | {{ template "button" makeFileDownload $ . }}
7 |
8 |
9 | {{ end }}
10 | {{ end }}
--------------------------------------------------------------------------------
/templates/partials/footer.html:
--------------------------------------------------------------------------------
1 | {{ define "footer"}}
2 |
29 |
32 | {{ end }}
--------------------------------------------------------------------------------
/templates/partials/icons.html:
--------------------------------------------------------------------------------
1 | {{ define "icons" }}
2 | {{ if eq . "download" }}
3 |
6 | {{ else if eq . "preview" }}
7 |
11 | {{ else if eq . "stream" }}
12 |
15 | {{ end }}
16 | {{ end }}
--------------------------------------------------------------------------------
/templates/partials/library/button.html:
--------------------------------------------------------------------------------
1 | {{ define "library/button" }}
2 | {{ if .User | hasAuth }}
3 | {{ with .Data.Resource }}
4 | {{ if .InLibrary }}
5 |
11 | {{ else }}
12 |
18 | {{ end }}
19 | {{ end }}
20 | {{ else }}
21 |
26 | {{ end }}
27 | {{ end }}
28 |
--------------------------------------------------------------------------------
/templates/partials/library/list.html:
--------------------------------------------------------------------------------
1 | {{ define "library/list"}}
2 | {{ if eq .Data.Args.Section "torrents" }}
3 |
4 | {{ template "library/torrent_list" .Data.Items }}
5 |
6 | {{ else }}
7 |
8 | {{ template "library/video_list" .Data.Items }}
9 |
10 | {{ end }}
11 | {{ end }}
--------------------------------------------------------------------------------
/templates/partials/library/menu.html:
--------------------------------------------------------------------------------
1 | {{ define "library/menu" }}
2 |
7 | {{ end }}
8 |
--------------------------------------------------------------------------------
/templates/partials/library/sort.html:
--------------------------------------------------------------------------------
1 | {{ define "library/sort"}}
2 |
10 | {{ end }}
11 |
--------------------------------------------------------------------------------
/templates/partials/library/stars.html:
--------------------------------------------------------------------------------
1 | {{ define "library/stars" }}
2 |
3 | {{ range . }}
4 | {{ if eq .Value 0.0 }}
5 |
6 | {{ else }}
7 | {{ if .HalfStep }}
8 |
9 | {{ else }}
10 |
11 | {{ end }}
12 | {{ end }}
13 | {{ end }}
14 |
15 | {{ end }}
16 |
--------------------------------------------------------------------------------
/templates/partials/library/torrent_list.html:
--------------------------------------------------------------------------------
1 | {{ define "library/torrent_list" }}
2 |
7 | {{ end }}
--------------------------------------------------------------------------------
/templates/partials/library/video_list.html:
--------------------------------------------------------------------------------
1 | {{ define "library/video_list" }}
2 |
31 | {{ end }}
--------------------------------------------------------------------------------
/templates/partials/profile/tier.html:
--------------------------------------------------------------------------------
1 | {{ define "profile/tier" }}
2 |
3 |
4 |
5 |
Your tier is {{ .Claims.Context.Tier.Name }}
6 | {{ if eq .Claims.Claims.Connection.Rate 0 }}
7 |
You have no bandwidth limits!
8 | {{ else }}
9 |
Your bandwidth is {{ .Claims.Claims.Connection.Rate }}Mbps!
10 | {{ end }}
11 | {{ if .Claims | hasAds }}
12 |
You have ADS
13 | {{ else }}
14 |
You have no ADS!
15 | {{ end }}
16 |
17 |
18 |
19 | {{ end }}
20 |
--------------------------------------------------------------------------------
/templates/partials/stream_button.html:
--------------------------------------------------------------------------------
1 | {{ define "stream_button" }}
2 | {{ with .Data }}
3 | {{ if eq .Item.MediaFormat "video" }}
4 | {{ template "button" makeVideo $ . }}
5 | {{ else if eq .Item.MediaFormat "audio" }}
6 | {{ template "button" makeAudio $ . }}
7 | {{ else if eq .Item.MediaFormat "image" }}
8 | {{ template "button" makeImage $ . }}
9 | {{ end }}
10 | {{ end }}
11 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/action/download_file.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
8 | {{- if .Data.HasAds }}
9 | Your current download speed will be limited to {{ .Claims.Claims.Connection.Rate }}Mbps, donate to increase your speed and remove ads!
10 | {{- end }}
11 |
26 | {{ end }}
27 |
--------------------------------------------------------------------------------
/templates/views/action/download_torrent.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
11 |
14 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/action/post.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 | {{ if .Err }}
3 |
4 |
{{ .Err | log | shortErr }}
5 |
ok
6 |
7 | {{ end }}
8 | {{ if has .Data "Job" }}
9 |
12 | {{ end }}
13 | {{ "action.js" | asset }}
14 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/action/preview_image.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 | {{ with .Data.ExportTag }}
3 |
4 | {{ end }}
5 | {{ "action/image.js" | asset }}
6 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/action/stream_audio.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 | {{ $MediaProbe := .Data.MediaProbe}}
3 | {{ with .Data.ExportTag }}
4 |
15 | {{ end }}
16 | {{ "mediaelement.css" | asset }}
17 | {{ "action/stream.js" | asset }}
18 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/auth/login.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Login{{ end }}
2 | {{ define "main" }}
3 |
4 | {{ if eq .Data.Instruction "library" }}
5 |
Authorization is required to access your library.
6 | {{ end }}
7 |
Enter your email to receive a one-time login link.
8 |
No password needed — just click the link in your inbox and you’re in!
9 |
10 |
14 |
20 | {{ "auth/login.js" | asset }}
21 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/auth/logout.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Logout{{ end }}
2 | {{ define "main" }}
3 |
9 | {{ "auth/logout.js" | asset }}
10 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/auth/refresh.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Refresh token{{ end }}
2 | {{ define "main" }}
3 | {{ "auth/refresh.js" | asset }}
4 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/auth/verify.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Check code{{ end }}
2 | {{ define "main" }}
3 |
13 | {{ "auth/verify.js" | asset }}
14 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/embed/ads.html:
--------------------------------------------------------------------------------
1 | {{ template "embed_ads" .}}
2 | {{ "embed/ads.js" | asset }}
3 |
--------------------------------------------------------------------------------
/templates/views/embed/example/basic.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/events.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 |
16 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/features.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 |
15 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/embed/example/fixed_size.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/fixed_size2.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/fixed_size3.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/imdb.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/index.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ range .Data }}
4 | -
5 | {{ .Name }}
6 |
7 | {{ end }}
8 |
9 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/embed/example/nocontrols.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/path.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/poster.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/pwd.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/pwd_with_file.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/responsive.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/responsive2.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
7 |
8 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/script.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 |
11 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/subtitles.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
6 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/torrent_url.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/example/user_lang.html:
--------------------------------------------------------------------------------
1 | {{ define "main" }}
2 |
3 | {{ end}}
--------------------------------------------------------------------------------
/templates/views/embed/get.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
42 | {{ "embed/check.js" | asset }}
43 |
44 |
45 |
50 |
51 |
--------------------------------------------------------------------------------
/templates/views/embed/post.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 | {{ template "embed_extra" . }}
16 | {{ "embed.css" | asset }}
17 | {{ "embed/index.js" | asset }}
18 |
19 |
20 | {{ if .Err }}
21 |
22 |
{{ .Err | log | shortErr }}
23 |
ok
24 |
25 | {{ end }}
26 | {{ with .Data }}
27 | {{ if has . "Job" }}
28 |
31 | {{ end }}
32 | {{ end }}
33 |
34 |
--------------------------------------------------------------------------------
/templates/views/ext/download.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | loading torrent | webtor.io
5 |
10 | {{ "ext/download.js" | asset }}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/views/ext/magnet.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | loading magnet... | webtor.io
5 |
10 | {{ "ext/magnet.js" | asset }}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/templates/views/instructions/stremio.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}
2 | Stremio Integration
3 | {{ end }}
4 | {{ define "main" }}
5 |
6 |
How to connect Webtor to Stremio
7 |
8 |
You can stream your personal torrent library from Webtor directly in Stremio. Here's how to do it:
9 |
10 |
11 | - Copy your personal addon link from your Webtor profile.
12 | - Open Stremio and go to the Add-ons section.
13 | - Click the Add Addon button in the top-right corner.
14 | - Paste the addon link and press Enter. Done!
15 |
16 |
17 |
Once installed, your library will appear in Stremio under the Webtor.io addon – ready to stream.
18 |
19 |
20 | ⚠️ Note: This feature is available only for paid users.
21 |
22 |
23 |
24 | ⏳ Streaming via Webtor may differ from regular Stremio addons. It can take some time to warm up the torrent before playback starts.
25 |
26 |
27 | {{ end }}
28 |
--------------------------------------------------------------------------------
/templates/views/library/index.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Library{{ end }}
2 | {{ define "main" }}
3 | {{ if .Claims | hasAds }}{{ template "promo" . }}{{ end }}
4 |
7 |
8 | {{ template "library/menu" .Data.Args | makeMenu }}
9 | {{ template "library/sort" .Data.Args | makeSort }}
10 |
11 |
12 | {{ if .Data.Items }}
13 | {{ template "library/list" . }}
14 | {{ else }}
15 |
16 |
No torrents yet! Hit “Add to Library” under any loaded torrent to get started.
17 |
18 | {{ end }}
19 | Add to library
20 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/profile/get.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Profile{{ end }}
2 | {{ define "main" }}
3 | {{ if .Claims | hasAds }}{{ template "promo" . }}{{ end }}
4 |
5 | {{ template "profile/tier" $ }}
6 |
7 |
8 |
9 | {{ template "profile/stremio" $ }}
10 |
11 |
12 |
15 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/resource/get.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}
2 | {{ with .Data }}
3 | {{ if has . "Item" }}
4 | {{ .Item.PathStr }} | {{ .Resource.Name }}
5 | {{ else }}
6 | {{ .Resource.Name }}
7 | {{ end }}
8 | {{ end }}
9 | {{ end }}
10 | {{ define "main" }}
11 | {{ if .Claims | hasAds }}{{ template "promo" . }}{{ end }}
12 | {{ with .Data }}
13 | {{ if .Item }}
14 |
15 | {{ template "file" $ }}
16 |
17 | {{ end }}
18 | {{ if and ($.Claims | hasAds) (not (.Resource.MagnetURI | isDemoMagnet)) }}{{ template "get_ads" $ }}{{ end }}
19 | {{ if and .Item .List }}
20 |
21 | {{ end }}
22 | {{ if .List }}
23 |
24 | {{ template "list" $ }}
25 |
26 | {{ end }}
27 |
28 |
29 | {{ template "library/button" $ }}
30 |
31 |
32 | {{ template "button" makeTorrentDownload $ . }}
33 |
34 |
35 |
36 | {{ end }}
37 | {{ template "get_extra" . }}
38 | {{ "resource/get.js" | asset }}
39 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/support/form.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Support{{ end }}
2 | {{ define "main" }}
3 | Support
4 | {{ if .Err }}
5 |
6 |
{{ .Err | log | shortErr }}
7 |
ok
8 |
9 | {{ end }}
10 | {{ with .Data }}
11 |
31 | {{ end }}
32 | {{ "support.js" | asset }}
33 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/support/success.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Support{{ end }}
2 | {{ define "main" }}
3 | Support
4 |
8 | {{ end }}
--------------------------------------------------------------------------------
/templates/views/tests/theme_switcher.html:
--------------------------------------------------------------------------------
1 | {{ define "title" }}Theme switcher{{ end }}
2 | {{ define "main" }}
3 |
8 | {{ end }}
--------------------------------------------------------------------------------