Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
fffonion committed Aug 4, 2016
0 parents commit 251f9ec
Show file tree
Hide file tree
Showing 22 changed files with 2,543 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.py[cod]

.atomignore
*.pyc
*.json
*.sh
*.log
release
desktop.ini
verinfo.txt
config.py
make.bat
674 changes: 674 additions & 0 deletions LICENSE.txt

Large diffs are not rendered by default.

Binary file added icon3.ico
Binary file not shown.
58 changes: 58 additions & 0 deletions make_verinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# coding:utf-8
from xeHentai import const

version = const.__version__
v = []
t = version
for i in range(4):
v.append(str(int(t)))
t = (t - int(t)) * 10

tmpl='''# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(%s),
prodvers=(%s),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x40004,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'080404B0',
[StringStruct(u'FileVersion', u'%s'),
StringStruct(u'ProductVersion', u'%s'),
StringStruct(u'OriginalFilename', u'xeHentai-%s.exe'),
StringStruct(u'InternalName', u'xeHentai'),
StringStruct(u'FileDescription', u'绅♂士漫画下载器'),
StringStruct(u'CompanyName', u'[email protected]'),
StringStruct(u'LegalCopyright', u'GPLv3'),
StringStruct(u'ProductName', u'xeHentai')])
]),
VarFileInfo([VarStruct(u'Translation', [2052, 1200])])
]
)''' % (
", ".join(v), ", ".join(v),
".".join(v), ".".join(v), version
)

open("verinfo.txt", "wb").write(tmpl)
61 changes: 61 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python

PROJ_NAME = 'xeHentai'
PACKAGE_NAME = 'xeHentai'

PROJ_METADATA = '%s.json' % PROJ_NAME

import os, json, imp
here = os.path.abspath(os.path.dirname(__file__))

try:
README = open(os.path.join(here, 'README.md')).read()
except:
README = ""
try:
CHANGELOG = open(os.path.join(here, 'CHANGELOG.md')).read()
except:
CHANGELOG = ""
VERSION = imp.load_source('version', os.path.join(here, '%s/const.py' % PACKAGE_NAME)).__version__

packages = [
'xeHentai',
'xeHentai.util',
'xeHentai.i18n',
]
requires = ['requests']

from setuptools import setup

setup(
name=PACKAGE_NAME,
version=VERSION,
description='xeHentai Downloader',
long_description=README + '\n\n' + CHANGELOG,
author='fffonion',
author_email='[email protected]',
url='https://yooooo.us/2013/xehentai',
packages=packages,
package_dir={'requests': 'requests'},
include_package_data=True,
install_requires=requires,
license='GPLv3',
zip_safe=False,
classifiers=(
'Development Status :: 4 - Beta',
'Intended Audience :: End Users/Desktop',
'Natural Language :: English',
'License :: OSI Approved :: GPLv3',
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy'
),
requires=requires,
entry_points = {'console_scripts': ["xeH = xeHentai.cli:start"]},
)
5 changes: 5 additions & 0 deletions xeH
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python

from xeHentai import cli

cli.start()
5 changes: 5 additions & 0 deletions xeH.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python

from xeHentai import cli

cli.start()
1 change: 1 addition & 0 deletions xeHentai/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/usr/bin/env python
151 changes: 151 additions & 0 deletions xeHentai/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/env python
# coding:utf-8
# Contributor:
# fffonion <[email protected]>

from __future__ import absolute_import
import os
import time
import argparse
import traceback
from threading import Thread
from .i18n import i18n
from .core import xeHentai
from .const import *
from .util import logger

sys.path.insert(1, FILEPATH)
try:
import config
except ImportError:
from . import config
sys.path.pop(1)

def start():
opt = parse_opt()
xeH = xeHentai()
xeH.update_config(vars(opt))
if opt.daemon:
if os.name == "posix":
pid = os.fork()
if pid == 0:
sys.stdin.close()
sys.stdout = open("/dev/null", "w")
sys.stderr = open("/dev/null", "w")
return main(xeH, opt)
elif os.name == "nt":
import multiprocessing
p = multiprocessing.Process(target = main, args = (xeH, opt, ))
p.start()
pid = p.pid
else:
return xeH.logger.error(i18n.XEH_PLATFORM_NO_DAEMON % os.name)
xeH.logger.info(i18n.XEH_DAEMON_START % pid)
else:
main(xeH, opt)

