mangaProxy / mangaProxy.py /
4425a6c 3 years ago
1 contributor
538 lines | 23.115kb
#!/usr/bin/env python3
from http.server import BaseHTTPRequestHandler, HTTPServer
import datetime
from time import perf_counter 
import os
import json
import urllib.parse
import configuration
import socket
import requests
import re
from userio import *

# Random Example URL: https://manganelo.tv/chapter/dy925032/chapter_21
# Random Example URL: https://manganelo.tv/chapter/read_rurouni_kenshin/chapter_257

server = None
csvFilename = None
connectionResults = None
opacity = -1

def getReadManganatoCOM(url):
  global opacity
  say("getReadManganatoCOM: "+url)
  r = requests.get(url, allow_redirects=True)
  content = r.text

  #print(r.text)
  lineNextChapter = None
  linePreviousChapter = None
  lineTitle = None
  linkNext = None
  linkPrev = None
  listImages = []

  for line in content.split("\n"):
    if "<meta property=\"og:title\" content=\"" in line and lineTitle is None:
      lineTitle = line
    elif "<div class=\"navi-change-chapter-btn\">" in line:
      if lineNextChapter is None and linkNext is None:
        #for subLine in line.split("><"):
        for subLine in line.split("<a rel="):
          if "NEXT CHAPTER" in subLine:
            linkNext=subLine.split("\"")[5]
      elif linePreviousChapter is None and linkPrev is None:
        subLinePrev=""
        for subLine in line.split("<a rel="):
          if "PREV CHAPTER" in subLine:
            linkPrev=subLine.split("\"")[5]
    elif "<img src=\"" in line:
      if ".jpg" in line:
        for subLine in line.split("><img"):
          if ".jpg" in subLine:
            listImages.append(subLine.split("\"")[1])
            debug(line.split("\"")[1])

  if None is not linePreviousChapter:
    say("Prev :"+str(len(linePreviousChapter)))
    #i.e First chapter is opened
    if 200 < len(linePreviousChapter):
      tempLine = linePreviousChapter 
      linePreviousChapter = None
      for line in tempLine.split("><"):
        if "navi-change-chapter-btn-prev a-h" in line and linePreviousChapter is None:
          linePreviousChapter = line
      linkPrev=linePreviousChapter.split("\"")[5]
    else:
      linkPrev="https://manganelo.tv"+linePreviousChapter.split("\"")[5]

  if None is not lineNextChapter:
    #i.e Last chapter is opened
    say("Next :"+str(len(lineNextChapter)))
    if 200 < len(lineNextChapter):
      tempLine = lineNextChapter 
      lineNextChapter = None
      for line in tempLine.split("><"):
        if "navi-change-chapter-btn-next a-h" in line and lineNextChapter is None:
          lineNextChapter = line
      linkNext=lineNextChapter.split("\"")[5]
    else:
      linkNext="https://manganelo.tv"+lineNextChapter.split("\"")[5]
        
  mangaImagesNum = len(listImages)
  mangaTitle=lineTitle.split("\"")[3].split(" - MangaNato")[0]
  mangaTitle=lineTitle.split("\"")[3].split(" - Manganelo")[0]
  say("Manga :"+mangaTitle)
  pageContent = ""
  pageContent += "<div class=\"mangaChapNavig\">\n"
  pageContent += "  <div class=\"mangaTitle\">"+mangaTitle+"</div>\n"
  if linkPrev is not None:
    pageContent += "  <div class=\"mangaChapNavigPrev\"><a href=\"?url="+linkPrev+"\"><div class=\"arrow-left\"></div><div class=\"arrow-left\"></div></a></div>\n"
  if linkNext is not None:
    pageContent += "  <div class=\"mangaChapNavigNext\"><a href=\"?url="+linkNext+"\"><div class=\"arrow-right\"></div><div class=\"arrow-right\"></div></a></div>\n"
  pageContent += "  <div class=\"mangaChapNavigHome\"><a href=\".\"><div class=\"arrow-up\"></div></a></div>\n"
  pageContent += "  <span id=\"mangaCurrPage\"></span><span id=\"mangaNumPages\"> / "+str(mangaImagesNum)+"</span>\n"
  pageContent += "  <span id=\"mangaFSStatus\" style=\"display: none;\">0</span>\n"
  pageContent += "  <span id=\"mangaFSToggle\" onclick=\"openFullscreen();\"><div class=\"fs-on\"></div></span>\n"
  if opacity == -1:
    opacityValue=2;
    if 7 <= datetime.datetime.now().hour and 20 >= datetime.datetime.now().hour:
      opacityValue=10;
    opacity=opacityValue
  pageContent += "  <span id=\"mangaOpacityMinus\" onclick=\"onOpacityMinus()\">&#9788;</span>"
  pageContent += "  <span id=\"mangaOpacityValue\">"+str(opacity)+"</span>"
  pageContent += "  <span id=\"mangaOpacityPlus\" onclick=\"onOpacityPlus()\">&#9728;</span>\n"
  pageContent += "  <span id=\"mangaReload\" onClick=\"window.location.reload();\"><div class=\"reload-circle\"></div></span>\n" 
  pageContent += "</div>\n"
  
  pageContent += "<a name=\"article-top\"></a><div id=\"article-current\"></div>\n"
  pageContent += "<div class=\"row\">\n\n"

  cpt = 0
  for pageImage in listImages:
    #debug(pageImage)
    pageContent += "<div class=\"article\" id=\"article-"+str(cpt)+"\" style=\"display: none;\">\n"
    pageContent += "  <div class=\"column\" id=\"colLeft\" onclick=\"onArticle("+str(cpt-1)+")\">\n"
    pageContent += "    <div class=\"arrow-left\"></div>\n"
    pageContent += "  </div><!-- /column colLeft -->\n"
        
    pageContent += "  <div class=\"column\" id=\"colMiddle\">\n"
    pageContent += "    <a name=\"article-"+str(cpt)+"\">\n"
    pageContent += "    <img src=\"defer.png\" data-src=\""+pageImage+"\" class=\"center\">\n"
    #pageContent += "    <li>"+str(cpt)+" : "+pageImage+"</li>\n"
    pageContent += "  </div><!-- /column colMiddle -->\n\n"
    
    pageContent += "  <div class=\"column\" id=\"colRight\" onclick=\"onArticle("+str(cpt+1)+")\">\n"
    pageContent += "    <div class=\"arrow-right\"></div>\n"
    pageContent += "  </div><!-- /column colRight -->\n"
    pageContent += "</div>\n"
    pageContent += "\n"
    cpt += 1

  pageContent += "</div><!-- /row -->\n"
  return pageContent

