Skip to content

Commit

Permalink
push files
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexZorzi authored and AlexZorzi committed Mar 26, 2021
1 parent ced853f commit dcce260
Show file tree
Hide file tree
Showing 10 changed files with 644 additions and 0 deletions.
129 changes: 129 additions & 0 deletions MangaWorldApi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Pagina Archivio
Json Sono caricati in pagina tra '.concat(' & ') \<script>'
https://www.mangaworld.cc/archive?page=1

Questa è la struttura importante
```
"o":{
"w":[
2[
"s0-13",
2,
{
"results":2125, //totale manga
"mangas":[
{
"extraTitles":[
"Onii-chan is done for",
"お兄ちゃんはおしまい!",
"Onii-chan wa Oshimai"
]
"author":[
"Nekotoufu"
],
"artist":[
"Nekotoufu"
],
"genres":[
{
"name":"commedia",
}
...
]
"references":[
"mangaupdatesId":146713,
"mangadexId":22615,
"anilistId":100080,
"malId":112592,
],
"fansub":{
"name":"Betta Scans",
"link":"https://www.facebook.com/BettaScans/"
},
"vm18":false,
"animeLink":null,
"_id":"5faa2373de75a27e9df97f61",
"title":" Onii-chan Is Done For!",
"status":"ONGOING",
"type":"DOUJINSHI",
"trama":"**", //la trama è qui
"year":2017,
"volumesCount":null,
"chaptersCount":null,
"image":"/mangas/5faa2373de75a27e9df97f61.png",
"slug":"onii-chan-is-done-for",
"slugFolder":"onii-chan-is-done-for",
"linkId":2070,
},
... //ripetuto per ogni manga in pagina
],
},
],
]
}
```

# Pagina Manga
si trova sempre nello stesso punto nel file html del precedente
https://www.mangaworld.cc/manga/2070/onii-chan-is-done-for
la pagina dei manga può essere vista anche così
https://www.mangaworld.cc/manga/`numero id` quindi può essere ottenuto ciclando da 170 a 2332 (ultimo attuale). così da saltare le query all archivio

```
"o":
"w":[
[
"s0-2",
0,
"manga":{
// Uguale a "manga" del json precedente
},
]
3[
"s0-83",
3,
{
"pages":{
"volumes":[ // se è manga normale
{
"volume":{
"_id":"5fb01fa0c34214221761baef",
"manga":"5faa2373de75a27e9df97f61",
"name":"Volume 04",
"image":"/volumes/5fb01fa0c34214221761baef.png",
},
"chapters":[
{
"_id":"5fd1f736ea2ffd76512a3647",
"pages":[
"1.png",
"2.png",
"3.png",
"4.png"
],
"name":"Capitolo 33.5",
},
...
],
},
...
],
"singleChapters":[ // se è oneshot
{
"_id":"5fc7aedae951863e97b3f121",
"pages":[
"1.jpg",
"2.jpg",
],
"name":"Oneshot",
},
...
],
},
},
],
```
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# MangaWorld Downloader
Un Downloader Per mangaworld.cc,
progetto a scopo didattico non affiliato a mangaworld.cc, non sono responsabile dell'utilizzo e delle immagini hostate su mangaworld.cc

# Features
- Download di manga interi o singoli capitoli
- MultiThreaded Download per scaricare le pagine alla massima velocità
- Download della Preview

# In caso di un CloudFlare captcha
Per passare il blocco il programma avrà bisogno del cookie cf_clearance e dell'useragent del browser che avete utilzzato per risolvere il captcha

