#!/usr/bin/env python2 # requires lxml, requests, cssselect, pillow import sys import os from io import BytesIO from lxml import html import requests from PIL import Image if len(sys.argv) != 3: print "usage: shonenmagazine.py " sys.exit(1) dom = html.fromstring(requests.get(sys.argv[1]).content) page_elements = dom.cssselect("img.page-image.js-page-image") if len(page_elements) == 0: print "No pages found!" sys.exit(1) print "%d pages found" % len(page_elements) print "" dir = sys.argv[2] if not os.path.exists(dir): os.makedirs(dir) i = 0 for page in page_elements: i += 1 src = page.get("data-src") or page.get("src") if src is None or src == "": print "Page %d is missing source, skipping..." % i continue drm = page.get("data-cho-ju-giga") != "usagi" try: raw = BytesIO(requests.get(src).content) except: print "Page %d could not be downloaded, skipping..." % i try: source = Image.open(raw) except: print "Page %d could not be opened, skipping..." % i if not drm: filename = "%d.%s" % (i, source.format.lower()) path = os.path.join(dir, filename) print "Page %d does not use DRM, saving original: %s" % (i, path) try: with open(path, 'wb') as file: file.write(raw) except: print "Error saving %s" % path continue dest = Image.new(source.mode, source.size) filename = "%d.png" % i path = os.path.join(dir, filename) print "Decoding page %d and saving to: %s" % (i, path) ''' From bundle.js: r.DIVIDE_NUM = 4, r.MULTIPLE = 8, r.width = n.width, r.height = n.height, r.cell_width = Math.floor(r.width / (r.DIVIDE_NUM * r.MULTIPLE)) * r.MULTIPLE, r.cell_height = Math.floor(r.height / (r.DIVIDE_NUM * r.MULTIPLE)) * r.MULTIPLE [...] t.prototype.solve = function() { if (this.skipDrm) this.view.showOriginalImage(); else { this.view.drawImage(0, 0, this.width, this.height, 0, 0); for (var e = 0; e < this.DIVIDE_NUM * this.DIVIDE_NUM; e++) { var t = Math.floor(e / this.DIVIDE_NUM) * this.cell_height , n = e % this.DIVIDE_NUM * this.cell_width , r = Math.floor(e / this.DIVIDE_NUM) , i = e % this.DIVIDE_NUM , o = r , a = i , u = a * this.DIVIDE_NUM + o , s = u % this.DIVIDE_NUM * this.cell_width , c = Math.floor(u / this.DIVIDE_NUM) * this.cell_height; this.view.drawImage(n, t, this.cell_width, this.cell_height, s, c) // ^- a.drawImage(this.$puzzledImage[0], sx, sy, sWidth, sHeight, dx, dy, sWidth, sHeight) } this.view.replaceImage() } } ''' def draw_subimage(sx, sy, sWidth, sHeight, dx, dy): rect = source.crop((sx, sy, sx+sWidth, sy+sHeight)) dest.paste(rect, (dx, dy, dx+sWidth, dy+sHeight)) DIVIDE_NUM = 4 MULTIPLE = 8 cell_width = (source.width / (DIVIDE_NUM * MULTIPLE)) * MULTIPLE cell_height = (source.height / (DIVIDE_NUM * MULTIPLE)) * MULTIPLE for e in range(0, DIVIDE_NUM * DIVIDE_NUM): t = e / DIVIDE_NUM * cell_height n = e % DIVIDE_NUM * cell_width r = e / DIVIDE_NUM i_ = e % DIVIDE_NUM u = i_ * DIVIDE_NUM + r s = u % DIVIDE_NUM * cell_width c = (u / DIVIDE_NUM) * cell_height draw_subimage(n, t, cell_width, cell_height, s, c) dest.save(path)