def getMangakakalotCom(url):
  global opacity
  debug("getMangakakalotCom :"+url)
  r = requests.get(url, allow_redirects=True)
  content = r.text
  
  isMangakakalot = 1
  lineNextChapter = None
  linePreviousChapter = None
  lineTitle = None
  linkNext = None
  linkPrev = None
  listImages = []
  for line in content.split("\n"):
    if "<meta property=\"og:title\" content=\"" in line and lineTitle is None:
      lineTitle = line

    elif isMangakakalot == 1 and "<div class='btn-navigation-chap'>" in line and lineNextChapter is None and linkNext is None:
      for subLine in line.split("><"):
        if "NEXT CHAPTER" in subLine:
          linkNext=subLine.split("'")[1]
          debug("linkNext: "+linkNext)
    elif isMangakakalot == 1 and "<div class='btn-navigation-chap'>" in line and linePreviousChapter is None and linkPrev is None:
      for subLine in line.split("><"):
        if "PREV CHAPTER" in subLine:
          linkPrev=subLine.split("'")[1]
          debug("linkPrev: "+linkPrev)

    elif "<img class=\"img-loading\" data-src=\"" in line:
      if ".jpg" in line:
        listImages.append(line.split("\"")[3])    

  if 0 == len(listImages):
    # Attempt to extract images once more, most likely all are on one line
    for line in content.split("\n"):
      if " page " in line:
        for subLine in line.split("><"):
          if "https://" in subLine:
            if ".jpg" in subLine.split("\"")[1]:
              listImages.append(subLine.split("\"")[1])

  if None is not linePreviousChapter:
    say("Prev :"+str(len(linePreviousChapter)))
    #i.e First chapter is opened
    if 200 < len(linePreviousChapter):
      tempLine = linePreviousChapter 
      linePreviousChapter = None
      for line in tempLine.split("><"):
        if "navi-change-chapter-btn-prev a-h" in line and linePreviousChapter is None:
          linePreviousChapter = line
      linkPrev=linePreviousChapter.split("\"")[5]
    else:
      linkPrev="https://manganelo.tv"+linePreviousChapter.split("\"")[5]

  if None is not lineNextChapter:
    #i.e Last chapter is opened
    say("Next :"+str(len(lineNextChapter)))
    if 200 < len(lineNextChapter):
      tempLine = lineNextChapter 
      lineNextChapter = None
      for line in tempLine.split("><"):
        if "navi-change-chapter-btn-next a-h" in line and lineNextChapter is None:
          lineNextChapter = line
      linkNext=lineNextChapter.split("\"")[5]
    else:
      linkNext="https://manganelo.tv"+lineNextChapter.split("\"")[5]
        
  mangaImagesNum = len(listImages)
  mangaTitle=lineTitle.split("\"")[3].split(" - Manganelo")[0]
  say("Manga :"+mangaTitle)
  pageContent = ""
  pageContent += "<div class=\"mangaChapNavig\">\n"
  pageContent += "  <div class=\"mangaTitle\">"+mangaTitle+"</div>\n"
  if linkPrev is not None:
    pageContent += "  <div class=\"mangaChapNavigPrev\"><a href=\"?url="+linkPrev+"\"><div class=\"arrow-left\"></div><div class=\"arrow-left\"></div></a></div>\n"
  if linkNext is not None:
    pageContent += "  <div class=\"mangaChapNavigNext\"><a href=\"?url="+linkNext+"\"><div class=\"arrow-right\"></div><div class=\"arrow-right\"></div></a></div>\n"
  pageContent += "  <div class=\"mangaChapNavigHome\"><a href=\".\"><div class=\"arrow-up\"></div></a></div>\n"
  pageContent += "  <span id=\"mangaCurrPage\"></span><span id=\"mangaNumPages\"> / "+str(mangaImagesNum)+"</span>\n"
  pageContent += "  <span id=\"mangaFSStatus\" style=\"display: none;\">0</span>\n"
  pageContent += "  <span id=\"mangaFSToggle\" onclick=\"openFullscreen();\"><div class=\"fs-on\"></div></span>\n"
  if opacity == -1:
    opacityValue=2;
    if 7 <= datetime.datetime.now().hour and 20 >= datetime.datetime.now().hour:
      opacityValue=10;
    opacity=opacityValue
  pageContent += "  <span id=\"mangaOpacityMinus\" onclick=\"onOpacityMinus()\">&#9788;</span>"
  pageContent += "  <span id=\"mangaOpacityValue\">"+str(opacity)+"</span>"
  pageContent += "  <span id=\"mangaOpacityPlus\" onclick=\"onOpacityPlus()\">&#9728;</span>\n"
  pageContent += "  <span id=\"mangaReload\" onClick=\"window.location.reload();\"><div class=\"reload-circle\"></div></span>\n" 
  pageContent += "</div>\n"
  
  pageContent += "<a name=\"article-top\"></a><div id=\"article-current\"></div>\n"
  pageContent += "<div class=\"row\">\n\n"

  cpt = 0
  for pageImage in listImages:
    #debug(pageImage)
    pageContent += "<div class=\"article\" id=\"article-"+str(cpt)+"\" style=\"display: none;\">\n"
    pageContent += "  <div class=\"column\" id=\"colLeft\" onclick=\"onArticle("+str(cpt-1)+")\">\n"
    pageContent += "    <div class=\"arrow-left\"></div>\n"
    pageContent += "  </div><!-- /column colLeft -->\n"
        
    pageContent += "  <div class=\"column\" id=\"colMiddle\">\n"
    pageContent += "    <a name=\"article-"+str(cpt)+"\">\n"
    pageContent += "    <img src=\"defer.png\" data-src=\""+pageImage+"\" class=\"center\">\n"
    #pageContent += "    <li>"+str(cpt)+" : "+pageImage+"</li>\n"
    pageContent += "  </div><!-- /column colMiddle -->\n\n"
    
    pageContent += "  <div class=\"column\" id=\"colRight\" onclick=\"onArticle("+str(cpt+1)+")\">\n"
    pageContent += "    <div class=\"arrow-right\"></div>\n"
    pageContent += "  </div><!-- /column colRight -->\n"
    pageContent += "</div>\n"
    pageContent += "\n"
    cpt += 1

  pageContent += "</div><!-- /row -->\n"
  return pageContent