def main(xeH, opt):
log = xeH.logger
log.info(i18n.XEH_STARTED % xeH.verstr)
if opt.cookie:
xeH.set_cookie(opt.cookie)
if opt.username and opt.key and not xeH.has_login:
xeH.login_exhentai(opt.username, opt.key)
if opt.interactive:
try:
r = interactive(xeH)
opt.__dict__.update(r)
xeH.update_config(r)
except KeyboardInterrupt:
log.info(i18n.XEH_CLEANUP)
xeH._cleanup()
return
try:
if opt.urls:
for u in opt.urls:
xeH.add_task(u)
# finished this task and exit xeHentai
Thread(target = lambda:(time.sleep(0.618), setattr(xeH, "_exit", XEH_STATE_SOFT_EXIT))).start()
Thread(target = xeH._task_loop, name = "main" ).start()
while xeH._exit < XEH_STATE_CLEAN:
time.sleep(1)
except KeyboardInterrupt:
log.info(i18n.XEH_CLEANUP)
except Exception as ex:
log.error(i18n.XEH_CRITICAL_ERROR % traceback.format_exc())
else:
sys.exit(0) # this is mandatory for single task auto exit
try:
xeH._term_threads()
# we should call cleanup ourself because we break out of task_loop
xeH._cleanup()
except KeyboardInterrupt:
pass
# this is mandatory for ctrl+c kill
os._exit(0)

''' -ro --redirect-norm 是否应用在线代理到已解析到的非原图,默认不启用
-f --force 即使超出配额也下载,默认为否
-re --rename 是否重命名成原始文件名
-j --no-jp-name 是否不使用日语命名,默认为否'''

def parse_opt():
parser = argparse.ArgumentParser(description = i18n.XEH_OPT_DESC, epilog = i18n.XEH_OPT_EPILOG)
# the followings are handled in cli
parser.add_argument('-u', '--username', help = i18n.XEH_OPT_u)
parser.add_argument('-k', '--key', help = i18n.XEH_OPT_k)
parser.add_argument('-c', '--cookie', help = i18n.XEH_OPT_c)
parser.add_argument('-i', '--interactive', action = 'store_true', default = False,
help = i18n.XEH_OPT_i)
# the followings are passed to xeHentai
parser.add_argument('urls', metavar = 'url', type = str, nargs = '*',
help = i18n.XEH_OPT_URLS)
parser.add_argument('-o', '--download-ori',
action = 'store_true', default = config.download_ori,
help = i18n.XEH_OPT_o)
parser.add_argument('-t', '--thread', type = int, metavar = 'N',
default = config.download_thread_cnt, dest = 'download_thread_cnt',
help = i18n.XEH_OPT_t)
parser.add_argument('-f', '--fast-scan', action = 'store_true', default = config.fast_scan,
help = i18n.XEH_OPT_f)
parser.add_argument('-d', '--dir', default = os.path.abspath(config.dir),
help = i18n.XEH_OPT_d)
parser.add_argument('--daemon', action = 'store_true', default = config.daemon,
help = i18n.XEH_OPT_daemon)
parser.add_argument('-l', '--logpath', metavar = '/path/to/eh.log',
default = os.path.abspath(config.log_path), help = i18n.XEH_OPT_l)
parser.add_argument('-p', '--proxy', action = 'append', default = config.proxy,
help = i18n.XEH_OPT_p)
parser.add_argument('-v', '--verbose', action = 'count', default = config.log_verbose,
help = i18n.XEH_OPT_v)
parser.add_argument('--rpc-port', type = int, metavar = "PORT", default = config.rpc_port,
help = i18n.XEH_OPT_rpc_port)
parser.add_argument('--rpc-interface', metavar = "ADDR", default = config.rpc_interface,
help = i18n.XEH_OPT_rpc_interface)
# parser.add_argument('--rpc-secret', metavar = "...", default = config.rpc_secret,
# help = i18n.XEH_OPT_rpc_secret)

