diff --git a/src/en/rainofsnow/AndroidManifest.xml b/src/en/rainofsnow/AndroidManifest.xml
new file mode 100644
index 000000000..30deb7f79
--- /dev/null
+++ b/src/en/rainofsnow/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/src/en/rainofsnow/build.gradle b/src/en/rainofsnow/build.gradle
new file mode 100644
index 000000000..739379b34
--- /dev/null
+++ b/src/en/rainofsnow/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+ext {
+ extName = 'Rain Of Snow'
+ pkgNameSuffix = 'en.rainofsnow'
+ extClass = '.RainOfSnow'
+ extVersionCode = 1
+ libVersion = '1.2'
+ containsNsfw = false
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/en/rainofsnow/res/mipmap-hdpi/ic_launcher.png b/src/en/rainofsnow/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..a7cc0ebcd
Binary files /dev/null and b/src/en/rainofsnow/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/en/rainofsnow/res/mipmap-mdpi/ic_launcher.png b/src/en/rainofsnow/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..138486f1a
Binary files /dev/null and b/src/en/rainofsnow/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/en/rainofsnow/res/mipmap-xhdpi/ic_launcher.png b/src/en/rainofsnow/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..87b764205
Binary files /dev/null and b/src/en/rainofsnow/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/en/rainofsnow/res/mipmap-xxhdpi/ic_launcher.png b/src/en/rainofsnow/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..10a6226c9
Binary files /dev/null and b/src/en/rainofsnow/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/en/rainofsnow/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/rainofsnow/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..c5f293043
Binary files /dev/null and b/src/en/rainofsnow/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/en/rainofsnow/res/web_hi_res_512.png b/src/en/rainofsnow/res/web_hi_res_512.png
new file mode 100644
index 000000000..8cf0ceb39
Binary files /dev/null and b/src/en/rainofsnow/res/web_hi_res_512.png differ
diff --git a/src/en/rainofsnow/src/eu/kanade/tachiyomi/extension/en/rainofsnow/RainOfSnow.kt b/src/en/rainofsnow/src/eu/kanade/tachiyomi/extension/en/rainofsnow/RainOfSnow.kt
new file mode 100644
index 000000000..93ada2c10
--- /dev/null
+++ b/src/en/rainofsnow/src/eu/kanade/tachiyomi/extension/en/rainofsnow/RainOfSnow.kt
@@ -0,0 +1,113 @@
+package eu.kanade.tachiyomi.extension.en.rainofsnow
+
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.FilterList
+import eu.kanade.tachiyomi.source.model.Page
+import eu.kanade.tachiyomi.source.model.SChapter
+import eu.kanade.tachiyomi.source.model.SManga
+import eu.kanade.tachiyomi.source.online.ParsedHttpSource
+import okhttp3.HttpUrl
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+import java.util.concurrent.TimeUnit
+
+open class RainOfSnow() : ParsedHttpSource() {
+
+ override val name = "Rain Of Snow"
+
+ override val baseUrl = "https://rainofsnow.com"
+
+ override val lang = "en"
+
+ override val supportsLatest = false
+
+ override val client: OkHttpClient = network.cloudflareClient.newBuilder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .build()
+
+ override fun popularMangaRequest(page: Int): Request {
+ return GET("$baseUrl/comic/")
+ }
+
+ override fun popularMangaSelector() = "ul.boxhover1 li"
+
+ override fun popularMangaFromElement(element: Element): SManga {
+ val manga = SManga.create()
+ manga.url = element.select("h4 a").attr("abs:href")
+ manga.title = element.select("h4").text()
+ manga.thumbnail_url = element.select("img").attr("abs:src")
+ return manga
+ }
+
+ override fun popularMangaNextPageSelector() = ".page-numbers .next"
+
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+ val url = HttpUrl.parse("$baseUrl/")!!.newBuilder()
+ url.addQueryParameter("serchfor", "comics")
+ url.addQueryParameter("s", query)
+ return GET(url.build().toString(), headers)
+ }
+
+ override fun searchMangaSelector() = popularMangaSelector()
+
+ override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
+
+ override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
+
+ override fun mangaDetailsRequest(manga: SManga): Request {
+ if (manga.url.startsWith("http")) {
+ return GET(manga.url, headers)
+ }
+ return super.mangaDetailsRequest(manga)
+ }
+
+ override fun mangaDetailsParse(document: Document): SManga {
+ val manga = SManga.create()
+ manga.title = document.select("h3").text()
+ manga.author = document.select("li:contains(author) .n2").text()
+ manga.artist = document.select("li:contains(author) .n2").text()
+ manga.status = 0
+ manga.genre = document.select("li:contains(tags) .n2").text()
+ manga.description = document.select(".col-md-8 .text").text()
+ manga.thumbnail_url = document.select(".imgbox img").attr("abs:src")
+ return manga
+ }
+
+ override fun chapterListRequest(manga: SManga): Request {
+ if (manga.url.startsWith("http")) {
+ return GET(manga.url, headers)
+ }
+ return super.chapterListRequest(manga)
+ }
+
+ override fun chapterListSelector() = ".chapter1 li"
+
+ override fun chapterFromElement(element: Element): SChapter {
+ val chapter = SChapter.create()
+ chapter.url = element.select("a").attr("abs:href")
+ chapter.name = element.select("a").text()
+ return chapter
+ }
+
+ override fun pageListRequest(chapter: SChapter): Request {
+ if (chapter.url.startsWith("http")) {
+ return GET(chapter.url, headers)
+ }
+ return super.pageListRequest(chapter)
+ }
+
+ override fun pageListParse(document: Document): List = mutableListOf().apply {
+ document.select(".zoomdesc-cont img").forEachIndexed { index, element ->
+ add(Page(index, "", element.attr("abs:src")))
+ }
+ }
+
+ override fun latestUpdatesFromElement(element: Element) = throw Exception("Not used")
+ override fun latestUpdatesNextPageSelector() = throw Exception("Not used")
+ override fun latestUpdatesRequest(page: Int) = throw Exception("Not used")
+ override fun latestUpdatesSelector() = throw Exception("Not used")
+ override fun imageUrlParse(document: Document) = throw Exception("Not used")
+}