def getManganeloTV(url):
  global opacity
  debug("getManganeloTV :"+url)
  r = requests.get(url, allow_redirects=True)
  content = r.text
  
  isMangakakalot = 0
  #print(r.text)
  lineNextChapter = None
  linePreviousChapter = None
  lineTitle = None
  linkNext = None
  linkPrev = None
  listImages = []
  for line in content.split("\n"):
    if "navi-change-chapter-btn-prev a-h" in line and linePreviousChapter is None:
      linePreviousChapter = line
    elif "navi-change-chapter-btn-next a-h" in line and lineNextChapter is None:
      print("Found at"+str(line))
      lineNextChapter = line

    elif "<meta property=\"og:title\" content=\"" in line and lineTitle is None:
      lineTitle = line

    elif isMangakakalot == 1 and "<div class='btn-navigation-chap'>" in line and lineNextChapter is None and linkNext is None:
      for subLine in line.split("><"):
        if "NEXT CHAPTER" in subLine:
          linkNext=subLine.split("'")[1]
    elif isMangakakalot == 1 and "<div class='btn-navigation-chap'>" in line and linePreviousChapter is None and linkPrev is None:
      for subLine in line.split("><"):
        if "PREV CHAPTER" in subLine:
          linkPrev=subLine.split("'")[1]

    elif "<img class=\"img-loading\" data-src=\"" in line:
      if ".jpg" in line:
        listImages.append(line.split("\"")[3])    
  if None is not linkNext:
    print("NEXT :"+linkNext)
  if None is not linkPrev:
    print("PREV :"+linkPrev)

  if 0 == len(listImages):
    # Attempt to extract images once more, most likely all are on one line
    for line in content.split("\n"):
      if " page " in line:
        for subLine in line.split("><"):
          if "https://" in subLine:
            if ".jpg" in subLine.split("\"")[1]:
              listImages.append(subLine.split("\"")[1])

  if None is not linePreviousChapter:
    say("Prev :"+str(len(linePreviousChapter)))
    #i.e First chapter is opened
    if 200 < len(linePreviousChapter):
      tempLine = linePreviousChapter 
      linePreviousChapter = None
      for line in tempLine.split("><"):
        if "navi-change-chapter-btn-prev a-h" in line and linePreviousChapter is None:
          linePreviousChapter = line
      linkPrev=linePreviousChapter.split("\"")[5]
    else:
      linkPrev="https://manganelo.tv"+linePreviousChapter.split("\"")[5]

  if None is not lineNextChapter:
    #i.e Last chapter is opened
    say("Next :"+str(len(lineNextChapter)))
    if 200 < len(lineNextChapter):
      tempLine = lineNextChapter 
      lineNextChapter = None
      for line in tempLine.split("><"):
        if "navi-change-chapter-btn-next a-h" in line and lineNextChapter is None:
          lineNextChapter = line
      linkNext=lineNextChapter.split("\"")[5]
    else:
      linkNext="https://manganelo.tv"+lineNextChapter.split("\"")[5]
        
  mangaImagesNum = len(listImages)
  mangaTitle=lineTitle.split("\"")[3].split(" - Manganelo")[0]
  say("Manga :"+mangaTitle)
  pageContent = ""
  pageContent += "<div class=\"mangaChapNavig\">\n"
  pageContent += "  <div class=\"mangaTitle\">"+mangaTitle+"</div>\n"
  if linkPrev is not None:
    pageContent += "  <div class=\"mangaChapNavigPrev\"><a href=\"?url="+linkPrev+"\"><div class=\"arrow-left\"></div><div class=\"arrow-left\"></div></a></div>\n"
  if linkNext is not None:
    pageContent += "  <div class=\"mangaChapNavigNext\"><a href=\"?url="+linkNext+"\"><div class=\"arrow-right\"></div><div class=\"arrow-right\"></div></a></div>\n"
  pageContent += "  <div class=\"mangaChapNavigHome\"><a href=\".\"><div class=\"arrow-up\"></div></a></div>\n"
  pageContent += "  <span id=\"mangaCurrPage\"></span><span id=\"mangaNumPages\"> / "+str(mangaImagesNum)+"</span>\n"
  pageContent += "  <span id=\"mangaFSStatus\" style=\"display: none;\">0</span>\n"
  pageContent += "  <span id=\"mangaFSToggle\" onclick=\"openFullscreen();\"><div class=\"fs-on\"></div></span>\n"
  if opacity == -1:
    opacityValue=2;
    if 7 <= datetime.datetime.now().hour and 20 >= datetime.datetime.now().hour:
      opacityValue=10;
    opacity=opacityValue
  pageContent += "  <span id=\"mangaOpacityMinus\" onclick=\"onOpacityMinus()\">&#9788;</span>"
  pageContent += "  <span id=\"mangaOpacityValue\">"+str(opacity)+"</span>"
  pageContent += "  <span id=\"mangaOpacityPlus\" onclick=\"onOpacityPlus()\">&#9728;</span>\n"
  pageContent += "  <span id=\"mangaReload\" onClick=\"window.location.reload();\"><div class=\"reload-circle\"></div></span>\n" 
  pageContent += "</div>\n"
  
  pageContent += "<a name=\"article-top\"></a><div id=\"article-current\"></div>\n"
  pageContent += "<div class=\"row\">\n\n"

  cpt = 0
  for pageImage in listImages:
    #debug(pageImage)
    pageContent += "<div class=\"article\" id=\"article-"+str(cpt)+"\" style=\"display: none;\">\n"
    pageContent += "  <div class=\"column\" id=\"colLeft\" onclick=\"onArticle("+str(cpt-1)+")\">\n"
    pageContent += "    <div class=\"arrow-left\"></div>\n"
    pageContent += "  </div><!-- /column colLeft -->\n"
        
    pageContent += "  <div class=\"column\" id=\"colMiddle\">\n"
    pageContent += "    <a name=\"article-"+str(cpt)+"\">\n"
    pageContent += "    <img src=\"defer.png\" data-src=\""+pageImage+"\" class=\"center\">\n"
    #pageContent += "    <li>"+str(cpt)+" : "+pageImage+"</li>\n"
    pageContent += "  </div><!-- /column colMiddle -->\n\n"
    
    pageContent += "  <div class=\"column\" id=\"colRight\" onclick=\"onArticle("+str(cpt+1)+")\">\n"
    pageContent += "    <div class=\"arrow-right\"></div>\n"
    pageContent += "  </div><!-- /column colRight -->\n"
    pageContent += "</div>\n"
    pageContent += "\n"
    cpt += 1

  pageContent += "</div><!-- /row -->\n"
  return pageContent

