Repository: torta/dark-dmzj Branch: master Commit: e5022717bf40 Files: 10 Total size: 22.2 KB Directory structure: gitextract_vpoukq8z/ ├── .gitattributes ├── .github/ │ └── workflows/ │ └── release.yml ├── .gitignore ├── .goreleaser.yml ├── README.md ├── dark_dmzj.go ├── go.mod ├── hotupdate.go └── public/ ├── dmzj.css └── index.html ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ /public/*.html linguist-detectable=false ================================================ FILE: .github/workflows/release.yml ================================================ name: goreleaser on: push: jobs: goreleaser: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v1 - name: Set up Go uses: actions/setup-go@v1 with: go-version: "1.13.x" - name: Run GoReleaser uses: goreleaser/goreleaser-action@v1 with: version: latest args: release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ *.exe /go.sum /dark_dmzj /public/data.json /test ================================================ FILE: .goreleaser.yml ================================================ builds: - env: - CGO_ENABLED=0 goos: - linux - darwin - windows goarch: - 386 - amd64 - arm - arm64 checksum: name_template: "{{ .ProjectName }}_checksums.txt" archives: - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" format_overrides: - goos: windows format: zip files: - README.md - public/**/* ================================================ FILE: README.md ================================================ # dark-dmzj 方便得浏览动漫之家藏起来的漫画. [dark-dmzj.hloli.net](https://dark-dmzj.hloli.net) ## usage 1. 下载安装动漫之家手机APP. 2. 手机浏览器打开 [https://dark-dmzj.hloli.net](https://dark-dmzj.hloli.net). ![gif](https://i.imgur.com/NQdMDLo.gif) ![cat](https://i.imgur.com/dtG3c3Q.jpg) ================================================ FILE: dark_dmzj.go ================================================ package main import ( "crypto/tls" "encoding/json" "fmt" "github.com/labstack/echo" "github.com/labstack/echo/middleware" "github.com/tidwall/gjson" "gopkg.in/cheggaaa/pb.v1" "io" "io/ioutil" "math/rand" "net/http" "os" "path/filepath" "sort" "time" ) var client *http.Client var bar *pb.ProgressBar var isDownloading bool type dmzjBook struct { ID uint64 `json:"id"` Title string `json:"title"` IsLong int64 `json:"islong"` Authors []string `json:"authors"` Types []string `json:"types"` Status []string `json:"status"` Cover string `json:"cover"` LastUpdateChapterName string `json:"last_update_chapter_name"` LastUpdateChapterID uint64 `json:"last_update_chapter_id"` LastUpdateTime int64 `json:"last_updatetime"` } func init() { client = &http.Client{ Transport: &http.Transport{ MaxIdleConnsPerHost: 256, MaxIdleConns: 256, ResponseHeaderTimeout: 10 * time.Second, TLSHandshakeTimeout: 10 * time.Second, TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), }, Timeout: time.Second * 10, } ex, err := os.Executable() if err != nil { panic(err) } exPath := filepath.Dir(ex) if _, err := os.Stat(filepath.Join(exPath, "public", "index.html")); !os.IsNotExist(err) { if err := os.Chdir(exPath); err != nil { panic(err) } } } func apiWithRetry(id int, try int) string { for i := 0; i < try; i++ { domains := []string{"v3api.dmzj1.com/comic/comic_"} res, err := client.Get(fmt.Sprintf("http://%s%d.json", domains[rand.Intn(1)], id)) resCk, errCk := client.Get(fmt.Sprintf("https://api.m.dmzj.com/info/%d.html", id)) if err == nil { defer res.Body.Close() defer io.Copy(ioutil.Discard, res.Body) } if errCk == nil { defer resCk.Body.Close() defer io.Copy(ioutil.Discard, resCk.Body) } if err == nil && res.StatusCode == 200 { body, _ := ioutil.ReadAll(res.Body) if errCk == nil && resCk.StatusCode == 200 { bodyCk, _ := ioutil.ReadAll(resCk.Body) if len(bodyCk) > 1024 { return "" } return string(body) } } } return "" } func getItem(id int, c chan<- string) { c <- apiWithRetry(id, 5) bar.Increment() } func arrayMap(vs []string, f func(string) []string) [][]string { vsm := make([][]string, len(vs)) for i, v := range vs { vsm[i] = f(v) } return vsm } func downloadBooks() { if isDownloading { return } isDownloading = true defer func() { isDownloading = false }() MaxRoutines := 50 MaxBooks := 70000 bar = pb.New(MaxBooks - 1).Prefix("Updating ") bar.SetWidth(60) bar.ShowTimeLeft = true bar.ShowCounters = false bar.ShowSpeed = true bar.Start() defer bar.FinishPrint("Finish!") c := make(chan string, MaxBooks) jobs := make(chan int, MaxBooks) for i := 0; i < MaxRoutines; i++ { go func() { for e := range jobs { getItem(e, c) } }() } for i := 1; i < MaxBooks; i++ { jobs <- i } items := []dmzjBook{} for p := 1; p < MaxBooks; p++ { dat := gjson.Parse(<-c) if dat.Get("id").Exists() { tags := arrayMap([]string{"authors", "types", "status"}, func(v string) []string { tag := []string{} for _, e := range dat.Get(v).Array() { tag = append(tag, e.Get("tag_name").String()) } return tag }) items = append(items, dmzjBook{ ID: dat.Get("id").Uint(), Title: dat.Get("title").String(), IsLong: dat.Get("islong").Int(), Authors: tags[0], Types: tags[1], Status: tags[2], Cover: dat.Get("cover").String(), LastUpdateChapterName: dat.Get("chapters.0.data.0.chapter_title").String(), LastUpdateChapterID: dat.Get("chapters.0.data.0.chapter_id").Uint(), LastUpdateTime: dat.Get("last_updatetime").Int(), }) } } sort.Slice(items, func(a, b int) bool { return items[a].LastUpdateTime > items[b].LastUpdateTime }) jsonDat, _ := json.Marshal(items) ioutil.WriteFile("public/data.json", jsonDat, 0644) } func main() { go func() { time.Sleep(1 * time.Second) downloadBooks() }() e := echo.New() e.HideBanner = true e.Static("/", "public") e.Use(middleware.GzipWithConfig(middleware.GzipConfig{ Level: 5, })) e.GET("/webpic/*", func(c echo.Context) error { req, _ := http.NewRequest("GET", fmt.Sprintf("http://images.dmzj.com%s", c.Request().URL.Path), nil) req.Header.Set("Referer", "https://m.dmzj.com/") res, err := client.Do(req) if err != nil { return c.NoContent(http.StatusBadGateway) } defer res.Body.Close() data, _ := ioutil.ReadAll(res.Body) return c.Blob(res.StatusCode, res.Header.Get("Content-Type"), data) }) e.Logger.Fatal(e.Start(":7777")) } ================================================ FILE: go.mod ================================================ module github.com/torta/dark-dmzj require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/fatih/color v1.7.0 // indirect github.com/labstack/echo v3.3.10+incompatible github.com/labstack/gommon v0.2.8 // indirect github.com/mattn/go-colorable v0.0.9 // indirect github.com/mattn/go-isatty v0.0.4 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/stretchr/testify v1.3.0 // indirect github.com/tidwall/gjson v1.1.5 github.com/tidwall/match v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 // indirect golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613 // indirect golang.org/x/sys v0.0.0-20190130150945-aca44879d564 // indirect gopkg.in/cheggaaa/pb.v1 v1.0.27 ) ================================================ FILE: hotupdate.go ================================================ // +build !windows package main import ( "os" "os/signal" "syscall" ) func init() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGUSR1) go func() { for { <-c downloadBooks() } }() } ================================================ FILE: public/dmzj.css ================================================ body,button,dd,dl,dt,fieldset,h1,h2,h3,h4,h5,h6,hr,input,lengend,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0}body,html{height:100%}body{background:#f5f5f5;font-family:"PingFang SC","Microsoft YaHei","微软雅黑",SimSun,"宋体",Arial,STHeiti,"华文黑体",Helvetica,Tahoma,Arial sans-serif}body,button,input,select,textarea{font-size:12px}ol,ul{list-style:none}a{text-decoration:none;cursor:pointer;outline:0}a:hover{text-decoration:none}fieldset,img{border:none}button,input,select,textarea{font-size:100%}.header{height:46px;background-size:100% 2px;background-color:#fff}.header .serCh{display:none;width:100%;height:44px;background:#fff;position:absolute;left:0;top:0;z-index:5}.serChinputBox{margin-right:92px;height:10px}.searInput{-webkit-appearance:none;width:100%;float:left;height:30px;border:1px solid #cbcbcb;margin:8px 0 0 10px;border-radius:2px 0 0 2px;border-right:0;background:#f5f5f5;outline:0;font-size:15px;padding:0 5px}.searBtn{width:33px;height:28px;border:1px solid #cbcbcb;float:right;margin:8px 0 0 0;border-radius:0 2px 2px 0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAiCAMAAADmrkDzAAAAUVBMVEUAAAA1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTWDH6iCAAAAGnRSTlMA84gUz8rp4dzEPgxiWCcbBo1HRuCoSbGmIVJ8jhUAAADTSURBVDjLzZNZDsMgDEQNDVvIvrWZ+x+0UmkgTSz5t/Nlw5PMGJuyah2sUjbomlg1Hlm+ud/vBnB67ofYTdoDZr8AtYVrS9o62N9Ss8Izng/iC2o65Z3CSBeNUF3JDFa6aYUpLuDinYgO2ZFHS4xa+MMHFmK14OtHQ7NAuQiYeGJCSIFFzxM9bAoUBp4YoGRCrnK8dBZeKrgVOiZ2Xf45+fflCSrauCncUpiRyyRnoBQ6tmHo5882dBTMQ9gog+qCUD2mrRxTox5VQnj9I2JIQEx4A1Y8D2zeFlbPAAAAAElFTkSuQmCC) no-repeat center;background-size:17px 17px;background-color:#f5f5f5;border-left:0}.searClose{width:31px;height:28px;border:1px solid #cbcbcb;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATBAMAAACAfiv/AAAAIVBMVEUAAAA1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTXjvRxHAAAACnRSTlMAFNTO2BnFLii7fcpN5AAAAGdJREFUCNctzaENgDAQheGHINgGJqgiqYJgCCMgSQeoYh5mAEM6JeS/O3X5xP+0BHFH0Rb52r2ov+H8BDUpgrMEg4JBYxAeQbg6Sl195ZcrbZorbRuizRBtQ9qGgg2N04/wpNOTw/UBx1EX2JLOhUoAAAAASUVORK5CYII=) no-repeat center;background-size:10px 10px;border-radius:2px;float:right;margin:8px 10px 0 5px;background-color:#f5f5f5}.messagSjr{width:100%;position:absolute;top:46px;z-index:4;background:#fff;z-index:888}.messagSjr .keyTit li{margin:0 10px;padding:0 5px;height:40px;border-bottom:1px solid #cbcbcb;line-height:40px;font-size:14px}.UpdateList{margin-top:7px;background:#fff}.UpdateList .itemBox{height:114px;border-bottom:1px solid #cbcbcb;padding-top:10px;margin-left:10px;position:relative}.UpdateList .itemImg{width:78px;height:103px;float:left;display:block;position:relative}.UpdateList .itemImg img{border-radius:2px}.UpdateList .itemTxt{height:114px;margin-left:88px;padding-right:10px}.UpdateList .itemTxt .title{height:33px;display:block;padding-right:80px;color:#000;line-height:33px;font-size:15px;text-overflow:ellipsis;overflow:hidden}.UpdateList .itemTxt .txtItme{display:block;height:15px;line-height:15px;font-size:12px;color:#000;opacity:.9;margin:7px 0}.UpdateList .itemTxt .txtItme .pd{padding-right:5px}.UpdateList .itemTxt .txtItme .icon{float:left;display:block;width:15px;height:15px;float:left;display:block;margin-right:5px}.UpdateList .itemTxt .txtItme .icon.icon01{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAZlBMVEUAAABmvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP/m9P9twP/w+f+ByP9wwf9qvv/////L6f+x3f+/4//2+/+Y0v+V0f+JzP+84v/U7P/X7f/W7f+k1/+i1v/o0ERqAAAADXRSTlMA6pQE+VdMEMWArceByQzOeQAAAQZJREFUKM+Fk+mSgyAQhMULTTIcIqAx2eP9X3J1tUeSWOX3h5IG6bkypqjzRpSlaPK6yN6RrSBGtPJVrSDiQJWIRU4f5AWrFzrgAp3vTs9heE58f3sX379q7LpR/eC7+vcMV1Z1y9IpC3+L/xaH/X1d7x477eyLQzJ6XbXh8IqsJtBD7gnUs21g8HNDu/mGwAPWIoEmw9PLvhq1HtV8CoisJGYa+plhIqbcZRdNsE7bYKLbZQH128O5/4Iu2Fr0xPgIawjMrklBYiwCq7eoAiWEx5YWJBV1QHW2pKIkwaWyCygJCnqAkGiHQyo00yH5SSueNPL5GAB5E4l4k6mGEbwuI3hNR/AP2holij6C64EAAAAASUVORK5CYII=);background-size:100%}.UpdateList .itemTxt .txtItme .icon.icon02{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAeFBMVEUAAABmvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP/////w+P/6/f+LzP96xf+y3v/r9/+Rz/9pvv+AyP91w//m9P/a7/+94v+34P/y+v/R6//G5v+W0v/2+//f8f/K6P8CnX0IAAAAEXRSTlMA6QSS+VcQlUyA68Wtx8aBTV5wTfMAAAEBSURBVCjPhdNtc4MgDAfwABZF+7AUta5d1da2+/7fcDMFQll3/l+Id78DckcCIbJQW5FlYqsKCWm0ERhSGv2qK0KOWEUoc/yTXAZd45usvSt8m9zdi/+E7tdc1dd031Pqkeqb6zes58fpSH+3mhYDIAXrdUbKnr5CQpHop7U3z1iA8tp9017bNDawggopbTfNmnAFwulAa3K4gOypI8Y5Os6efO7xJe3dMx1+SXi6+sMrurA+xDpcTr40heypooICUx+sV/wAWSY+sgrJT9L8OmmLPsY9KPshUqG5Hcj7vmNF14558O4Rab7QiguNvDQGHL0rGcudZuER3MwjuIlH8AcPlDETmzg0tgAAAABJRU5ErkJggg==);background-size:100%}.UpdateList .itemTxt .txtItme .icon.icon03{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAY1BMVEUAAABmvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9mvP9wwf/p9v/a7/+Y0v/+///N6f+k1/+Mzf/4/P/s9/+54P+d1P+Ax//v+f/n9P/X7v+/4/98xv/qsHowAAAADnRSTlMA6ZT5V0wQgOvErcfGgcWY6r4AAAD0SURBVCjPhZNZFoMgDEXFuYNRBBVn97/KCqFGsae8D3P0SniQJCAl4ZtFEXuHSXBTmjE4lGfplcYGklh8piHcFBJ9wg893bW1VF03y/q6Praw4s1YlmPDK/tDbDyjq75qwaqtevSn/WdIeUnblhx5tmOGmTUlPpv8bL8r8z61cFE7mZCg7WEBK27jMqD5hw6y+WJhYyP184Fbq83Fm8LNIx06cDF+iiw+fE9CCK69I8bk8wiORkzuWgPHGh2MRAfzXUuQ/7lUT0mooOu5oCsV1NMO1EyDVEIoOVAzeVrR08j+MUClRU4wL1IiNIIvPYKv8wh+AJ7oKJ0DK8hKAAAAAElFTkSuQmCC);background-size:100%}.UpdateList .coll{width:50px;height:15px;color:#000;overflow:hidden;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE0AAABOCAMAAABSQ2ssAAAA3lBMVEUAAAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/tAD/////+/D/6K3/wCf/uxf/uA7/tgX//vn/vyP//PX/+/L/6rX/2Hj/vR3/+OX/8dD/67r/02n/zlX/+er/9uH/wzL/wi7/uhH/3In/yUj/5qn/46D/0F3/4Zn/24P/x0D/xTkRj11eAAAAKHRSTlMAUhHv1+zcuLP7+fyPSh0CVcWEP1nz6LyTcWNhKAHTubWmo9+XbifPferQzAAAAptJREFUWMPtmNd22kAQhleo0Yxp7gVsJ86MBAjRe7Od8v4vFAOHE82gEEBzwUW+y9GZj7MsK2Z/FUrsvlC8yX95snOGpesJ+ORCv7S+5eLP1/mv2cJ9TO1DTEvblp6Ef5LULTut7ZKea/EEHEQirp2rcDQDjsDQwlwZG47EzijOmQlHY54x2W0KIpC6I7I7iEhQd5aCiKT+LDajQ2T0zVY8XIEAVw9rWxZEyK5PgAEiGKtToYEQ2tIWByHiy7dGAoRIxMhCBZaaBjHSStkghq2UxUq/3sZ1DDL6PlnWJ+8jUq6P3ytAsZQygTBdq2hjG6AdUm90gGAqlQTCHN/8Gqn48zouFlif095ZpY9tICSVAkoffwKnjf1lJ2eILqvEuK2LHeBU0XGwCpwp9ljlldh810H0YAv8BEI+BB3XhwCFoK3isLbdNm9ZdoIbmw3aXGxV0Nll4+VOi3x3N0Gbg9XqIbYG1qrYDBTyijTB7BCbgzUgD66ZrRbJ9ixqizObh41DdgGoLae2nkawPYraXkRtl6I2XdR2IWqD/7YT2AX9hH+9Lyd86mXfSGVR25Oo7VrUlt+2efv/19eZ7YbbHJzta5uhw2xFbuthu1Pbx1bzf2CP2QrcNkBKt/XhrW3eh9tFypDZXrkNhv1xkwmHq06mcsatBTBbTCWJjeP5g96mvzfwPeAgkknVZE+2GTRWI/MAOLzHJBP+ZhzlTEaIowmEQSYuSymbTIPhummjOYUw6DRoK5Xmk+r+8Ek1TW9tFbeJB9F0AzLQZG+Uordd2Zu4bEogmWAUZdMV0eRHOpXacAsRuRVN80STRsEUtJRRIWSPS2izculxWTvfnWyXDHOfZNs0StvJ9u7UvZwzLFNPblL3x3XqXvxr6v4bzaRYyhqP0ToAAAAASUVORK5CYII=) no-repeat 6px 0;background-size:39px;float:right;padding-top:45px;line-height:18px;font-size:12px;opacity:.9;text-align:center;position:absolute;top:37px;right:12px}.UpdateList .coll:hover{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE4AAABOCAMAAAC5dNAvAAAA2FBMVEUAAAD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/ogD/////+vH/pw//4a3/sSf/pAX//vz/9eL/tDD/+/P/rR//5LX/rBn/+e//9+j/5rr/yWn/wVX/qxf/04b/zXf/ryT//Pf/3J3/vEj/79H/68n/4Kn/0Hz/xF3/uDz/79SHA+hiAAAAJ3RSTlMAUvy46u7Us/L43dliV0pAKB0SApUQj4Nx4cfDu6NVppGFblvepw6iItqwAAACr0lEQVRYw82Y6XKiUBBGm01Egxr3mMRk1m5AUNzX7Mm8/xuNZSo13JbJuPRUef7Rt/pYeIG6/UE6tVLxW/NL9YfRyucsS8c1WcvMZS7t69vGV7dY+gk7UdbqRt5y8J84Vt6oa2X4hIpm67gXuq1V4C9oGTyAjAZpnBt4IMY5bFEw8WDMAjDOdDwC/YzZ8EgUX0HHI9ELiV2w8GisP/txhQJcfdjaKEIbNlQyKEL+/f3QUAhto7NRCBvWlHUUQi+zexW421sUow4ABophAECO1d6euxElGd/3cE3vfqyU77r3HVTJAYCJCr2ItoiWiMuUetxHBRMAHFRY0PPKVyr9RUQPDxQt1Ga/M6ElKjgANVSZ0BtyXmgyoRfkzChglRqUWGVMQ+TMyfNSyj16ZJUSFDHBKvCIQtyC1mDKr5AXrDBBEdzEVWfE+j7XhbRmlNxeF5qJq4AGHfI+0/Fyf6D8f01oJK48Gs730d2RP6Q4UWhAVelCfx+dRz4qC1W4kdRdgyGps6Gl6kK622crUNVdQmZr+QhdBi4kdReyOhNMSV0WsiesQ8CT1mVPWJcVflCkH+Pvoi+Z9CfgUlLXAltSZ8C1pO4GqpK6KjQkdQ1osuWIwt1PARHTNcFlOo/8XXU+jZjOhSLT/aJl399F568W9MR0RSgx3ZRUuoPX8F0XvgZdUpkxXQlqTIezSddjxtmmlbm87uABma4G4Cg6TtifPn4InqZ9tk2sxwEAky1tM41pTTxFDu8x1UHg48TK6Y2Jxj1MY06xOggYynFxnu6L43TbUDkuGuoQ1RnRXvDDbJ2NeJ3Ao73wgoQNNeEBVHo8lh/eK3k8Bh4tgIsiuLKxjHBoJBtpyQZusnGgcFgpH6Vy2ocFvW3hGPr/h+TpEf6N0crkTMtJRvjVTYRfg1R+AyqRRSgxTWieAAAAAElFTkSuQmCC) no-repeat;background-size:39px} ================================================ FILE: public/index.html ================================================ Dark Dmzj
  • 1. 下载安装动漫之家手机APP.
  • 2. 手机浏览器打开 https://dark-dmzj.hloli.net
/
{{ item.title }}

{{ item.authors.join('/') }}

{{ type }}

{{ moment(item.last_updatetime * 1000).format('YYYY-MM-DD H:mm') }}

{{ item.last_update_chapter_name }}
Fork me on GitHub