From 31c26efd3ab382a026b20c0eff5b166d990b551f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Dastres=20Gallardo?= Date: Tue, 28 Dec 2021 16:31:04 -0300 Subject: [PATCH] added initial support for animeflv --- .../AnimeFLV/AnimeFlv+Anime.swift | 98 +++++++++++++++++ .../AnimeFLV/AnimeFlv+Episode.swift | 48 ++++++++ .../AnimeFLV/AnimeFlv+Featured.swift | 91 +++++++++++++++ .../AnimeFLV/AnimeFlv+Search.swift | 104 ++++++++++++++++++ .../AnimeSources/AnimeFLV/AnimeFlv.swift | 61 ++++++++++ .../NativeSources.swift | 1 + .../AnimeFlv Site Icon.imageset/Contents.json | 21 ++++ .../AnimeFlv Site Icon.imageset/animeflv.png | Bin 0 -> 22919 bytes 8 files changed, 424 insertions(+) create mode 100644 Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Anime.swift create mode 100644 Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Episode.swift create mode 100644 Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Featured.swift create mode 100644 Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Search.swift create mode 100644 Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv.swift create mode 100644 NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/Contents.json create mode 100644 NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/animeflv.png diff --git a/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Anime.swift b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Anime.swift new file mode 100644 index 00000000..85a6a15c --- /dev/null +++ b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Anime.swift @@ -0,0 +1,98 @@ +// +// This file is part of the NineAnimator project. +// +// Copyright © 2018-2020 Marcus Zhou. All rights reserved. +// +// NineAnimator is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// NineAnimator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with NineAnimator. If not, see . +// + +import Foundation +import NineAnimatorCommon +import SwiftSoup + +extension NASourceAnimeFlv { + func anime(from link: AnimeLink) -> NineAnimatorPromise { + self.requestManager.request( + url: link.link, handling: .browsing) + .responseString + .then { + responseContent -> Anime in + let bowl = try SwiftSoup.parse(responseContent) + let animeTitle = try bowl.select("h1.Title").text() + let animeArtworkURL = try URL( + string: bowl.select("figure.Image > img").attr("src"), + relativeTo: self.endpointURL + ) ?? link.image + let reconstructedAnimeLink = AnimeLink( + title: animeTitle, + link: link.link, + image: animeArtworkURL, + source: self + ) + // List of episode + let episodeList = try bowl.select("li.Episode").compactMap { + episodeElement -> (identifier: String, episodeNumber: String) in + let episodeIdentifier = "\(self.endpointURL)\(try episodeElement.select("a").attr("href"))" + let episodeNumber = try episodeElement + .select("a") + .text() + .replacingOccurrences(of: animeTitle, with: "") + return (episodeIdentifier, episodeNumber) + } .reversed() + + if episodeList.isEmpty { + throw NineAnimatorError.responseError("No episodes found for this anime") + } + + // Collection of episodes + var episodeCollection = Anime.EpisodesCollection() + + // We incorrectly assume each server contains every episode + for (serverIdentifier, _) in NASourceAnimeFlv.knownServers { + var currentCollection = [EpisodeLink]() + + for (episodeIdentifier, episodeName) in episodeList { + let currentEpisodeLink = EpisodeLink( + identifier: episodeIdentifier, + name: episodeName, + server: serverIdentifier, + parent: reconstructedAnimeLink + ) + currentCollection.append(currentEpisodeLink) + } + + episodeCollection[serverIdentifier] = currentCollection.reversed() + } + + // Information + let animeSynopsis = try bowl.select("header > p:nth-child(3)").text().replacingOccurrences(of: "Sinopsis: ", with: "") + + // Attributes + var additionalAnimeAttributes = [Anime.AttributeKey: Any]() + + let rating = try bowl.select("#votes_prmd").text() + additionalAnimeAttributes[.rating] = Float(rating) ?? 0 + additionalAnimeAttributes[.ratingScale] = Float(5.0) + + return Anime( + reconstructedAnimeLink, + alias: "", + additionalAttributes: additionalAnimeAttributes, + description: animeSynopsis, + on: NASourceAnimeFlv.knownServers, + episodes: episodeCollection + ) + } + } +} diff --git a/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Episode.swift b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Episode.swift new file mode 100644 index 00000000..db16292d --- /dev/null +++ b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Episode.swift @@ -0,0 +1,48 @@ +// +// This file is part of the NineAnimator project. +// +// Copyright © 2018-2020 Marcus Zhou. All rights reserved. +// +// NineAnimator is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// NineAnimator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with NineAnimator. If not, see . +// + +import Foundation +import NineAnimatorCommon +import SwiftSoup + +extension NASourceAnimeFlv { + static let knownServers = [ + "yuserver": "YUserver" + ] + + static let urlRegex = try! NSRegularExpression(pattern: "https:\\\\/\\\\/www.+?(?=\")") + + func episode(from link: EpisodeLink, with anime: Anime) -> NineAnimatorPromise { + self.requestManager.request(url: link.identifier, handling: .browsing) + .responseString + .then { + responseContent in + let bowl = try SwiftSoup.parse(responseContent) + let scriptText = try bowl.select("#AnimeFlv > script:nth-child(16)").outerHtml() + let iframeURLString = try (NASourceAnimeFlv.urlRegex.firstMatch(in: scriptText)) + .tryUnwrap()[0].replacingOccurrences(of: "\\", with: "") + let iframeURL = try URL(string: iframeURLString).tryUnwrap() + return Episode( + link, + target: iframeURL, + parent: anime + ) + } + } +} diff --git a/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Featured.swift b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Featured.swift new file mode 100644 index 00000000..158870c2 --- /dev/null +++ b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Featured.swift @@ -0,0 +1,91 @@ +// +// This file is part of the NineAnimator project. +// +// Copyright © 2018-2020 Marcus Zhou. All rights reserved. +// +// NineAnimator is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// NineAnimator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with NineAnimator. If not, see . +// + +import Foundation +import NineAnimatorCommon +import SwiftSoup + +extension NASourceAnimeFlv { + func featured() -> NineAnimatorPromise { + self.requestManager.request( + url: endpointURL, + handling: .browsing + ).responseString.then { + responseContent in + let bowl = try SwiftSoup.parse(responseContent) + let featuredAnime = try bowl.select("ul.List-Animes") + .first() + .tryUnwrap(NineAnimatorError.decodeError("Cannot retrieve featured anime")) + .select("li") + .map { + animeContainer -> AnimeLink in + + let animeArtworkURL = try URL( + string: animeContainer.select("a > figure.Image > img").attr("src"), + relativeTo: self.endpointURL + ) ?? NineAnimator.placeholderArtworkUrl + let animeLink = try URL( + string: animeContainer.select("a").attr("href"), + relativeTo: self.endpointURL + ).tryUnwrap(NineAnimatorError.urlError) + + let animeTitle = try animeContainer.select("a h2.Title").text() + return AnimeLink( + title: animeTitle, + link: animeLink, + image: animeArtworkURL, + source: self + ) + } + /* + let ongoingAnime = try bowl.select("ul.List-Episodes") + .first() + .tryUnwrap(NineAnimatorError.decodeError("Cannot retrieve latest anime")) + .select("li") + .map { + animeContainer -> AnimeLink in + + let animeArtworkURL = try URL( + string: animeContainer.select("a figure.Image > img").attr("src"), + relativeTo: self.endpointURL + ) ?? NineAnimator.placeholderArtworkUrl + + let animeLink = try URL( + string: animeContainer.select("a").attr("href"), + relativeTo: self.endpointURL + ).tryUnwrap(NineAnimatorError.urlError) + + let animeTitle = try animeContainer.select("a h2.Title").text() + + return AnimeLink( + title: animeTitle, + link: animeLink, + image: animeArtworkURL, + source: self + ) + } + */ + + return BasicFeaturedContainer( + featured: featuredAnime, + latest: [] + ) + } + } +} diff --git a/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Search.swift b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Search.swift new file mode 100644 index 00000000..959da0f4 --- /dev/null +++ b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv+Search.swift @@ -0,0 +1,104 @@ +// +// This file is part of the NineAnimator project. +// +// Copyright © 2018-2020 Marcus Zhou. All rights reserved. +// +// NineAnimator is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// NineAnimator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with NineAnimator. If not, see . +// + +import Foundation +import NineAnimatorCommon +import SwiftSoup + +extension NASourceAnimeFlv { + class SearchAgent: ContentProvider { + var title: String + + var totalPages: Int? { 1 } + var availablePages: Int { _results == nil ? 0 : 1 } + var moreAvailable: Bool { _results == nil } + + weak var delegate: ContentProviderDelegate? + private var parent: NASourceAnimeFlv + private var performingTask: NineAnimatorAsyncTask? + private var _results: [AnimeLink]? + + func links(on page: Int) -> [AnyLink] { + page == 0 ? _results?.map { .anime($0) } ?? [] : [] + } + + func more() { + if performingTask == nil { + // Animehub includes the search title in the URL path, rather than as a URL query param. + let encodedTitle = self.title.replacingOccurrences(of: " ", with: "+") + + performingTask = parent.requestManager.request( + "/browse?q=\(encodedTitle)", + handling: .browsing + ).responseString.then { + [parent] responseContent -> [AnimeLink]? in + try SwiftSoup.parse(responseContent) + .select("ul.List-Animes > li.Anime").compactMap { + animeContainer -> AnimeLink? in + let animeArtworkURL = try URL( + string: animeContainer.select("a > figure.Image > img").attr("src"), + relativeTo: self.parent.endpointURL + ) ?? NineAnimator.placeholderArtworkUrl + + let animeLink = try URL( + string: animeContainer.select("a").attr("href"), + relativeTo: self.parent.endpointURL + ).tryUnwrap(NineAnimatorError.urlError) + + let animeTitle = try animeContainer.select("a > h2.Title").text() + + return AnimeLink( + title: animeTitle, + link: animeLink, + image: animeArtworkURL, + source: parent + ) + } + } .then { + results -> [AnimeLink] in + if results.isEmpty { + throw NineAnimatorError.searchError("No results found") + } else { return results } + } .error { + [weak self] in + guard let self = self else { return } + + // Reset performing task if the error is not 404 + if !($0 is NineAnimatorError.SearchError) { + self.performingTask = nil + } + + self.delegate?.onError($0, from: self) + } .finally { + [weak self] in + guard let self = self else { return } + self._results = $0 + self.delegate?.pageIncoming(0, from: self) + } + } + } + init(_ query: String, withParent parent: NASourceAnimeFlv) { + self.parent = parent + self.title = query + } + } + func search(keyword: String) -> ContentProvider { + SearchAgent(keyword, withParent: self) + } +} diff --git a/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv.swift b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv.swift new file mode 100644 index 00000000..d2c28049 --- /dev/null +++ b/Modules/Sources/NineAnimatorNativeSources/AnimeSources/AnimeFLV/AnimeFlv.swift @@ -0,0 +1,61 @@ +// +// This file is part of the NineAnimator project. +// +// Copyright © 2018-2020 Marcus Zhou. All rights reserved. +// +// NineAnimator is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// NineAnimator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with NineAnimator. If not, see . +// + +import Foundation +import NineAnimatorCommon + +#if canImport(UIKit) +import UIKit +#elseif canImport(AppKit) +import AppKit +#endif + +class NASourceAnimeFlv: BaseSource, Source, PromiseSource { + var name: String { "animeflv.net" } + + var aliases: [String] { [] } + + #if canImport(UIKit) + var siteLogo: UIImage { #imageLiteral(resourceName: "AnimeFlv Site Icon") } + #elseif canImport(AppKit) + var siteLogo: NSImage { #imageLiteral(resourceName: "AnimeFlv Site Icon") } + #endif + + var siteDescription: String { + "El mejor portal de anime online para latinoamérica, encuentra animes clásicos, animes del momento, animes más populares y mucho más, todo en animeflv, tu fuente de anime diaria." + } + + var preferredAnimeNameVariant: KeyPath { + \.romaji + } + + override var endpoint: String { "https://m.animeflv.net" } + + func suggestProvider(episode: Episode, forServer server: Anime.ServerIdentifier, withServerName name: String) -> VideoProviderParser? { + VideoProviderRegistry.default.provider(for: name) + } + + func link(from url: URL) -> NineAnimatorPromise { + .fail() + } + + override required init(with parent: NineAnimator) { + super.init(with: parent) + } +} diff --git a/Modules/Sources/NineAnimatorNativeSources/NativeSources.swift b/Modules/Sources/NineAnimatorNativeSources/NativeSources.swift index 7f7490fb..3e13313a 100644 --- a/Modules/Sources/NineAnimatorNativeSources/NativeSources.swift +++ b/Modules/Sources/NineAnimatorNativeSources/NativeSources.swift @@ -46,6 +46,7 @@ public enum NativeSources { registry.register(sourceType: NASourceMonosChinos.self) registry.register(sourceType: NASourceAnimeSaturn.self) registry.register(sourceType: NASourceAnimeWorld.self) + registry.register(sourceType: NASourceAnimeFlv.self) // Disabled sources registry.register(sourceType: NASourceWonderfulSubs.self) diff --git a/NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/Contents.json b/NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/Contents.json new file mode 100644 index 00000000..c013f7a0 --- /dev/null +++ b/NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "animeflv.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/animeflv.png b/NineAnimator/Assets.xcassets/AnimeFlv Site Icon.imageset/animeflv.png new file mode 100644 index 0000000000000000000000000000000000000000..9aa710fea9e75dd7d535d9ae314edde4eab5005c GIT binary patch literal 22919 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

U2{!LI_1P2E% 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 literal 0 HcmV?d00001