class MyServer(BaseHTTPRequestHandler):
    def log_message(self, format, *args):
        # To silence the default output of server (too verbose)
        return  
    def do_GET(self):
        global opacity
        global csvFilename
        global csvFilenameTemp
        global connectionResults
        rootdir = 'pages/static/'
        csvFilename = rootdir + server['csv']
        csvFilenameTemp = rootdir + server['csvTemp']

        if '/list.html' in self.path:
            page=[]
            data_begin = ""

            with open(configuration.get_pageBegin(),'r') as fStart:
                data_begin += fStart.read().replace( 'CSTAPPNAME', server['name'] )
            
            data_end = ""
            with open(configuration.get_pageEnd(),'r') as fEnd:
                data_end += fEnd.read().replace( 'CSTAPPNAME', server['name'] ).replace( 'CSTAPPVERSION', server['version'] )

            data_page = ""
            with open("list.html", "rt") as f:
                lines=f.readlines()
                for line in lines:
                    data_page += "<li><a href=\"./?url="+line.split("@")[0]+"\">"+line.split("@")[1]+"</a></li>"
                    f.close()
            page.append(data_begin)
            page.append(data_page)
            page.append(data_end)
            content = ''.join(page)
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.send_header('Server',server['name']+" v"+server['version'])
            self.end_headers()
            self.wfile.write(content.encode('utf-8'))

        elif not os.path.exists(rootdir + self.path) or self.path == '/index.html' or self.path == '/':
            if self.headers['X-Real-IP'] is None:
                say("From: "+self.client_address[0]+" GET Received : "+self.path)
            else:
                say("From: "+self.headers['X-Real-IP']+" GET Received : "+self.path)
            page=[]

            data_begin = ""
            with open(configuration.get_pageBegin(),'r') as fStart:
                data_begin += fStart.read().replace( 'CSTAPPNAME', server['name'] )
            
            data_end = ""
            with open(configuration.get_pageEnd(),'r') as fEnd:
                data_end += fEnd.read().replace( 'CSTAPPNAME', server['name'] ).replace( 'CSTAPPVERSION', server['version'] )


            s = self.path
            urlArgs = urllib.parse.parse_qs(s[2:])
            url = None
            if "url" in urlArgs:
                url = urlArgs['url'][0]

            data_page = ""

            opacity=-1
            #try:
                #if urlArgs['opacity'] is not None:
                #    opacity=urlArgs['opacity'][0]
                #print(self)
            #except:
                #pass

            #Forging response
            #if configuration.get_debug() != 0:
            #    data_page += "<p>Request: "+self.path+"</p>\n"
            #    data_page += "<xmp>"+json.dumps(urlArgs)+"</xmp>\n"

            if not url is None:
                if "manganelo" in url:
                    data_page += getManganeloTV(url)
                elif "readmanganato.com" in url:
                    data_page += getReadManganatoCOM(url)
                elif "mangakakalot.com" in url:
                    data_page += getMangakakalotCom(url)
                else:
                    warn("Unsupported Hoster at "+url)
                    data_page += "<span id=\"lbl\">Unsupported hoster at "+url+"</span>"
                    data_page += "<div class=\"mangaChapNavigHome\"><a href=\".\"><div class=\"arrow-up\"></div></a></div>"

            else:
                try:
                    with open(server['favorite'], "rt") as f:
                        lines=f.readlines()
                        for line in lines:
                            data_page += "<li><a href=\"./?url="+line+"\">"+line+"</a></li>"
                        f.close()
                except:
                    pass
                data_form = "<form action=\"\">\n\
<span id=\"lbl\">Url:</span>\n\
<input type=\"text\" id=\"srvIp\" name=\"url\" value=\"\">\n\
<input type=\"submit\" value=\"Read Online\">\n\
</form>\n"
                data_page += data_form

            page.append(data_begin)          
            page.append(data_page)
            page.append(data_end)
            content = ''.join(page)
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.send_header('Server',server['name']+" v"+server['version'])
            self.end_headers()
            self.wfile.write(content.encode('utf-8'))

        elif not os.path.exists(rootdir + self.path):
            self.send_header('Server',server['name']+" v"+server['version'])
            self.send_error(404, 'file not found')
        else:
            try:
                #say(self.path)
                f = open(rootdir + self.path,'rb') #open requested file
                self.send_response(200)
                if self.path.endswith('.css'):
                    self.send_header('Content-type','text/css')
                elif self.path.endswith('.bmp'):
                    self.send_header('Content-type','image/x-ms-bmp')
                elif self.path.endswith('.png'):
                    self.send_header('Content-type','image/png')
                elif self.path.endswith('.jpg'):
                    self.send_header('Content-type','image/jpeg')
                else:
                    self.send_header('Content-type','text/html')
                self.send_header('Server',server['name']+" v"+server['version'])
                self.end_headers()
                self.wfile.write(f.read())
                f.close()
                return
            except IOError:
                self.send_header('Server',server['name']+" v"+server['version'])
                self.send_error(404, 'file not found')

if __name__ == "__main__":        
    #global server
    server = configuration.get_server()
    say(server['name']+" v"+server['version'])
    webServer = HTTPServer((server['address'], server['port']), MyServer)
    say("Server started http://%s:%s" % (server['address'], server['port']))

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Server stopped.")