From 6c26812b92442a8cdcb822ce10bd769f721c8a96 Mon Sep 17 00:00:00 2001 From: Simon Ding Date: Sun, 11 Aug 2024 19:18:27 +0800 Subject: [PATCH] feat: filter resources that is qiangban --- db/const.go | 27 ++++++++++++++------------- pkg/metadata/movie.go | 18 ++++++++++++++++++ server/core/scheduler.go | 7 +++++++ server/core/torrent.go | 4 ++++ server/resources.go | 10 +++++++++- server/setting.go | 12 +++++++++++- ui/lib/providers/settings.dart | 17 ++++++++++++++--- ui/lib/settings/general.dart | 19 ++++++++++++++++--- 8 files changed, 93 insertions(+), 21 deletions(-) diff --git a/db/const.go b/db/const.go index b675fd0..3a1bb05 100644 --- a/db/const.go +++ b/db/const.go @@ -3,27 +3,28 @@ package db var Version = "undefined" const ( - SettingTmdbApiKey = "tmdb_api_key" - SettingLanguage = "language" - SettingJacketUrl = "jacket_url" - SettingJacketApiKey = "jacket_api_key" - SettingDownloadDir = "download_dir" - SettingLogLevel = "log_level" - SettingProxy = "proxy" + SettingTmdbApiKey = "tmdb_api_key" + SettingLanguage = "language" + SettingJacketUrl = "jacket_url" + SettingJacketApiKey = "jacket_api_key" + SettingDownloadDir = "download_dir" + SettingLogLevel = "log_level" + SettingProxy = "proxy" SettingPlexMatchEnabled = "plexmatch_enabled" + SettingAllowQiangban = "filter_qiangban" ) const ( SettingAuthEnabled = "auth_enbled" - SettingUsername = "auth_username" - SettingPassword = "auth_password" + SettingUsername = "auth_username" + SettingPassword = "auth_password" ) const ( IndexerTorznabImpl = "torznab" - DataPath = "./data" - ImgPath = DataPath + "/img" - LogPath = DataPath + "/logs" + DataPath = "./data" + ImgPath = DataPath + "/img" + LogPath = DataPath + "/logs" ) const ( @@ -33,4 +34,4 @@ const ( type ResolutionType string -const JwtSerectKey = "jwt_secrect_key" \ No newline at end of file +const JwtSerectKey = "jwt_secrect_key" diff --git a/pkg/metadata/movie.go b/pkg/metadata/movie.go index 0a346a3..23acf4f 100644 --- a/pkg/metadata/movie.go +++ b/pkg/metadata/movie.go @@ -11,6 +11,7 @@ type MovieMetadata struct { Name string Year int Resolution string + IsQingban bool } func ParseMovie(name string) *MovieMetadata { @@ -50,5 +51,22 @@ func ParseMovie(name string) *MovieMetadata { if len(resMatches) > 0 { meta.Resolution = resMatches[0] } + meta.IsQingban = isQiangban(name) return meta } + +// https://en.wikipedia.org/wiki/Pirated_movie_release_types +func isQiangban(name string) bool { + qiangbanFilter := []string{"CAM-Rip", "CAM", "HDCAM", "TS", "HDTS", "TELESYNC", "PDVD", "PreDVDRip", "TC", "HDTC", "TELECINE", "WP", "WORKPRINT"} + re := regexp.MustCompile(`\W`) + name = re.ReplaceAllString(strings.ToLower(name), " ") + fields := strings.Fields(name) + for _, q := range qiangbanFilter { + for _, f := range fields { + if strings.ToLower(q) == strings.ToLower(f) { + return true + } + } + } + return false +} diff --git a/server/core/scheduler.go b/server/core/scheduler.go index 01fd633..3fb2f39 100644 --- a/server/core/scheduler.go +++ b/server/core/scheduler.go @@ -3,6 +3,7 @@ package core import ( "fmt" "path/filepath" + "polaris/db" "polaris/ent" "polaris/ent/episode" "polaris/ent/history" @@ -276,11 +277,17 @@ func (c *Client) downloadMovieSingleEpisode(ep *ent.Episode) error { if err != nil { return errors.Wrap(err, "connect transmission") } + qiangban := c.db.GetSetting(db.SettingAllowQiangban) + allowQiangban := false + if qiangban == "true" { + allowQiangban = false + } res, err := SearchMovie(c.db, &SearchParam{ MediaId: ep.MediaID, CheckFileSize: true, CheckResolution: true, + FilterQiangban: !allowQiangban, }) if err != nil { diff --git a/server/core/torrent.go b/server/core/torrent.go index b2aa647..66b5a2f 100644 --- a/server/core/torrent.go +++ b/server/core/torrent.go @@ -23,6 +23,7 @@ type SearchParam struct { Episodes []int //for tv CheckResolution bool CheckFileSize bool + FilterQiangban bool //for movie, 是否过滤枪版电影 } func SearchTvSeries(db1 *db.Client, param *SearchParam) ([]torznab.Result, error) { @@ -150,6 +151,9 @@ func SearchMovie(db1 *db.Client, param *SearchParam) ([]torznab.Result, error) { if !torrentSizeOk(movieDetail, r.Size, param) { continue } + if param.FilterQiangban && meta.IsQingban { //过滤枪版电影 + continue + } ss := strings.Split(movieDetail.AirDate, "-")[0] year, _ := strconv.Atoi(ss) diff --git a/server/resources.go b/server/resources.go index dcc6b95..8900fb9 100644 --- a/server/resources.go +++ b/server/resources.go @@ -2,6 +2,7 @@ package server import ( "fmt" + "polaris/db" "polaris/ent/media" "polaris/log" "polaris/pkg/torznab" @@ -77,8 +78,15 @@ func (s *Server) SearchAvailableTorrents(c *gin.Context) (interface{}, error) { } } else { log.Info("search movie %d", in.ID) + qiangban := s.db.GetSetting(db.SettingAllowQiangban) + allowQiangban := false + if qiangban == "true" { + allowQiangban = true + } + res, err = core.SearchMovie(s.db, &core.SearchParam{ - MediaId: in.ID, + MediaId: in.ID, + FilterQiangban: !allowQiangban, }) if err != nil { if err.Error() == "no resource found" { diff --git a/server/setting.go b/server/setting.go index 3799d8c..a989e62 100644 --- a/server/setting.go +++ b/server/setting.go @@ -19,6 +19,7 @@ type GeneralSettings struct { LogLevel string `json:"log_level"` Proxy string `json:"proxy"` EnablePlexmatch bool `json:"enable_plexmatch"` + AllowQiangban bool `json:"allow_qiangban"` } func (s *Server) SetSetting(c *gin.Context) (interface{}, error) { @@ -54,6 +55,13 @@ func (s *Server) SetSetting(c *gin.Context) (interface{}, error) { } s.db.SetSetting(db.SettingProxy, in.Proxy) + + if in.AllowQiangban { + s.db.SetSetting(db.SettingAllowQiangban, "true") + } else { + s.db.SetSetting(db.SettingAllowQiangban, "false") + } + return nil, nil } @@ -62,12 +70,14 @@ func (s *Server) GetSetting(c *gin.Context) (interface{}, error) { downloadDir := s.db.GetSetting(db.SettingDownloadDir) logLevel := s.db.GetSetting(db.SettingLogLevel) plexmatchEnabled := s.db.GetSetting(db.SettingPlexMatchEnabled) + allowQiangban := s.db.GetSetting(db.SettingAllowQiangban) return &GeneralSettings{ TmdbApiKey: tmdb, DownloadDir: downloadDir, LogLevel: logLevel, Proxy: s.db.GetSetting(db.SettingProxy), EnablePlexmatch: plexmatchEnabled == "true", + AllowQiangban: allowQiangban == "true", }, nil } @@ -218,4 +228,4 @@ func (s *Server) EditMediaMetadata(c *gin.Context) (interface{}, error) { return nil, errors.Wrap(err, "save db") } return "success", nil -} \ No newline at end of file +} diff --git a/ui/lib/providers/settings.dart b/ui/lib/providers/settings.dart index c79816e..52db8c5 100644 --- a/ui/lib/providers/settings.dart +++ b/ui/lib/providers/settings.dart @@ -52,13 +52,15 @@ class GeneralSetting { String? logLevel; String? proxy; bool? enablePlexmatch; + bool? allowQiangban; GeneralSetting( {this.tmdbApiKey, this.downloadDIr, this.logLevel, this.proxy, - this.enablePlexmatch}); + this.enablePlexmatch, + this.allowQiangban}); factory GeneralSetting.fromJson(Map json) { return GeneralSetting( @@ -66,6 +68,7 @@ class GeneralSetting { downloadDIr: json["download_dir"], logLevel: json["log_level"], proxy: json["proxy"], + allowQiangban: json["allow_qiangban"] ?? false, enablePlexmatch: json["enable_plexmatch"] ?? false); } @@ -76,6 +79,7 @@ class GeneralSetting { data["log_level"] = logLevel; data["proxy"] = proxy; data["enable_plexmatch"] = enablePlexmatch; + data["allow_qiangban"] = allowQiangban; return data; } } @@ -134,7 +138,14 @@ class Indexer { double? seedRatio; bool? disabled; - Indexer({this.name, this.url, this.apiKey, this.id, this.priority=50, this.seedRatio=0, this.disabled}); + Indexer( + {this.name, + this.url, + this.apiKey, + this.id, + this.priority = 50, + this.seedRatio = 0, + this.disabled}); Indexer.fromJson(Map json) { name = json['name']; @@ -142,7 +153,7 @@ class Indexer { apiKey = json['api_key']; id = json["id"]; priority = json["priority"]; - seedRatio = json["seed_ratio"]??0; + seedRatio = json["seed_ratio"] ?? 0; disabled = json["disabled"] ?? false; } Map toJson() { diff --git a/ui/lib/settings/general.dart b/ui/lib/settings/general.dart index 12b047c..1e9550f 100644 --- a/ui/lib/settings/general.dart +++ b/ui/lib/settings/general.dart @@ -34,7 +34,8 @@ class _GeneralState extends ConsumerState { "download_dir": v.downloadDIr, "log_level": v.logLevel, "proxy": v.proxy, - "enable_plexmatch": v.enablePlexmatch + "enable_plexmatch": v.enablePlexmatch, + "allow_qiangban": v.allowQiangban, }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -81,8 +82,19 @@ class _GeneralState extends ConsumerState { ), SizedBox( width: 300, - child: FormBuilderSwitch(decoration: const InputDecoration(icon: Icon(Icons.token)), - name: "enable_plexmatch", title: const Text("Plex 刮削支持")), + child: FormBuilderSwitch( + decoration: + const InputDecoration(icon: Icon(Icons.token)), + name: "enable_plexmatch", + title: const Text("Plex 刮削支持")), + ), + SizedBox( + width: 300, + child: FormBuilderSwitch( + decoration: + const InputDecoration(icon: Icon(Icons.token)), + name: "allow_qiangban", + title: const Text("是否下载枪版资源")), ), Center( child: Padding( @@ -102,6 +114,7 @@ class _GeneralState extends ConsumerState { downloadDIr: values["download_dir"], logLevel: values["log_level"], proxy: values["proxy"], + allowQiangban: values["allow_qiangban"], enablePlexmatch: values["enable_plexmatch"])) .then((v) => showSnakeBar("更新成功"));