args = parser.parse_args()
return args

def interactive(xeH):
def _readline(s):
if not isinstance(s, unicode):
s = s.decode("utf-8")
return raw_input(logger.convhans(s).encode(locale.getdefaultlocale()[1] or 'utf-8', 'replace'))

if not xeH.has_login and _readline(i18n.PS_LOGIN) == "y":
uname = pwd = ""
while not uname:
uname = _readline(i18n.PS_USERNAME)
while not pwd:
pwd = _readline(i18n.PS_PASSWD)
xeH.login_exhentai(uname, pwd)
url = proxy = ""
while not url:
url = _readline(i18n.PS_URL)
url = url.split(",")
download_ori = _readline(i18n.PS_DOWNLOAD_ORI) == "y"
proxy = _readline(i18n.PS_PROXY).strip()
proxy = [proxy] if proxy else None
return {'urls': url, 'proxy': proxy, 'download_ori': download_ori}
67 changes: 67 additions & 0 deletions xeHentai/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python
# coding:utf-8
# constants module
# Contributor:
# fffonion <[email protected]>

import os
import sys
import locale

PY3K = sys.version_info[0] == 3
IRONPYTHON = sys.platform == 'cli'
EXEBUNDLE = os.path.split(sys.argv[0])[1].find('py') == -1
LOCALE = locale.getdefaultlocale()[0]
CODEPAGE = locale.getdefaultlocale()[1]
ANDROID = 'ANDROID_ARGUMENT' in os.environ

__version__ = 2.0
DEVELOPMENT = True

SCRIPT_NAME = "xeHentai"

# https://github.com/soimort/you-get/you-get
if getattr(sys, 'frozen', False):
# The application is frozen
FILEPATH = os.path.dirname(os.path.realpath(sys.executable))
else:
# The application is not frozen
# Change this bit to match where you store your data files:
FILEPATH = sys.path[0]

XEH_STATE_RUNNING = 0
XEH_STATE_SOFT_EXIT = 1 # wait until current task finish and exit
XEH_STATE_FULL_EXIT = 2 # finish current task stage and exit
XEH_STATE_CLEAN = 3

TASK_STATE_PAUSED = 0
TASK_STATE_WAITING = 1
TASK_STATE_GET_META = 2
TASK_STATE_GET_HATHDL = 3
TASK_STATE_SCAN_PAGE = 4
TASK_STATE_SCAN_IMG = 5
TASK_STATE_DOWNLOAD = 10
TASK_STATE_FINISHED = 20
TASK_STATE_FAILED = -1

ERR_NO_ERROR = 0
ERR_URL_NOT_RECOGNIZED = 1000
ERR_CANT_DOWNLOAD_EXH = 1001
ERR_ONLY_VISIBLE_EXH = 1002
ERR_MALFORMED_HATHDL = 1003
ERR_GALLERY_REMOVED = 1004
ERR_IMAGE_RESAMPLED = 1005
ERR_QUOTA_EXCEEDED = 1006
ERR_KEY_EXPIRED = 1007
ERR_NO_PAGEURL_FOUND = 1008
ERR_TASK_NOT_FOUND = 1101
ERR_SAVE_SESSION_FAILED = 1103
ERR_TASK_LEVEL_UNDEF = 1104
ERR_DELETE_RUNNING_TASK = 1105
ERR_TASK_CANNOT_PAUSE = 1106
ERR_TASK_CANNOT_RESUME = 1107
ERR_RPC_PARSE_ERROR = -32700
ERR_RPC_INVALID_REQUEST = -32600
ERR_RPC_METHOD_NOT_FOUND = -32601
ERR_RPC_INVALID_PARAMS = -32601
ERR_RPC_EXEC_ERROR = -32603
Loading

0 comments on commit 251f9ec

Please sign in to comment.