├── .idea ├── .name ├── .gitignore ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── vcs.xml ├── compiler.xml ├── kotlinc.xml ├── migrations.xml ├── gradle.xml └── jarRepositories.xml ├── AnimeScrapCommon ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── talent │ │ │ └── animescrap_common │ │ │ ├── model │ │ │ ├── SimpleAnime.kt │ │ │ ├── UpdateDetails.kt │ │ │ ├── AnimeDetails.kt │ │ │ ├── AnimeStreamLink.kt │ │ │ └── AnimePlayingDetails.kt │ │ │ ├── source │ │ │ └── AnimeSource.kt │ │ │ ├── sourceutils │ │ │ ├── AndroidCookieJar.kt │ │ │ ├── WebViewClientCompat.kt │ │ │ ├── DDosGuardIntreceptor.kt │ │ │ ├── WebViewInterceptor.kt │ │ │ └── CloudflareInterceptor.kt │ │ │ └── utils │ │ │ └── Utils.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── talent │ │ │ └── animescrap_common │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── talent │ │ └── animescrap_common │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── animeSources ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── talent │ │ │ └── animescrapsources │ │ │ ├── SourceSelector.kt │ │ │ └── animesources │ │ │ ├── sourceCommonExtractors │ │ │ └── AsianExtractor.kt │ │ │ ├── AsianLoad.kt │ │ │ ├── MyAsianTvSource.kt │ │ │ ├── KissKhSource.kt │ │ │ └── KawaiifuSource.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── talent │ │ │ └── animescrapsources │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── talent │ │ └── animescrapsources │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── drawable │ │ │ ├── cc.png │ │ │ ├── bottom_nav_drawable.xml │ │ │ ├── shadow_gradient.xml │ │ │ ├── select_latest.xml │ │ │ ├── select_fav.xml │ │ │ ├── icon_triangle.xml │ │ │ ├── subs_toggle_image_selector.xml │ │ │ ├── gradient_shape.xml │ │ │ ├── ic_baseline_navigate_before_24.xml │ │ │ ├── ic_baseline_navigate_next_24.xml │ │ │ ├── ic_baseline_play_arrow_24.xml │ │ │ ├── ic_baseline_pause_24.xml │ │ │ ├── ic_baseline_fast_forward_24.xml │ │ │ ├── ic_trending_black_24.xml │ │ │ ├── ic_baseline_fast_rewind_24.xml │ │ │ ├── ic_baseline_arrow_back_24.xml │ │ │ ├── ic_baseline_height_24.xml │ │ │ ├── ic_baseline_fullscreen_24.xml │ │ │ ├── ic_favorite_black_24.xml │ │ │ ├── ic_broken_image.xml │ │ │ ├── ic_play.xml │ │ │ ├── background_selector.xml │ │ │ ├── background_selector_accent.xml │ │ │ ├── ic_search_black_24.xml │ │ │ ├── ic_baseline_zoom_out_map_24.xml │ │ │ ├── ic_outline_latest_black_24.xml │ │ │ ├── ic_baseline_lock_open_24.xml │ │ │ ├── ic_latest_black_24.xml │ │ │ ├── ic_baseline_closed_caption_24.xml │ │ │ ├── ic_baseline_favorite_border_24.xml │ │ │ ├── ic_baseline_closed_caption_disabled_24.xml │ │ │ ├── ic_baseline_screen_rotation_24.xml │ │ │ ├── sort_numeric_reversed.xml │ │ │ ├── sort_numeric_normal.xml │ │ │ ├── ic_baseline_settings_24.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ ├── ic_heart_minus.xml │ │ │ ├── ic_episode.xml │ │ │ └── ic_heart_plus.xml │ │ ├── font │ │ │ └── zcool_font.ttf │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_banner.png │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── values-night │ │ │ ├── colors.xml │ │ │ └── themes.xml │ │ ├── values │ │ │ ├── ic_banner_background.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── arrays.xml │ │ │ ├── style_full_screen.xml │ │ │ ├── themes.xml │ │ │ ├── colors.xml │ │ │ └── strings.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_banner.xml │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── anim │ │ │ ├── fade_out.xml │ │ │ ├── expand_in.xml │ │ │ └── pop_in.xml │ │ ├── values-v29 │ │ │ └── themes.xml │ │ ├── layout │ │ │ ├── bottom_sheet_layout.xml │ │ │ ├── spinner_dropdown_item.xml │ │ │ ├── activity_splash.xml │ │ │ ├── fragment_favorite.xml │ │ │ ├── fragment_trending.xml │ │ │ ├── fragment_latest.xml │ │ │ ├── fragment_search.xml │ │ │ ├── fragment_player.xml │ │ │ ├── episode_bottom_sheet_layout.xml │ │ │ ├── double_tap_overlay.xml │ │ │ ├── landscape_cover_cardview_item.xml │ │ │ ├── portrait_cover_cardview_item.xml │ │ │ └── activity_main.xml │ │ ├── menu │ │ │ ├── topbar_menu.xml │ │ │ ├── bottom_nav_menu.xml │ │ │ └── rail_nav_menu.xml │ │ ├── layout-land │ │ │ └── portrait_cover_cardview_item.xml │ │ ├── xml │ │ │ └── root_preferences.xml │ │ └── navigation │ │ │ └── mobile_navigation.xml │ │ ├── ic_launcher-playstore.png │ │ ├── java │ │ └── com │ │ │ └── talent │ │ │ └── animescrap │ │ │ ├── AnimeScrapApplication.kt │ │ │ ├── room │ │ │ ├── LinksRoomDatabase.kt │ │ │ ├── FavRoomModel.kt │ │ │ └── LinkDao.kt │ │ │ ├── di │ │ │ ├── RepositoryModule.kt │ │ │ ├── VideoPlayerModule.kt │ │ │ └── DatabaseModule.kt │ │ │ ├── ui │ │ │ ├── viewmodels │ │ │ │ ├── SearchViewModel.kt │ │ │ │ ├── FavoriteViewModel.kt │ │ │ │ ├── LatestViewModel.kt │ │ │ │ ├── TrendingViewModel.kt │ │ │ │ ├── AnimeStreamViewModel.kt │ │ │ │ ├── UpdateViewModel.kt │ │ │ │ └── AnimeDetailsViewModel.kt │ │ │ ├── activities │ │ │ │ └── SplashActivity.kt │ │ │ └── fragments │ │ │ │ ├── TrendingFragment.kt │ │ │ │ ├── SearchFragment.kt │ │ │ │ ├── FavoriteFragment.kt │ │ │ │ └── LatestFragment.kt │ │ │ ├── viewbindings │ │ │ └── Bindings.kt │ │ │ └── widgets │ │ │ └── DoubleTapPlayerView.kt │ │ └── AndroidManifest.xml ├── schemas │ └── com.talent.animescrap.room.LinksRoomDatabase │ │ ├── 1.json │ │ ├── 2.json │ │ └── 3.json ├── proguard-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle ├── LICENSE ├── gradle.properties ├── .github └── workflows │ └── android.yml └── gradlew.bat /.idea/.name: -------------------------------------------------------------------------------- 1 | Anime Scrap -------------------------------------------------------------------------------- /AnimeScrapCommon/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /animeSources/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /animeSources/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AnimeScrapCommon/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /debug 3 | /release 4 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/drawable/cc.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/font/zcool_font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/font/zcool_font.ttf -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xhdpi/ic_banner.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #5C5050 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakeyatogod/AnimeScrap/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /animeSources/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_banner_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F44545 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F44545 4 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/AnimeScrapApplication.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class AnimeScrapApplication : Application() -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/model/SimpleAnime.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.model 2 | 3 | data class SimpleAnime( 4 | val animeName: String, 5 | val animeImageURL: String, 6 | val animeLink: String 7 | ) -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/model/UpdateDetails.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.model 2 | 3 | data class UpdateDetails( 4 | val isUpdateAvailable : Boolean, 5 | val link : String, 6 | val description : String 7 | ) 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu May 27 14:44:22 IST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/model/AnimeDetails.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.model 2 | 3 | data class AnimeDetails( 4 | val animeName: String, 5 | val animeDesc: String, 6 | val animeCover: String, 7 | val animeEpisodes: Map> 8 | ) -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/model/AnimeStreamLink.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.model 2 | 3 | data class AnimeStreamLink( 4 | val link: String, 5 | val subsLink: String, 6 | val isHls: Boolean, 7 | val extraHeaders: HashMap? = null 8 | ) 9 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_nav_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/room/LinksRoomDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.room 2 | 3 | import androidx.room.Database 4 | import androidx.room.RoomDatabase 5 | 6 | @Database(entities = [FavRoomModel::class], version = 3) 7 | abstract class LinksRoomDatabase : RoomDatabase() { 8 | abstract fun linkDao(): LinkDao 9 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shadow_gradient.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/select_latest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/select_fav.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_triangle.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | /.idea/deploymentTargetDropDown.xml 17 | /.idea/misc.xml 18 | .idea/misc.xml 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/subs_toggle_image_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/gradient_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_navigate_before_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_navigate_next_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_play_arrow_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values-v29/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/bottom_sheet_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_pause_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "Anime Scrap" 16 | include ':app' 17 | include ':AnimeScrapCommon' 18 | include ':animeSources' 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_fast_forward_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_trending_black_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /animeSources/src/test/java/com/talent/animescrapsources/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrapsources 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/expand_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_fast_rewind_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /AnimeScrapCommon/src/test/java/com/talent/animescrap_common/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_arrow_back_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_height_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/spinner_dropdown_item.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_fullscreen_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/room/FavRoomModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.room 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | 7 | @Entity(tableName = "fav_table") 8 | data class FavRoomModel( 9 | @PrimaryKey @ColumnInfo(name = "favLink") val linkString: String, 10 | @ColumnInfo(name = "favPic") val picLinkString: String, 11 | @ColumnInfo(name = "favName") val nameString: String, 12 | @ColumnInfo(name = "favSource") val sourceString: String? 13 | ) -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/model/AnimePlayingDetails.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.model 2 | 3 | import android.os.Parcelable 4 | import androidx.annotation.Keep 5 | import kotlinx.parcelize.Parcelize 6 | 7 | @Keep 8 | @Parcelize 9 | data class AnimePlayingDetails( 10 | val animeName: String, 11 | val animeUrl: String, 12 | var animeEpisodeIndex: String, 13 | val animeEpisodeMap: HashMap, 14 | val animeTotalEpisode: String, 15 | val epType: String 16 | ) : Parcelable -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite_black_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_broken_image.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_selector_accent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.di 2 | 3 | import com.talent.animescrap.repo.AnimeRepository 4 | import com.talent.animescrap.repo.AnimeRepositoryImpl 5 | import dagger.Binds 6 | import dagger.Module 7 | import dagger.hilt.InstallIn 8 | import dagger.hilt.components.SingletonComponent 9 | import kotlinx.coroutines.ExperimentalCoroutinesApi 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | @ExperimentalCoroutinesApi 14 | abstract class RepositoryModule { 15 | 16 | @Binds 17 | abstract fun bindAnimeRepository(repository: AnimeRepositoryImpl): AnimeRepository 18 | 19 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_black_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_zoom_out_map_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/menu/topbar_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_outline_latest_black_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/bottom_nav_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_lock_open_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_latest_black_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_closed_caption_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_favorite_border_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/source/AnimeSource.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.source 2 | 3 | import com.talent.animescrap_common.model.AnimeDetails 4 | import com.talent.animescrap_common.model.AnimeStreamLink 5 | import com.talent.animescrap_common.model.SimpleAnime 6 | 7 | interface AnimeSource { 8 | suspend fun animeDetails(contentLink: String): AnimeDetails 9 | suspend fun searchAnime(searchedText: String): ArrayList 10 | suspend fun latestAnime(): ArrayList 11 | suspend fun trendingAnime(): ArrayList 12 | suspend fun streamLink( 13 | animeUrl: String, 14 | animeEpCode: String, 15 | extras: List? = null 16 | ): AnimeStreamLink 17 | } 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/di/VideoPlayerModule.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.di 2 | 3 | import android.app.Application 4 | import com.google.android.exoplayer2.ExoPlayer 5 | import com.google.android.exoplayer2.source.MediaSource 6 | import dagger.Module 7 | import dagger.Provides 8 | import dagger.hilt.InstallIn 9 | import dagger.hilt.android.components.ViewModelComponent 10 | import dagger.hilt.android.scopes.ViewModelScoped 11 | 12 | @Module 13 | @InstallIn(ViewModelComponent::class) 14 | object VideoPlayerModule { 15 | 16 | @Provides 17 | @ViewModelScoped 18 | fun provideVideoPlayer(app: Application): ExoPlayer { 19 | return ExoPlayer.Builder(app) 20 | .setSeekForwardIncrementMs(10000) 21 | .setSeekBackIncrementMs(10000) 22 | .build() 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_closed_caption_disabled_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /animeSources/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /AnimeScrapCommon/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/room/LinkDao.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.room 2 | 3 | import androidx.room.* 4 | import kotlinx.coroutines.flow.Flow 5 | 6 | @Dao 7 | interface LinkDao { 8 | @Query("SELECT * FROM fav_table where favSource = :sourceName") 9 | fun getLinks(sourceName: String? = "yugen"): Flow> 10 | 11 | @Insert(onConflict = OnConflictStrategy.IGNORE) 12 | fun insert(fav: FavRoomModel) 13 | 14 | @Delete 15 | fun deleteOne(fav: FavRoomModel) 16 | 17 | @Query("SELECT EXISTS (SELECT * FROM fav_table where favLink = :link AND favSource = :sourceName)") 18 | fun isItFav(link: String, sourceName: String): Boolean 19 | 20 | @Query("SELECT * FROM fav_table where favLink = :link AND favSource = :sourceName") 21 | fun getFav(link: String, sourceName: String): FavRoomModel 22 | 23 | } -------------------------------------------------------------------------------- /AnimeScrapCommon/src/androidTest/java/com/talent/animescrap_common/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.talent.AnimeScrapCommon.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /animeSources/src/androidTest/java/com/talent/animescrapsources/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrapsources 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.talent.animescrap_animesources.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_screen_rotation_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /animeSources/src/main/java/com/talent/animescrapsources/SourceSelector.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrapsources 2 | 3 | import android.content.Context 4 | import com.talent.animescrap_common.source.AnimeSource 5 | import com.talent.animescrapsources.animesources.* 6 | 7 | class SourceSelector(context: Context) { 8 | val sourceMap: Map = mapOf( 9 | "yugen" to YugenSource(), 10 | "allanime" to AllAnimeSource(), 11 | "animepahe" to AnimePaheSource(), 12 | "kawaiifu" to KawaiifuSource(context), 13 | // "aniwave" to AniWaveSource(), 14 | "kiss_kh" to KissKhSource(), 15 | "asian_load" to AsianLoad(), 16 | "my_asian_tv" to MyAsianTvSource(), 17 | ) 18 | 19 | fun getSelectedSource(selectedSource: String): AnimeSource { 20 | if (selectedSource in sourceMap.keys) { 21 | return sourceMap[selectedSource]!! 22 | } 23 | return sourceMap["yugen"]!! 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/sort_numeric_reversed.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sort_numeric_normal.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/pop_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 21 | 22 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/menu/rail_nav_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 18 | 22 | 26 | 27 | -------------------------------------------------------------------------------- /app/schemas/com.talent.animescrap.room.LinksRoomDatabase/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 1, 5 | "identityHash": "1481ce57d78c039fc2dc3f35286e9f58", 6 | "entities": [ 7 | { 8 | "tableName": "fav_table", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`fav` TEXT NOT NULL, PRIMARY KEY(`fav`))", 10 | "fields": [ 11 | { 12 | "fieldPath": "linkString", 13 | "columnName": "fav", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | } 17 | ], 18 | "primaryKey": { 19 | "columnNames": [ 20 | "fav" 21 | ], 22 | "autoGenerate": false 23 | }, 24 | "indices": [], 25 | "foreignKeys": [] 26 | } 27 | ], 28 | "views": [], 29 | "setupQueries": [ 30 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 31 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1481ce57d78c039fc2dc3f35286e9f58')" 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 18 | 19 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Yato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -dontwarn org.bouncycastle.jsse.BCSSLSocket 24 | -dontwarn org.bouncycastle.jsse.BCSSLParameters 25 | -dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider 26 | -dontwarn org.conscrypt.* 27 | -dontwarn org.openjsse.javax.net.ssl.SSLParameters 28 | -dontwarn org.openjsse.javax.net.ssl.SSLSocket 29 | -dontwarn org.openjsse.net.ssl.OpenJSSE -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/viewmodels/SearchViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.viewmodels 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.talent.animescrap_common.model.SimpleAnime 8 | import com.talent.animescrap.repo.AnimeRepository 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.withContext 13 | import javax.inject.Inject 14 | 15 | @HiltViewModel 16 | class SearchViewModel @Inject constructor( 17 | private val animeRepository: AnimeRepository 18 | ) : ViewModel() { 19 | private val _searchedAnimeList = MutableLiveData>() 20 | val searchedAnimeList: LiveData> = _searchedAnimeList 21 | 22 | fun searchAnime(searchUrl: String) { 23 | viewModelScope.launch { 24 | withContext(Dispatchers.IO) { 25 | animeRepository.searchAnimeFromSite(searchUrl).apply { 26 | _searchedAnimeList.postValue(this@apply) 27 | } 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/viewmodels/FavoriteViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.viewmodels 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.talent.animescrap_common.model.SimpleAnime 8 | import com.talent.animescrap.repo.AnimeRepository 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.withContext 13 | import javax.inject.Inject 14 | 15 | @HiltViewModel 16 | class FavoriteViewModel @Inject constructor( 17 | private val animeRepository: AnimeRepository 18 | ) : ViewModel() { 19 | 20 | private val _favoriteAnimeList = MutableLiveData>().apply { 21 | getFavorites() 22 | } 23 | val favoriteAnimeList: LiveData> = _favoriteAnimeList 24 | 25 | fun getFavorites() { 26 | viewModelScope.launch { 27 | withContext(Dispatchers.IO) { 28 | animeRepository.getFavoritesFromRoom().collect { 29 | _favoriteAnimeList.postValue(it) 30 | } 31 | } 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/viewmodels/LatestViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.viewmodels 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.talent.animescrap_common.model.SimpleAnime 8 | import com.talent.animescrap.repo.AnimeRepository 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.withContext 13 | import javax.inject.Inject 14 | 15 | @HiltViewModel 16 | class LatestViewModel @Inject constructor( 17 | private val animeRepository: AnimeRepository 18 | ) : ViewModel() { 19 | private val _latestAnimeList = 20 | MutableLiveData>().apply { getLatestAnimeList() } 21 | val latestAnimeList: LiveData> = _latestAnimeList 22 | 23 | fun getLatestAnimeList() { 24 | viewModelScope.launch { 25 | withContext(Dispatchers.IO) { 26 | animeRepository.getLatestAnimeFromSite().apply { 27 | _latestAnimeList.postValue(this@apply) 28 | } 29 | } 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_settings_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/viewmodels/TrendingViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.viewmodels 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.talent.animescrap_common.model.SimpleAnime 8 | import com.talent.animescrap.repo.AnimeRepository 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.withContext 13 | import javax.inject.Inject 14 | 15 | @HiltViewModel 16 | class TrendingViewModel @Inject constructor( 17 | private val animeRepository: AnimeRepository 18 | ) : ViewModel() { 19 | private val _trendingAnimeList = 20 | MutableLiveData>().apply { getTrendingAnimeList() } 21 | val trendingAnimeList: LiveData> = _trendingAnimeList 22 | 23 | 24 | fun getTrendingAnimeList() { 25 | viewModelScope.launch { 26 | withContext(Dispatchers.IO) { 27 | animeRepository.getTrendingAnimeFromSite().apply { 28 | _trendingAnimeList.postValue(this@apply) 29 | } 30 | } 31 | } 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Yugen 5 | 6 | AllAnime 7 | 8 | KissKh 9 | AnimePahe 10 | Kawaiifu 11 | MarinMoe 12 | AsianLoad 13 | MyAsianTv 14 | 15 | 16 | 17 | yugen 18 | 19 | allanime 20 | 21 | kiss_kh 22 | animepahe 23 | kawaiifu 24 | marin_moe 25 | asian_load 26 | my_asian_tv 27 | 28 | 29 | 30 | 31 | Off 32 | On 33 | Follow system 34 | 35 | 36 | 37 | off 38 | on 39 | follow_system 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_heart_minus.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_episode.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 15 | 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/viewmodels/AnimeStreamViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.viewmodels 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.talent.animescrap_common.model.AnimeStreamLink 8 | import com.talent.animescrap.repo.AnimeRepository 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.withContext 13 | import javax.inject.Inject 14 | 15 | @HiltViewModel 16 | class AnimeStreamViewModel @Inject constructor( 17 | private val animeRepository: AnimeRepository 18 | ) : ViewModel() { 19 | 20 | private val _animeStreamLink: MutableLiveData = MutableLiveData() 21 | val animeStreamLink: LiveData = _animeStreamLink 22 | 23 | fun setAnimeLink(animeUrl: String, animeEpCode: String, extras: List) { 24 | viewModelScope.launch { 25 | withContext(Dispatchers.IO) { 26 | println("STREAM GET LINK") 27 | animeRepository.getStreamLink(animeUrl, animeEpCode, extras).apply { 28 | _animeStreamLink.postValue(this@apply) 29 | } 30 | } 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/di/DatabaseModule.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.di 2 | 3 | import android.app.Application 4 | import androidx.room.Room 5 | import androidx.room.migration.Migration 6 | import androidx.sqlite.db.SupportSQLiteDatabase 7 | import com.talent.animescrap.room.LinkDao 8 | import com.talent.animescrap.room.LinksRoomDatabase 9 | import dagger.Module 10 | import dagger.Provides 11 | import dagger.hilt.InstallIn 12 | import dagger.hilt.components.SingletonComponent 13 | import javax.inject.Singleton 14 | 15 | 16 | @InstallIn(SingletonComponent::class) 17 | @Module 18 | object DatabaseModule { 19 | 20 | private val MIGRATION_2_3 = object : Migration(2, 3) { 21 | override fun migrate(database: SupportSQLiteDatabase) { 22 | database.execSQL("ALTER TABLE fav_table ADD COLUMN favSource TEXT DEFAULT 'yugen'") 23 | } 24 | } 25 | 26 | @Provides 27 | @Singleton 28 | fun provideAppDatabase( 29 | application: Application, 30 | ): LinksRoomDatabase { 31 | return Room 32 | .databaseBuilder(application, LinksRoomDatabase::class.java, "fav-db") 33 | .addMigrations(MIGRATION_2_3) 34 | .fallbackToDestructiveMigration() 35 | .build() 36 | } 37 | 38 | @Provides 39 | @Singleton 40 | fun provideLinkDao(appDatabase: LinksRoomDatabase): LinkDao = appDatabase.linkDao() 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/viewbindings/Bindings.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.viewbindings 2 | 3 | import android.widget.ImageView 4 | import androidx.databinding.BindingAdapter 5 | import coil.ImageLoader 6 | import coil.load 7 | import com.facebook.shimmer.Shimmer 8 | import com.facebook.shimmer.ShimmerDrawable 9 | import com.talent.animescrap.R 10 | import com.talent.animescrap_common.utils.Utils 11 | 12 | private val shimmer = 13 | Shimmer.AlphaHighlightBuilder()// The attributes for a ShimmerDrawable is set by this builder 14 | .setDuration(1200) // how long the shimmering animation takes to do one full sweep 15 | .setBaseAlpha(0.6f) //the alpha of the underlying children 16 | .setHighlightAlpha(0.9f) // the shimmer alpha amount 17 | .setDirection(Shimmer.Direction.LEFT_TO_RIGHT) 18 | .setAutoStart(true) 19 | .build() 20 | /* A function that is called when the `image` attribute is used in the layout. */ 21 | @BindingAdapter("image") 22 | fun ImageView.setImage(url: String?) { 23 | val imageLoader = ImageLoader.Builder(context) 24 | .okHttpClient { Utils.httpClient } 25 | .build() 26 | if (!url.isNullOrEmpty()) 27 | load(url, imageLoader) { 28 | crossfade(true) 29 | placeholder(ShimmerDrawable().apply { 30 | setShimmer(shimmer) 31 | }) 32 | error(R.drawable.ic_broken_image) 33 | build() 34 | } 35 | } -------------------------------------------------------------------------------- /AnimeScrapCommon/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'org.jetbrains.kotlin.android' 4 | id 'kotlin-parcelize' 5 | } 6 | 7 | android { 8 | namespace 'com.talent.AnimeScrapCommon' 9 | compileSdk 33 10 | 11 | defaultConfig { 12 | minSdk 23 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | consumerProguardFiles "consumer-rules.pro" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | compileOptions { 25 | sourceCompatibility JavaVersion.VERSION_1_8 26 | targetCompatibility JavaVersion.VERSION_1_8 27 | } 28 | kotlinOptions { 29 | jvmTarget = '1.8' 30 | } 31 | } 32 | 33 | dependencies { 34 | 35 | implementation 'androidx.core:core-ktx:1.12.0' 36 | implementation 'androidx.appcompat:appcompat:1.6.1' 37 | implementation 'com.google.android.material:material:1.10.0' 38 | 39 | // Network 40 | implementation 'org.jsoup:jsoup:1.15.2' // Web scraping tool 41 | implementation 'com.google.code.gson:gson:2.9.0' // Json Parser 42 | implementation 'com.squareup.okhttp3:okhttp:4.10.0' 43 | 44 | testImplementation 'junit:junit:4.13.2' 45 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 46 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 47 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true 24 | android.defaults.buildfeatures.buildconfig=true 25 | android.nonFinalResIds=false -------------------------------------------------------------------------------- /app/schemas/com.talent.animescrap.room.LinksRoomDatabase/2.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 2, 5 | "identityHash": "3faf319f6e2d4a27d936dc0c9ea3a5ef", 6 | "entities": [ 7 | { 8 | "tableName": "fav_table", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`favLink` TEXT NOT NULL, `favPic` TEXT NOT NULL, `favName` TEXT NOT NULL, PRIMARY KEY(`favLink`))", 10 | "fields": [ 11 | { 12 | "fieldPath": "linkString", 13 | "columnName": "favLink", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "picLinkString", 19 | "columnName": "favPic", 20 | "affinity": "TEXT", 21 | "notNull": true 22 | }, 23 | { 24 | "fieldPath": "nameString", 25 | "columnName": "favName", 26 | "affinity": "TEXT", 27 | "notNull": true 28 | } 29 | ], 30 | "primaryKey": { 31 | "columnNames": [ 32 | "favLink" 33 | ], 34 | "autoGenerate": false 35 | }, 36 | "indices": [], 37 | "foreignKeys": [] 38 | } 39 | ], 40 | "views": [], 41 | "setupQueries": [ 42 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 43 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3faf319f6e2d4a27d936dc0c9ea3a5ef')" 44 | ] 45 | } 46 | } -------------------------------------------------------------------------------- /animeSources/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | namespace 'com.talent.animescrap_animesources' 8 | compileSdk 34 9 | 10 | defaultConfig { 11 | minSdk 23 12 | 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | consumerProguardFiles "consumer-rules.pro" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | compileOptions { 24 | sourceCompatibility JavaVersion.VERSION_1_8 25 | targetCompatibility JavaVersion.VERSION_1_8 26 | } 27 | kotlinOptions { 28 | jvmTarget = '1.8' 29 | } 30 | } 31 | 32 | dependencies { 33 | 34 | implementation project(path: ':AnimeScrapCommon') 35 | 36 | 37 | implementation 'androidx.core:core-ktx:1.12.0' 38 | implementation 'androidx.appcompat:appcompat:1.6.1' 39 | implementation 'com.google.android.material:material:1.10.0' 40 | 41 | // Network 42 | implementation 'org.jsoup:jsoup:1.15.2' // Web scraping tool 43 | implementation 'com.google.code.gson:gson:2.9.0' // Json Parser 44 | implementation 'com.squareup.okhttp3:okhttp:4.10.0' 45 | 46 | testImplementation 'junit:junit:4.13.2' 47 | androidTestImplementation 'androidx.test.ext:junit:1.1.5' 48 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' 49 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_heart_plus.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /AnimeScrapCommon/src/main/java/com/talent/animescrap_common/sourceutils/AndroidCookieJar.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap_common.sourceutils 2 | 3 | import android.webkit.CookieManager 4 | import okhttp3.Cookie 5 | import okhttp3.CookieJar 6 | import okhttp3.HttpUrl 7 | 8 | class AndroidCookieJar : CookieJar { 9 | 10 | private val manager = CookieManager.getInstance() 11 | 12 | override fun saveFromResponse(url: HttpUrl, cookies: List) { 13 | val urlString = url.toString() 14 | 15 | cookies.forEach { manager.setCookie(urlString, it.toString()) } 16 | } 17 | 18 | override fun loadForRequest(url: HttpUrl): List { 19 | return get(url) 20 | } 21 | 22 | fun get(url: HttpUrl): List { 23 | val cookies = manager.getCookie(url.toString()) 24 | 25 | return if (cookies != null && cookies.isNotEmpty()) { 26 | cookies.split(";").mapNotNull { Cookie.parse(url, it) } 27 | } else { 28 | emptyList() 29 | } 30 | } 31 | 32 | fun remove(url: HttpUrl, cookieNames: List? = null, maxAge: Int = -1): Int { 33 | val urlString = url.toString() 34 | val cookies = manager.getCookie(urlString) ?: return 0 35 | 36 | fun List.filterNames(): List { 37 | return if (cookieNames != null) { 38 | this.filter { it in cookieNames } 39 | } else { 40 | this 41 | } 42 | } 43 | 44 | return cookies.split(";") 45 | .map { it.substringBefore("=") } 46 | .filterNames() 47 | .onEach { manager.setCookie(urlString, "$it=;Max-Age=$maxAge") } 48 | .count() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/schemas/com.talent.animescrap.room.LinksRoomDatabase/3.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 3, 5 | "identityHash": "131e8c62a69c6d6c2f410f2644d422a0", 6 | "entities": [ 7 | { 8 | "tableName": "fav_table", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`favLink` TEXT NOT NULL, `favPic` TEXT NOT NULL, `favName` TEXT NOT NULL, `favSource` TEXT, PRIMARY KEY(`favLink`))", 10 | "fields": [ 11 | { 12 | "fieldPath": "linkString", 13 | "columnName": "favLink", 14 | "affinity": "TEXT", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "picLinkString", 19 | "columnName": "favPic", 20 | "affinity": "TEXT", 21 | "notNull": true 22 | }, 23 | { 24 | "fieldPath": "nameString", 25 | "columnName": "favName", 26 | "affinity": "TEXT", 27 | "notNull": true 28 | }, 29 | { 30 | "fieldPath": "sourceString", 31 | "columnName": "favSource", 32 | "affinity": "TEXT", 33 | "notNull": false 34 | } 35 | ], 36 | "primaryKey": { 37 | "columnNames": [ 38 | "favLink" 39 | ], 40 | "autoGenerate": false 41 | }, 42 | "indices": [], 43 | "foreignKeys": [] 44 | } 45 | ], 46 | "views": [], 47 | "setupQueries": [ 48 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 49 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '131e8c62a69c6d6c2f410f2644d422a0')" 50 | ] 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 11 | 12 | 13 | 14 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android CI 2 | 3 | on: 4 | push: 5 | branches: [ "main" , "common" ] 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v3 14 | - name: set up JDK 17 15 | uses: actions/setup-java@v3 16 | with: 17 | java-version: '17' 18 | distribution: 'temurin' 19 | cache: gradle 20 | 21 | - name: Grant execute permission for gradlew 22 | run: chmod +x gradlew 23 | 24 | - name: Build Release APK 25 | run: ./gradlew assembleRelease 26 | 27 | - uses: r0adkll/sign-android-release@v1 28 | name: Sign app APK 29 | # ID used to access action output 30 | id: sign_app 31 | with: 32 | releaseDirectory: app/build/outputs/apk/release 33 | signingKeyBase64: ${{ secrets.BASE64KEY }} 34 | alias: ${{ secrets.ALIAS }} 35 | keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }} 36 | keyPassword: ${{ secrets.KEY_PASSWORD }} 37 | env: 38 | # override default build-tools version (29.0.3) -- optional 39 | BUILD_TOOLS_VERSION: "34.0.0" 40 | 41 | # Example use of `signedReleaseFile` output -- not needed 42 | - uses: actions/upload-artifact@v2 43 | with: 44 | name: Signed app bundle 45 | path: ${{steps.sign_app.outputs.signedReleaseFile}} 46 | 47 | - name: Set current date as env variable 48 | run: echo "date_now=$(date +'%Y-%m-%d')" >> $GITHUB_ENV 49 | 50 | - uses: marvinpinto/action-automatic-releases@latest 51 | with: 52 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 53 | automatic_release_tag: "latest" 54 | draft: true 55 | title: " Dev Release ${{ env.date_now }}" 56 | files: ${{steps.sign_app.outputs.signedReleaseFile}} 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/activities/SplashActivity.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.activities 2 | 3 | import android.content.Intent 4 | import android.content.res.Configuration 5 | import android.os.Bundle 6 | import android.os.Handler 7 | import android.os.Looper 8 | import androidx.appcompat.app.AppCompatActivity 9 | import androidx.appcompat.app.AppCompatDelegate 10 | import androidx.preference.PreferenceManager 11 | import com.google.android.material.color.DynamicColors 12 | import com.talent.animescrap.R 13 | import dagger.hilt.android.AndroidEntryPoint 14 | 15 | @AndroidEntryPoint 16 | class SplashActivity : AppCompatActivity() { 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | setContentView(R.layout.activity_splash) 20 | 21 | // Set dynamic colors 22 | val settingsPreferenceManager = PreferenceManager.getDefaultSharedPreferences(this) 23 | settingsPreferenceManager.getBoolean("dynamic_colors", true).also { 24 | if (it) DynamicColors.applyToActivitiesIfAvailable(application) 25 | } 26 | settingsPreferenceManager.getString("dark_mode", "follow_system").also { 27 | when (it.toString()) { 28 | "on" -> { 29 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 30 | } 31 | "off" -> { 32 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) 33 | } 34 | else -> { 35 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) 36 | } 37 | } 38 | } 39 | val intent = Intent(this, MainActivity::class.java) 40 | 41 | if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { 42 | startActivity(intent) 43 | finish() 44 | } else { 45 | Handler(Looper.getMainLooper()).postDelayed({ 46 | startActivity(intent) 47 | finish() 48 | }, 400) 49 | } 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_favorite.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 25 | 26 | 27 | 35 | 36 | 40 | 41 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_trending.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 25 | 26 | 27 | 35 | 36 | 40 | 41 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_latest.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 25 | 26 | 27 | 35 | 36 | 40 | 41 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/talent/animescrap/ui/viewmodels/UpdateViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrap.ui.viewmodels 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.talent.animescrap.BuildConfig 8 | import com.talent.animescrap_common.model.UpdateDetails 9 | import kotlinx.coroutines.Dispatchers 10 | import kotlinx.coroutines.launch 11 | import kotlinx.coroutines.withContext 12 | import org.jsoup.Jsoup 13 | 14 | class UpdateViewModel : ViewModel() { 15 | private val githubReleaseLink = "https://github.com/fakeyatogod/AnimeScrap/releases/latest" 16 | private val githubAPKLink = 17 | "https://github.com/fakeyatogod/AnimeScrap/releases/download/TAG/AnimeScrap-vTAG.apk" 18 | 19 | private val _isUpdateAvailable = MutableLiveData().apply { 20 | checkForNewUpdate() 21 | } 22 | val isUpdateAvailable: LiveData = _isUpdateAvailable 23 | 24 | fun checkForNewUpdate() { 25 | val currentVersion = BuildConfig.VERSION_NAME 26 | viewModelScope.launch { 27 | withContext(Dispatchers.IO) { 28 | try { 29 | val doc = Jsoup.connect(githubReleaseLink).get() 30 | val updateDesc = try { 31 | doc.select(".markdown-body").text() 32 | } catch (_: Exception) { 33 | "No Update Description found" 34 | } 35 | println("Update desc = $updateDesc") 36 | val latestVersion = 37 | Regex("\\d+\\.\\d+\\.\\d+").find(doc.toString())?.value 38 | println("$currentVersion == $latestVersion = ${latestVersion == currentVersion}") 39 | _isUpdateAvailable.postValue( 40 | UpdateDetails( 41 | latestVersion != currentVersion, 42 | githubAPKLink.replace("TAG", latestVersion ?: currentVersion), 43 | updateDesc 44 | ) 45 | ) 46 | } catch (_: Exception) { 47 | } 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /animeSources/src/main/java/com/talent/animescrapsources/animesources/sourceCommonExtractors/AsianExtractor.kt: -------------------------------------------------------------------------------- 1 | package com.talent.animescrapsources.animesources.sourceCommonExtractors 2 | 3 | import android.net.Uri 4 | import android.util.Base64 5 | import com.google.gson.JsonParser 6 | import com.talent.animescrap_common.utils.Utils 7 | import org.jsoup.Jsoup 8 | import javax.crypto.Cipher 9 | import javax.crypto.spec.IvParameterSpec 10 | import javax.crypto.spec.SecretKeySpec 11 | 12 | class AsianExtractor { 13 | private val key = "93422192433952489752342908585752" 14 | private val iv = "9262859232435825" 15 | 16 | public fun getAsianStreamLink(embedLink: String): String { 17 | val id = Uri.parse(embedLink).getQueryParameter("id")!! 18 | val embedDoc = Jsoup.parse(Utils.get(embedLink)) 19 | val scriptValue = embedDoc.select("script[data-name='crypto']").attr("data-value") 20 | 21 | val encryptedKey = encryptAES(id, key, iv) 22 | val decryptedToken = decryptAES(scriptValue, key, iv) 23 | 24 | val url = 25 | "https://${Uri.parse(embedLink).host}/encrypt-ajax.php?id=$encryptedKey&alias=$decryptedToken" 26 | println(url) 27 | val data = JsonParser.parseString(Utils.get(url)).asJsonObject["data"].asString 28 | println(data) 29 | return JsonParser.parseString( 30 | decryptAES( 31 | data, 32 | key, 33 | iv 34 | ) 35 | ).asJsonObject["source"].asJsonArray.first().asJsonObject["file"].asString 36 | } 37 | 38 | private fun encryptAES(data: String, key: String, iv: String): String { 39 | val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") 40 | val secretKey = SecretKeySpec(key.toByteArray(), "AES") 41 | val ivSpec = IvParameterSpec(iv.toByteArray()) 42 | cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec) 43 | val encryptedBytes = cipher.doFinal(data.toByteArray()) 44 | return Base64.encodeToString(encryptedBytes, Base64.DEFAULT) 45 | } 46 | 47 | private fun decryptAES(encryptedData: String, key: String, iv: String): String { 48 | val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") 49 | val secretKey = SecretKeySpec(key.toByteArray(), "AES") 50 | val ivSpec = IvParameterSpec(iv.toByteArray()) 51 | cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec) 52 | val decryptedBytes = cipher.doFinal(Base64.decode(encryptedData, Base64.DEFAULT)) 53 | return String(decryptedBytes) 54 | } 55 | } -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 19 | 20 | 25 | 26 | 34 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 56 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_player.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 27 | 28 | 33 | 34 | 43 | 44 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/src/main/res/values/style_full_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | 35 |