- Token: Risolvete il captcha su www.mangaworld.cc e in Dev Console prendete il valore del cookie cf_clearance
![Token](https://i.imgur.com/HYUu0M0.png)

- UserAgent: Al sito www.whatsmyua.info è possibile vedere il proprio useragent
![Useragent](https://i.imgur.com/nZZfCt1.png)

il programma vi chiederà in automatico questi due parametri se ne avrà bisogno, poi li salverà in automatico in un file JSON così da poterli utilizzare
anche dopo che il programma è stato chiuso.

Manualmente: è possibile inserire manualmente i valori in un file chiamato `cred.json` con questa struttura nella stessa cartella dell'eseguibile

```
{
"useragent" : "useragent value here"
"cf_clearance" : "cf_clearance value here"
}
```
10 changes: 10 additions & 0 deletions chapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

type Chapter struct {
ID string `json:"_id"`
Pages []string `json:"pages"`
Manga string `json:"manga"`
Name string `json:"name"`
Slug string `json:"slugFolder"`
}

32 changes: 32 additions & 0 deletions commonLogic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"strings"
)

func Contains(s []int, ID int) bool {
for _, v := range s {
if v == ID {
return true
}
}

return false
}

func Between(value string, a string, b string) string {
// Get substring between two strings.
posFirst := strings.Index(value, a)
if posFirst == -1 {
return ""
}
posLast := strings.Index(value, b)
if posLast == -1 {
return ""
}
posFirstAdjusted := posFirst + len(a)
if posFirstAdjusted >= posLast {
return ""
}
return value[posFirstAdjusted:posLast]
}
6 changes: 6 additions & 0 deletions cred.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package main

type Cred struct {
Useragent string `json:"useragent"`
Clearance string `json:"cf_clearance"`
}
164 changes: 164 additions & 0 deletions download.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package main

import (
"bufio"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
)

func DownloadManga(m Manga) {
// https://cdn.mangaworld.cc/chapters/blust-5fde5e956fe15b440d71d1c6/oneshot-5fde5ea093f7544385e33e4d/1.png
// slugManga - idManga / slugChapther - idChapter / pageFilename
DownloadPreview(m)
// TODO: download Banner
// Download Volumes
for _, volumeEntity := range m.Pages.Volumes {
for _, chapter := range volumeEntity.Chapters {
DownloadChapter(chapter, volumeEntity.Volume, m)
}
}
// insert all SingleChapters
for _, chapter := range m.Pages.SingleChapters {
DownloadChapterNoVolume(chapter, m)
}
}

func DownloadPreview(m Manga) {
PATH := filepath.FromSlash("./" + m.Slug + "/")
WG.Add(1)
go downloadWPath("https://cdn.mangaworld.cc"+m.Image, PATH, m.Slug+"."+strings.Split(m.Image, ".")[1])
}
func DownloadChapterNoVolume(c Chapter, m Manga) {
WG.Wait()
var floatC float64
fmt.Println(c.Name)
if c.Name == "Oneshot" {
floatC = 0.0
} else {
floattry, err2 := strconv.ParseFloat(strings.Split(c.Name, " ")[1], 32)
if err2 != nil {
panic(err2)
}
floatC = floattry
}
chapterNumber := fmt.Sprintf("%.1F", floatC)
for _, page := range c.Pages {
API := "https://cdn.mangaworld.cc/chapters/" + m.SlugFolder + "-" + m.ID + "/" + c.Slug + "-" + c.ID + "/" + page
PATH := filepath.FromSlash("./" + m.Slug + "/chapter " + chapterNumber + "/")
WG.Add(1)
go downloadWPath(API, PATH, page)
}
}
func DownloadChapter(c Chapter, v Volume, m Manga) {
floatV, err := strconv.ParseFloat(strings.Split(v.Name, " ")[1], 32)
if err != nil {
panic(err)
}
volumeNumber := fmt.Sprintf("%.1f", floatV)
fmt.Println("Download: Volume " + v.Name + " Chapter " + c.Name)
floatC, err2 := strconv.ParseFloat(strings.Split(c.Name, " ")[1], 32)
if err2 != nil {
panic(err2)
}
chapterNumber := fmt.Sprintf("%.1F", floatC)
WG.Wait()
for _, page := range c.Pages {
API := "https://cdn.mangaworld.cc/chapters/" + m.SlugFolder + "-" + m.ID + "/" + v.Slug + "-" + v.ID + "/" + c.Slug + "-" + c.ID + "/" + page
PATH := filepath.FromSlash("./" + m.Slug + "/volume " + volumeNumber + "/chapter " + chapterNumber + "/")
WG.Add(1)
go downloadWPath(API, PATH, page)
}
}

func downloadWPath(url string, path string, filename string) {
req, err := http.NewRequest("GET", url, nil)
req.Header.Set("content-type", "charset=UTF-8")
req.Header.Set("cookie", COOKIE)
req.Header.Set("user-agent", USERAGENT)
client := &http.Client{}
response, e := client.Do(req)
if e != nil {
log.Fatal(e)
}
defer response.Body.Close()
os.MkdirAll(path, os.ModePerm)
file, err := os.Create(path + filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
_, err = io.Copy(file, response.Body)
if err != nil {
log.Fatal(err)
}
WG.Done()
}

func GetWebPage(url string) (*http.Response, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
panic(err)
}
req.Header.Set("content-type", "charset=UTF-8")
req.Header.Set("cookie", COOKIE)
req.Header.Set("user-agent", USERAGENT)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
println(resp.Status)
panic(err)
}
if DEBUG {

println(resp.Status)
}
return resp, err
}

func SyncProxyList() {
url := "https://raw.githubusercontent.com/clarketm/proxy-list/master/proxy-list-raw.txt"
resp, err := GetWebPage(url)
if err != nil {
panic(err)
}
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
bodyString := strings.Split(string(bodyBytes), "\n")
bodyString = bodyString[2 : len(bodyString)-1]
PROXY = bodyString
}
func ChangeProxy() {
os.Setenv("HTTP_PROXY", PROXY[len(PROXY)-1])
os.Setenv("HTTPS_PROXY", PROXY[len(PROXY)-1])
println("Proxy changed in " + PROXY[len(PROXY)-1])
PROXY = PROXY[0 : len(PROXY)-2]
}

func ChangeCookie() {
reader := bufio.NewReader(os.Stdin)
print("Cookie Error, supply new cookie: ")
cookie, _ := reader.ReadString('\n')
cookienew := strings.ReplaceAll(cookie, "\n", "")
COOKIE = "cf_clearance=" + cookienew
}

func ChangeUserAgent() {
reader := bufio.NewReader(os.Stdin)
print("supply new USERAGENT: ")
useragent, _ := reader.ReadString('\n')
useragentnew := strings.ReplaceAll(useragent, "\n", "")
USERAGENT = useragentnew
}

func SaveCookies() {
ioutil.WriteFile("cred.json", []byte("{\n \"useragent\":\""+USERAGENT+"\", \n \"cf_clearance\":\""+COOKIE+"\" \n}"), 0755)
}
Loading

0 comments on commit dcce260

Please sign in to comment.