Advertisement
Guest User

Untitled

a guest
Dec 15th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 83.85 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # pylint: disable=I0011, C, C0302
  4.  
  5. import sys
  6. reload(sys)
  7. sys.setdefaultencoding("utf-8")
  8.  
  9. import os
  10. import re
  11. import traceback
  12. import gc
  13. import time
  14. import datetime
  15. import urllib2
  16. import getpass
  17. import httplib
  18. import codecs
  19.  
  20. from BeautifulSoup import BeautifulSoup
  21.  
  22. if os.name == 'nt':
  23.     # enable unicode support on windows console.
  24.     import win_unicode_console
  25.     win_unicode_console.enable()
  26.  
  27. import PixivConstant
  28. import PixivConfig
  29. import PixivDBManager
  30. import PixivHelper
  31. from PixivModel import PixivArtist, PixivImage, PixivListItem, PixivBookmark, PixivTags
  32. from PixivModel import PixivNewIllustBookmark, PixivGroup
  33. from PixivException import PixivException
  34. import PixivBrowserFactory
  35.  
  36. from optparse import OptionParser
  37.  
  38. import random
  39.  
  40. script_path = PixivHelper.module_path()
  41.  
  42. np_is_valid = False
  43. np = 0
  44. op = ''
  45. DEBUG_SKIP_PROCESS_IMAGE = False
  46. ERROR_CODE = 0
  47.  
  48. gc.enable()
  49. # gc.set_debug(gc.DEBUG_LEAK)
  50.  
  51. import mechanize
  52. # replace unenscape_charref implementation with our implementation due to bug.
  53. mechanize._html.unescape_charref = PixivHelper.unescape_charref
  54.  
  55. __config__ = PixivConfig.PixivConfig()
  56. configfile = "config.ini"
  57. __dbManager__ = None
  58. __br__ = None
  59. __blacklistTags = list()
  60. __suppressTags = list()
  61. __log__ = PixivHelper.GetLogger()
  62. __errorList = list()
  63. __blacklistMembers = list()
  64.  
  65. # http://www.pixiv.net/member_illust.php?mode=medium&illust_id=18830248
  66. __re_illust = re.compile(r'member_illust.*illust_id=(\d*)')
  67. __re_manga_page = re.compile(r'(\d+(_big)?_p\d+)')
  68.  
  69.  
  70. # -T04------For download file
  71. def download_image(url, filename, referer, overwrite, max_retry, backup_old_file=False, image_id=None, page=None):
  72.     global ERROR_CODE
  73.     tempErrorCode = None
  74.     retry_count = 0
  75.     while retry_count <= max_retry:
  76.         res = None
  77.         req = None
  78.         try:
  79.             try:
  80.                 if not overwrite and not __config__.alwaysCheckFileSize:
  81.                     print 'Checking local filename...',
  82.                     if os.path.exists(filename) and os.path.isfile(filename):
  83.                         PixivHelper.printAndLog('info', "File exists: {0}".format(filename.encode('utf-8')))
  84.                         return PixivConstant.PIXIVUTIL_SKIP_DUPLICATE
  85.  
  86.                 print 'Getting remote filesize...'
  87.                 # open with HEAD method
  88.                 req = PixivHelper.createCustomRequest(url, __config__, referer, head=True)
  89.                 res = __br__.open_novisit(req)
  90.  
  91.                 # get file size
  92.                 file_size = -1
  93.                 try:
  94.                     file_size = int(res.info()['Content-Length'])
  95.                 except KeyError:
  96.                     file_size = -1
  97.                     PixivHelper.printAndLog('info', "\tNo file size information!")
  98.                 print "Remote filesize = {0} ({1} Bytes)".format(PixivHelper.sizeInStr(file_size), file_size)
  99.  
  100.                 # check if existing file exists
  101.                 if os.path.exists(filename) and os.path.isfile(filename) and not filename.endswith(".zip"):
  102.                     old_size = os.path.getsize(filename)
  103.                     checkResult = PixivHelper.checkFileExists(overwrite, filename, file_size, old_size, backup_old_file)
  104.                     if checkResult != 1:
  105.                         return checkResult
  106.  
  107.                 # check for ugoira file
  108.                 if filename.endswith(".zip"):
  109.                     ugoName = filename[:-4] + ".ugoira"
  110.                     gifName = filename[:-4] + ".gif"
  111.                     apngName = filename[:-4] + ".png"
  112.                     # non-converted zip (no animation.json)
  113.                     if os.path.exists(filename) and os.path.isfile(filename):
  114.                         # not sure what is the proper handling, currently it will throw error after download due to file already exists.
  115.                         pass
  116.                     # converted to ugoira (has animation.json)
  117.                     if os.path.exists(ugoName) and os.path.isfile(ugoName):
  118.                         old_size = PixivHelper.getUgoiraSize(ugoName)
  119.                         checkResult = PixivHelper.checkFileExists(overwrite, ugoName, file_size, old_size, backup_old_file)
  120.                         if checkResult != 1:
  121.                             # try to convert existing file.
  122.                             if __config__.createGif and not os.path.exists(gifName):
  123.                                 PixivHelper.ugoira2gif(ugoName, gifName)
  124.                             if __config__.createApng and not os.path.exists(apngName):
  125.                                 PixivHelper.ugoira2apng(ugoName, apngName)
  126.  
  127.                             return checkResult
  128.  
  129.                 # check based on filename stored in DB using image id
  130.                 if image_id is not None:
  131.                     db_filename = None
  132.                     if page is not None:
  133.                         row = __dbManager__.selectImageByImageIdAndPage(image_id, page)
  134.                         if row is not None:
  135.                             db_filename = row[2]
  136.                     else:
  137.                         row = __dbManager__.selectImageByImageId(image_id)
  138.                         if row is not None:
  139.                             db_filename = row[3]
  140.                     if db_filename is not None and os.path.exists(db_filename) and os.path.isfile(db_filename):
  141.                         old_size = os.path.getsize(db_filename)
  142.                         checkResult = PixivHelper.checkFileExists(overwrite, db_filename, file_size, old_size, backup_old_file)
  143.                         if checkResult != 1:
  144.                             ugoName = None
  145.                             if db_filename.endswith(".zip"):
  146.                                 ugoName = db_filename[:-4] + ".ugoira"
  147.                                 gifName = db_filename[:-4] + ".gif"
  148.                                 apngName = db_filename[:-4] + ".png"
  149.                             if db_filename.endswith(".ugoira"):
  150.                                 ugoName = db_filename
  151.                                 gifName = db_filename[:-7] + ".gif"
  152.                                 apngName = db_filename[:-7] + ".png"
  153.  
  154.                             if ugoName is not None and os.path.exists(ugoName) and os.path.isfile(ugoName):
  155.                                 # try to convert existing file.
  156.                                 if __config__.createGif and not os.path.exists(gifName):
  157.                                     PixivHelper.ugoira2gif(ugoName, gifName)
  158.                                 if __config__.createApng and not os.path.exists(apngName):
  159.                                     PixivHelper.ugoira2apng(ugoName, apngName)
  160.  
  161.                             return checkResult
  162.  
  163.                 # actual download
  164.                 print 'Start downloading...',
  165.                 req = PixivHelper.createCustomRequest(url, __config__, referer)
  166.                 res = __br__.open_novisit(req)
  167.                 downloadedSize = PixivHelper.downloadImage(url, filename, res, file_size, overwrite)
  168.  
  169.                 # check the downloaded file size again
  170.                 if file_size > 0 and downloadedSize != file_size:
  171.                     raise PixivException("Incomplete Downloaded for {0}".format(url), PixivException.DOWNLOAD_FAILED_OTHER)
  172.                 elif __config__.verifyImage and (filename.endswith(".jpg") or filename.endswith(".png") or filename.endswith(".gif")):
  173.                     fp = None
  174.                     try:
  175.                         from PIL import Image, ImageFile
  176.                         fp = open(filename, "rb")
  177.                         # Fix Issue #269, refer to https://stackoverflow.com/a/42682508
  178.                         ImageFile.LOAD_TRUNCATED_IMAGES = True
  179.                         img = Image.open(fp)
  180.                         img.load()
  181.                         fp.close()
  182.                         PixivHelper.printAndLog('info', ' Image verified.')
  183.                     except:
  184.                         if fp is not None:
  185.                             fp.close()
  186.                         PixivHelper.printAndLog('info', ' Image invalid, deleting...')
  187.                         os.remove(filename)
  188.                         raise
  189.                 elif __config__.verifyImage and (filename.endswith(".ugoira") or filename.endswith(".zip")):
  190.                     fp = None
  191.                     try:
  192.                         import zipfile
  193.                         fp = open(filename, "rb")
  194.                         zf = zipfile.ZipFile(fp)
  195.                         zf.testzip()
  196.                         fp.close()
  197.                         PixivHelper.printAndLog('info', ' Image verified.')
  198.                     except:
  199.                         if fp is not None:
  200.                             fp.close()
  201.                         PixivHelper.printAndLog('info', ' Image invalid, deleting...')
  202.                         os.remove(filename)
  203.                         raise
  204.                 else:
  205.                     PixivHelper.printAndLog('info', ' done.')
  206.  
  207.                 # write to downloaded lists
  208.                 if start_iv or __config__.createDownloadLists:
  209.                     dfile = codecs.open(dfilename, 'a+', encoding='utf-8')
  210.                     dfile.write(filename + "\n")
  211.                     dfile.close()
  212.  
  213.                 return PixivConstant.PIXIVUTIL_OK
  214.  
  215.             except urllib2.HTTPError as httpError:
  216.                 PixivHelper.printAndLog('error', '[download_image()] HTTP Error: {0} at {1}'.format(str(httpError), url))
  217.                 if httpError.code == 404 or httpError.code == 502:
  218.                     return PixivConstant.PIXIVUTIL_NOT_OK
  219.                 tempErrorCode = PixivException.DOWNLOAD_FAILED_NETWORK
  220.                 raise
  221.             except urllib2.URLError as urlError:
  222.                 PixivHelper.printAndLog('error', '[download_image()] URL Error: {0} at {1}'.format(str(urlError), url))
  223.                 tempErrorCode = PixivException.DOWNLOAD_FAILED_NETWORK
  224.                 raise
  225.             except IOError as ioex:
  226.                 if ioex.errno == 28:
  227.                     PixivHelper.printAndLog('error', ioex.message)
  228.                     raw_input("Press Enter to retry.")
  229.                     return PixivConstant.PIXIVUTIL_NOT_OK
  230.                 tempErrorCode = PixivException.DOWNLOAD_FAILED_IO
  231.                 raise
  232.             except KeyboardInterrupt:
  233.                 PixivHelper.printAndLog('info', 'Aborted by user request => Ctrl-C')
  234.                 return PixivConstant.PIXIVUTIL_ABORTED
  235.             finally:
  236.                 if res is not None:
  237.                     del res
  238.                 if req is not None:
  239.                     del req
  240.  
  241.         except:
  242.             if tempErrorCode is None:
  243.                 tempErrorCode = PixivException.DOWNLOAD_FAILED_OTHER
  244.             ERROR_CODE = tempErrorCode
  245.             exc_type, exc_value, exc_traceback = sys.exc_info()
  246.             traceback.print_exception(exc_type, exc_value, exc_traceback)
  247.             PixivHelper.printAndLog('error', 'Error at download_image(): {0} at {1} ({2})'.format(str(sys.exc_info()), url, ERROR_CODE))
  248.  
  249.             if retry_count < max_retry:
  250.                 retry_count = retry_count + 1
  251.                 print "Retrying [{0}]...".format(retry_count)
  252.                 PixivHelper.printDelay(__config__.retryWait)
  253.             else:
  254.                 raise
  255.  
  256.  
  257. #  Start of main processing logic
  258. def process_list(mode, list_file_name=None, tags=None):
  259.     global ERROR_CODE
  260.  
  261.     result = None
  262.     try:
  263.         # Getting the list
  264.         if __config__.processFromDb:
  265.             PixivHelper.printAndLog('info', 'Processing from database.')
  266.             if __config__.dayLastUpdated == 0:
  267.                 result = __dbManager__.selectAllMember()
  268.             else:
  269.                 print 'Select only last', __config__.dayLastUpdated, 'days.'
  270.                 result = __dbManager__.selectMembersByLastDownloadDate(__config__.dayLastUpdated)
  271.         else:
  272.             PixivHelper.printAndLog('info', 'Processing from list file: {0}'.format(list_file_name))
  273.             result = PixivListItem.parseList(list_file_name, __config__.rootDirectory)
  274.  
  275.         if os.path.exists("ignore_list.txt"):
  276.             PixivHelper.printAndLog('info', 'Processing ignore list for member: {0}'.format("ignore_list.txt"))
  277.             ignoreList = PixivListItem.parseList("ignore_list.txt", __config__.rootDirectory)
  278.             for ignore in ignoreList:
  279.                 for item in result:
  280.                     if item.memberId == ignore.memberId:
  281.                         result.remove(item)
  282.                         break
  283.  
  284.         print "Found " + str(len(result)) + " items."
  285.  
  286.         for item in result:
  287.             retry_count = 0
  288.             while True:
  289.                 try:
  290.                     process_member(mode, item.memberId, item.path, tags=tags)
  291.                     break
  292.                 except KeyboardInterrupt:
  293.                     raise
  294.                 except:
  295.                     if retry_count > __config__.retry:
  296.                         PixivHelper.printAndLog('error', 'Giving up member_id: ' + str(item.memberId))
  297.                         break
  298.                     retry_count = retry_count + 1
  299.                     print 'Something wrong, retrying after 2 second (', retry_count, ')'
  300.                     time.sleep(2)
  301.  
  302.             __br__.clear_history()
  303.             print 'done.'
  304.     except KeyboardInterrupt:
  305.         raise
  306.     except Exception as ex:
  307.         ERROR_CODE = getattr(ex, 'errorCode', -1)
  308.         print 'Error at process_list():', sys.exc_info()
  309.         print 'Failed'
  310.         __log__.exception('Error at process_list(): ' + str(sys.exc_info()))
  311.         raise
  312.  
  313.  
  314. def process_member(mode, member_id, user_dir='', page=1, end_page=0, bookmark=False, tags=None):
  315.     global __errorList
  316.     global ERROR_CODE
  317.     list_page = None
  318.  
  319.     PixivHelper.printAndLog('info', 'Processing Member Id: ' + str(member_id))
  320.     if page != 1:
  321.         PixivHelper.printAndLog('info', 'Start Page: ' + str(page))
  322.     if end_page != 0:
  323.         PixivHelper.printAndLog('info', 'End Page: ' + str(end_page))
  324.         if __config__.numberOfPage != 0:
  325.             PixivHelper.printAndLog('info', 'Number of page setting will be ignored')
  326.     elif np != 0:
  327.         PixivHelper.printAndLog('info', 'End Page from command line: ' + str(np))
  328.     elif __config__.numberOfPage != 0:
  329.         PixivHelper.printAndLog('info', 'End Page from config: ' + str(__config__.numberOfPage))
  330.  
  331.     __config__.loadConfig(path=configfile)
  332.  
  333.     # calculate the offset for display properties
  334.     offset = 20
  335.     if __br__._isWhitecube:
  336.         offset = 50
  337.     offset_start = (page - 1) * offset
  338.     offset_stop = end_page * offset
  339.  
  340.     try:
  341.         no_of_images = 1
  342.         is_avatar_downloaded = False
  343.         flag = True
  344.         updated_limit_count = 0
  345.         image_id = -1
  346.  
  347.         while flag:
  348.             print 'Page ', page
  349.             set_console_title("MemberId: " + str(member_id) + " Page: " + str(page))
  350.             # Try to get the member page
  351.             while True:
  352.                 try:
  353.                     (artist, list_page) = PixivBrowserFactory.getBrowser().getMemberPage(member_id, page, bookmark, tags)
  354.                     break
  355.                 except PixivException as ex:
  356.                     ERROR_CODE = ex.errorCode
  357.                     PixivHelper.printAndLog('info', 'Member ID (' + str(member_id) + '): ' + str(ex))
  358.                     if ex.errorCode == PixivException.NO_IMAGES:
  359.                         pass
  360.                     else:
  361.                         if list_page is None:
  362.                             list_page = ex.htmlPage
  363.                         if list_page is not None:
  364.                             PixivHelper.dumpHtml("Dump for " + str(member_id) + " Error Code " + str(ex.errorCode) + ".html", list_page)
  365.                         if ex.errorCode == PixivException.USER_ID_NOT_EXISTS or ex.errorCode == PixivException.USER_ID_SUSPENDED:
  366.                             __dbManager__.setIsDeletedFlagForMemberId(int(member_id))
  367.                             PixivHelper.printAndLog('info', 'Set IsDeleted for MemberId: ' + str(member_id) + ' not exist.')
  368.                             # __dbManager__.deleteMemberByMemberId(member_id)
  369.                             # PixivHelper.printAndLog('info', 'Deleting MemberId: ' + str(member_id) + ' not exist.')
  370.                         if ex.errorCode == PixivException.OTHER_MEMBER_ERROR:
  371.                             PixivHelper.safePrint(ex.message)
  372.                             __errorList.append(dict(type="Member", id=str(member_id), message=ex.message, exception=ex))
  373.                     return
  374.                 except AttributeError:
  375.                     # Possible layout changes, try to dump the file below
  376.                     raise
  377.                 except Exception:
  378.                     exc_type, exc_value, exc_traceback = sys.exc_info()
  379.                     traceback.print_exception(exc_type, exc_value, exc_traceback)
  380.                     PixivHelper.printAndLog('error', 'Error at processing Artist Info: ' + str(sys.exc_info()))
  381.                     __log__.exception('Error at processing Artist Info: ' + str(member_id))
  382.  
  383.             PixivHelper.safePrint('Member Name  : ' + artist.artistName)
  384.             print 'Member Avatar:', artist.artistAvatar
  385.             print 'Member Token :', artist.artistToken
  386.  
  387.             if artist.artistAvatar.find('no_profile') == -1 and not is_avatar_downloaded and __config__.downloadAvatar:
  388.                 if user_dir == '':
  389.                     target_dir = __config__.rootDirectory
  390.                 else:
  391.                     target_dir = user_dir
  392.  
  393.                 avatar_filename = PixivHelper.createAvatarFilename(artist, target_dir)
  394.                 if not DEBUG_SKIP_PROCESS_IMAGE:
  395.                     # hardcode the referer to pixiv main site
  396.                     download_image(artist.artistAvatar, avatar_filename, "https://www.pixiv.net/", __config__.overwrite,
  397.                                    __config__.retry, __config__.backupOldFile)
  398.                 is_avatar_downloaded = True
  399.  
  400.             __dbManager__.updateMemberName(member_id, artist.artistName)
  401.  
  402.             if not artist.haveImages:
  403.                 PixivHelper.printAndLog('info', "No image found for: " + str(member_id))
  404.                 flag = False
  405.                 continue
  406.  
  407.             result = PixivConstant.PIXIVUTIL_NOT_OK
  408.             for image_id in artist.imageList:
  409.                 print '#' + str(no_of_images)
  410.                 if mode == PixivConstant.PIXIVUTIL_MODE_UPDATE_ONLY:
  411.                     r = __dbManager__.selectImageByMemberIdAndImageId(member_id, image_id)
  412.                     if r is not None and not __config__.alwaysCheckFileSize:
  413.                         print 'Already downloaded:', image_id
  414.                         updated_limit_count = updated_limit_count + 1
  415.                         if updated_limit_count > __config__.checkUpdatedLimit:
  416.                             if __config__.checkUpdatedLimit != 0:
  417.                                 print 'Skipping member:', member_id
  418.                                 __dbManager__.updateLastDownloadedImage(member_id, image_id)
  419.  
  420.                                 del list_page
  421.                                 __br__.clear_history()
  422.                                 return
  423.                         gc.collect()
  424.                         continue
  425.  
  426.                 retry_count = 0
  427.                 while True:
  428.                     try:
  429.                         if artist.totalImages > 0:
  430.                             # PixivHelper.safePrint("Total Images = " + str(artist.totalImages))
  431.                             total_image_page_count = artist.totalImages
  432.                             if(offset_stop > 0 and offset_stop < total_image_page_count):
  433.                                 total_image_page_count = offset_stop
  434.                             total_image_page_count = total_image_page_count - offset_start
  435.                             # PixivHelper.safePrint("Total Images Offset = " + str(total_image_page_count))
  436.                         else:
  437.                             total_image_page_count = ((page - 1) * 20) + len(artist.imageList)
  438.                         title_prefix = "MemberId: {0} Page: {1} Image {2}+{3} of {4}".format(member_id,
  439.                                                                                              page,
  440.                                                                                              no_of_images,
  441.                                                                                              updated_limit_count,
  442.                                                                                              total_image_page_count)
  443.                         if not DEBUG_SKIP_PROCESS_IMAGE:
  444.                             result = process_image(mode, artist, image_id, user_dir, bookmark, title_prefix=title_prefix)  # Yavos added dir-argument to pass
  445.                             wait()
  446.  
  447.                         break
  448.                     except KeyboardInterrupt:
  449.                         result = PixivConstant.PIXIVUTIL_KEYBOARD_INTERRUPT
  450.                         break
  451.                     except:
  452.                         if retry_count > __config__.retry:
  453.                             PixivHelper.printAndLog('error', "Giving up image_id: " + str(image_id))
  454.                             return
  455.                         retry_count = retry_count + 1
  456.                         print "Stuff happened, trying again after 2 second (", retry_count, ")"
  457.                         exc_type, exc_value, exc_traceback = sys.exc_info()
  458.                         traceback.print_exception(exc_type, exc_value, exc_traceback)
  459.                         __log__.exception('Error at process_member(): ' + str(sys.exc_info()) + ' Member Id: ' + str(member_id))
  460.                         time.sleep(2)
  461.  
  462.                 no_of_images = no_of_images + 1
  463.  
  464.                 if result == PixivConstant.PIXIVUTIL_KEYBOARD_INTERRUPT:
  465.                     choice = raw_input("Keyboard Interrupt detected, continue to next image (Y/N)")
  466.                     if choice.upper() == 'N':
  467.                         PixivHelper.printAndLog("info", "Member: " + str(member_id) + ", processing aborted")
  468.                         flag = False
  469.                         break
  470.                     else:
  471.                         continue
  472.  
  473.                 # return code from process image
  474.                 if result == PixivConstant.PIXIVUTIL_SKIP_OLDER:
  475.                     PixivHelper.printAndLog("info", "Reached older images, skippin to next member.")
  476.                     flag = False
  477.                     break
  478.  
  479.             if artist.isLastPage:
  480.                 print "Last Page"
  481.                 flag = False
  482.  
  483.             page = page + 1
  484.  
  485.             # page limit checking
  486.             if end_page > 0 and page > end_page:
  487.                 print "Page limit reached (from endPage limit =" + str(end_page) + ")"
  488.                 flag = False
  489.             else:
  490.                 if np_is_valid:  # Yavos: overwriting config-data
  491.                     if page > np and np > 0:
  492.                         print "Page limit reached (from command line =" + str(np) + ")"
  493.                         flag = False
  494.                 elif page > __config__.numberOfPage and __config__.numberOfPage > 0:
  495.                     print "Page limit reached (from config =" + str(__config__.numberOfPage) + ")"
  496.                     flag = False
  497.  
  498.             del artist
  499.             del list_page
  500.             __br__.clear_history()
  501.             gc.collect()
  502.  
  503.         if image_id > 0:
  504.             __dbManager__.updateLastDownloadedImage(member_id, image_id)
  505.             log_message = 'last image_id: ' + str(image_id)
  506.         else:
  507.             log_message = 'no images were found'
  508.         print 'Done.\n'
  509.         __log__.info('Member_id: ' + str(member_id) + ' complete, ' + log_message)
  510.     except KeyboardInterrupt:
  511.         raise
  512.     except:
  513.         exc_type, exc_value, exc_traceback = sys.exc_info()
  514.         traceback.print_exception(exc_type, exc_value, exc_traceback)
  515.         PixivHelper.printAndLog('error', 'Error at process_member(): ' + str(sys.exc_info()))
  516.         __log__.exception('Error at process_member(): ' + str(member_id))
  517.         try:
  518.             if list_page is not None:
  519.                 dump_filename = 'Error page for member ' + str(member_id) + '.html'
  520.                 PixivHelper.dumpHtml(dump_filename, list_page)
  521.                 PixivHelper.printAndLog('error', "Dumping html to: " + dump_filename)
  522.         except:
  523.             PixivHelper.printAndLog('error', 'Cannot dump page for member_id:' + str(member_id))
  524.         raise
  525.  
  526.  
  527. def process_image(mode, artist=None, image_id=None, user_dir='', bookmark=False, search_tags='', title_prefix=None, bookmark_count=-1, image_response_count=-1):
  528.     global __errorList
  529.     global ERROR_CODE
  530.  
  531.     parse_big_image = None
  532.     parse_medium_page = None
  533.     image = None
  534.     result = None
  535.     referer = 'https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' + str(image_id)
  536.  
  537.     try:
  538.         filename = 'N/A'
  539.         print 'Processing Image Id:', image_id
  540.  
  541.         # check if already downloaded. images won't be downloaded twice - needed in process_image to catch any download
  542.         r = __dbManager__.selectImageByImageId(image_id)
  543.         if r is not None and not __config__.alwaysCheckFileSize:
  544.             if mode == PixivConstant.PIXIVUTIL_MODE_UPDATE_ONLY:
  545.                 print 'Already downloaded:', image_id
  546.                 gc.collect()
  547.                 return
  548.  
  549.         # get the medium page
  550.         try:
  551.             (image, parse_medium_page) = PixivBrowserFactory.getBrowser().getImagePage(imageId=image_id,
  552.                                                                                        parent=artist,
  553.                                                                                        fromBookmark=bookmark,
  554.                                                                                        bookmark_count=bookmark_count)
  555.             if title_prefix is not None:
  556.                 set_console_title(title_prefix + " ImageId: {0}".format(image.imageId))
  557.             else:
  558.                 set_console_title('MemberId: ' + str(image.artist.artistId) + ' ImageId: ' + str(image.imageId))
  559.  
  560.         except PixivException as ex:
  561.             ERROR_CODE = ex.errorCode
  562.             __errorList.append(dict(type="Image", id=str(image_id), message=ex.message, exception=ex))
  563.             if ex.errorCode == PixivException.UNKNOWN_IMAGE_ERROR:
  564.                 PixivHelper.safePrint(ex.message)
  565.             elif ex.errorCode == PixivException.SERVER_ERROR:
  566.                 PixivHelper.printAndLog('error', 'Giving up image_id (medium): ' + str(image_id))
  567.             elif ex.errorCode > 2000:
  568.                 PixivHelper.printAndLog('error', 'Image Error for ' + str(image_id) + ': ' + ex.message)
  569.             if parse_medium_page is not None:
  570.                 dump_filename = 'Error medium page for image ' + str(image_id) + '.html'
  571.                 PixivHelper.dumpHtml(dump_filename, parse_medium_page)
  572.                 PixivHelper.printAndLog('error', 'Dumping html to: ' + dump_filename)
  573.             else:
  574.                 PixivHelper.printAndLog('info', 'Image ID (' + str(image_id) + '): ' + str(ex))
  575.             return PixivConstant.PIXIVUTIL_NOT_OK
  576.         except Exception as ex:
  577.             PixivHelper.printAndLog('info', 'Image ID (' + str(image_id) + '): ' + str(ex))
  578.             if parse_medium_page is not None:
  579.                 dump_filename = 'Error medium page for image ' + str(image_id) + '.html'
  580.                 PixivHelper.dumpHtml(dump_filename, parse_medium_page)
  581.                 PixivHelper.printAndLog('error', 'Dumping html to: ' + dump_filename)
  582.             return PixivConstant.PIXIVUTIL_NOT_OK
  583.  
  584.         download_image_flag = True
  585.  
  586.         # date validation and blacklist tag validation
  587.         if __config__.dateDiff > 0:
  588.             if image.worksDateDateTime != datetime.datetime.fromordinal(1):
  589.                 if image.worksDateDateTime < datetime.datetime.today() - datetime.timedelta(__config__.dateDiff):
  590.                     PixivHelper.printAndLog('info', 'Skipping image_id: ' + str(image_id) + ' because contains older than: ' + str(__config__.dateDiff) + ' day(s).')
  591.                     download_image_flag = False
  592.                     result = PixivConstant.PIXIVUTIL_SKIP_OLDER
  593.  
  594.         if __config__.useBlacklistTags:
  595.             for item in __blacklistTags:
  596.                 if item in image.imageTags:
  597.                     PixivHelper.printAndLog('info', 'Skipping image_id: ' + str(image_id) + ' because contains blacklisted tags: ' + item)
  598.                     download_image_flag = False
  599.                     result = PixivConstant.PIXIVUTIL_SKIP_BLACKLIST
  600.                     break
  601.  
  602.         if __config__.useBlacklistMembers:
  603.             if str(image.originalArtist.artistId) in __blacklistMembers:
  604.                 PixivHelper.printAndLog('info', 'Skipping image_id: ' + str(image_id) + ' because contains blacklisted member id: ' + str(image.originalArtist.artistId))
  605.                 download_image_flag = False
  606.                 result = PixivConstant.PIXIVUTIL_SKIP_BLACKLIST
  607.  
  608.         if download_image_flag:
  609.             PixivHelper.safePrint("Title: " + image.imageTitle)
  610.             PixivHelper.safePrint("Tags : " + ', '.join(image.imageTags))
  611.             PixivHelper.safePrint("Date : " + str(image.worksDateDateTime))
  612.             print "Mode :", image.imageMode
  613.  
  614.             # get bookmark count
  615.             if ("%bookmark_count%" in __config__.filenameFormat or "%image_response_count%" in __config__.filenameFormat) and image.bookmark_count == -1:
  616.                 print "Parsing bookmark page",
  617.                 bookmark_url = 'https://www.pixiv.net/bookmark_detail.php?illust_id=' + str(image_id)
  618.                 parse_bookmark_page = PixivBrowserFactory.getBrowser().getPixivPage(bookmark_url)
  619.                 image.ParseBookmarkDetails(parse_bookmark_page)
  620.                 parse_bookmark_page.decompose()
  621.                 del parse_bookmark_page
  622.                 print "Bookmark Count :", str(image.bookmark_count)
  623.                 __br__.back()
  624.  
  625.             if __config__.useSuppressTags:
  626.                 for item in __suppressTags:
  627.                     if item in image.imageTags:
  628.                         image.imageTags.remove(item)
  629.  
  630.             # get manga page
  631.             if image.imageMode == 'manga' or image.imageMode == 'big':
  632.                 while True:
  633.                     try:
  634.                         big_url = 'https://www.pixiv.net/member_illust.php?mode={0}&illust_id={1}'.format(image.imageMode, image_id)
  635.                         parse_big_image = PixivBrowserFactory.getBrowser().getPixivPage(big_url, referer)
  636.                         if parse_big_image is not None:
  637.                             image.ParseImages(page=parse_big_image, _br=PixivBrowserFactory.getExistingBrowser())
  638.                             parse_big_image.decompose()
  639.                             del parse_big_image
  640.                         break
  641.                     except Exception as ex:
  642.                         __errorList.append(dict(type="Image", id=str(image_id), message=ex.message, exception=ex))
  643.                         PixivHelper.printAndLog('info', 'Image ID (' + str(image_id) + '): ' + str(traceback.format_exc()))
  644.                         try:
  645.                             if parse_big_image is not None:
  646.                                 dump_filename = 'Error Big Page for image ' + str(image_id) + '.html'
  647.                                 PixivHelper.dumpHtml(dump_filename, parse_big_image)
  648.                                 PixivHelper.printAndLog('error', 'Dumping html to: ' + dump_filename)
  649.                         except:
  650.                             PixivHelper.printAndLog('error', 'Cannot dump big page for image_id: ' + str(image_id))
  651.                         return PixivConstant.PIXIVUTIL_NOT_OK
  652.  
  653.                 if image.imageMode == 'manga':
  654.                     print "Page Count :", image.imageCount
  655.  
  656.             if user_dir == '':  # Yavos: use config-options
  657.                 target_dir = __config__.rootDirectory
  658.             else:  # Yavos: use filename from list
  659.                 target_dir = user_dir
  660.  
  661.             result = PixivConstant.PIXIVUTIL_OK
  662.             mangaFiles = dict()
  663.             page = 0
  664.             for img in image.imageUrls:
  665.                 print 'Image URL :', img
  666.                 url = os.path.basename(img)
  667.                 splitted_url = url.split('.')
  668.                 if splitted_url[0].startswith(str(image_id)):
  669.                     # Yavos: filename will be added here if given in list
  670.                     filename_format = __config__.filenameFormat
  671.                     if image.imageMode == 'manga':
  672.                         filename_format = __config__.filenameMangaFormat
  673.  
  674.                     filename = PixivHelper.makeFilename(filename_format, image, tagsSeparator=__config__.tagsSeparator, tagsLimit=__config__.tagsLimit, fileUrl=url, bookmark=bookmark, searchTags=search_tags)
  675.                     filename = PixivHelper.sanitizeFilename(filename, target_dir)
  676.  
  677.                     if image.imageMode == 'manga' and __config__.createMangaDir:
  678.                         manga_page = __re_manga_page.findall(filename)
  679.                         if len(manga_page) > 0:
  680.                             splitted_filename = filename.split(manga_page[0][0], 1)
  681.                             splitted_manga_page = manga_page[0][0].split("_p", 1)
  682.                             filename = splitted_filename[0] + splitted_manga_page[0] + os.sep + "_p" + splitted_manga_page[1] + splitted_filename[1]
  683.  
  684.                     PixivHelper.safePrint('Filename  : ' + filename)
  685.                     result = PixivConstant.PIXIVUTIL_NOT_OK
  686.                     try:
  687.                         overwrite = False
  688.                         if mode == PixivConstant.PIXIVUTIL_MODE_OVERWRITE:
  689.                             overwrite = True
  690.  
  691.                         result = download_image(img, filename, referer, overwrite, __config__.retry, __config__.backupOldFile, image_id, page)
  692.  
  693.                         mangaFiles[page] = filename
  694.                         page = page + 1
  695.  
  696.                         if result == PixivConstant.PIXIVUTIL_NOT_OK:
  697.                             PixivHelper.printAndLog('error', 'Image url not found/failed to download: ' + str(image.imageId))
  698.                         elif result == PixivConstant.PIXIVUTIL_ABORTED:
  699.                             raise KeyboardInterrupt()
  700.  
  701.                     except urllib2.URLError:
  702.                         PixivHelper.printAndLog('error', 'Giving up url: ' + str(img))
  703.                         __log__.exception('Error when download_image(): ' + str(img))
  704.                     print ''
  705.  
  706.             if __config__.writeImageInfo or __config__.writeImageJSON:
  707.                 filename_info_format = __config__.filenameInfoFormat
  708.                 info_filename = PixivHelper.makeFilename(filename_info_format, image, tagsSeparator=__config__.tagsSeparator,
  709.                                                     tagsLimit=__config__.tagsLimit, fileUrl=url, appendExtension=False, bookmark=bookmark,
  710.                                                     searchTags=search_tags)
  711.                 info_filename = PixivHelper.sanitizeFilename(info_filename, target_dir)
  712.                 # trim _pXXX
  713.                 info_filename = re.sub('_p?\d+$', '', info_filename)
  714.                 if __config__.writeImageInfo:
  715.                     image.WriteInfo(info_filename + ".txt")
  716.                 if __config__.writeImageJSON:
  717.                     image.WriteJSON(info_filename + ".json")
  718.  
  719.             if image.imageMode == 'ugoira_view':
  720.                 if __config__.writeUgoiraInfo:
  721.                     image.WriteUgoiraData(filename + ".js")
  722.                 if __config__.createUgoira and result == PixivConstant.PIXIVUTIL_OK:
  723.                     ugo_name = filename[:-4] + ".ugoira"
  724.                     PixivHelper.printAndLog('info', "Creating ugoira archive => " + ugo_name)
  725.                     image.CreateUgoira(filename)
  726.                     if __config__.deleteZipFile:
  727.                         PixivHelper.printAndLog('info', "Deleting zip file => " + filename)
  728.                         os.remove(filename)
  729.  
  730.                     if __config__.createGif:
  731.                         gif_filename = ugo_name[:-7] + ".gif"
  732.                         PixivHelper.ugoira2gif(ugo_name, gif_filename)
  733.                     if __config__.createApng:
  734.                         gif_filename = ugo_name[:-7] + ".png"
  735.                         PixivHelper.ugoira2apng(ugo_name, gif_filename)
  736.  
  737.             if __config__.writeUrlInDescription:
  738.                 PixivHelper.writeUrlInDescription(image, __config__.urlBlacklistRegex, __config__.urlDumpFilename)
  739.  
  740.         # Only save to db if all images is downloaded completely
  741.         if result == PixivConstant.PIXIVUTIL_OK or result == PixivConstant.PIXIVUTIL_SKIP_DUPLICATE or result == PixivConstant.PIXIVUTIL_SKIP_LOCAL_LARGER:
  742.             try:
  743.                 __dbManager__.insertImage(image.artist.artistId, image.imageId, image.imageMode)
  744.             except:
  745.                 pass
  746.             __dbManager__.updateImage(image.imageId, image.imageTitle, filename, image.imageMode)
  747.  
  748.             if image.imageMode == 'manga':
  749.                 for page in mangaFiles:
  750.                     __dbManager__.insertMangaImage(image_id, page, mangaFiles[page])
  751.  
  752.             # map back to PIXIVUTIL_OK (because of ugoira file check)
  753.             result = 0
  754.  
  755.         if image is not None:
  756.             del image
  757.         gc.collect()
  758.         # clearall()
  759.         print '\n'
  760.         return result
  761.     except KeyboardInterrupt:
  762.         raise
  763.     except Exception as ex:
  764.         ERROR_CODE = getattr(ex, 'errorCode', -1)
  765.         exc_type, exc_value, exc_traceback = sys.exc_info()
  766.         traceback.print_exception(exc_type, exc_value, exc_traceback)
  767.         PixivHelper.printAndLog('error', 'Error at process_image(): ' + str(sys.exc_info()))
  768.         __log__.exception('Error at process_image(): ' + str(image_id))
  769.  
  770.         if parse_medium_page is not None:
  771.             dump_filename = 'Error medium page for image ' + str(image_id) + '.html'
  772.             PixivHelper.dumpHtml(dump_filename, parse_medium_page)
  773.             PixivHelper.printAndLog('error', 'Dumping html to: ' + dump_filename)
  774.  
  775.         raise
  776.  
  777.  
  778. def process_tags(mode, tags, page=1, end_page=0, wild_card=True, title_caption=False,
  779.                start_date=None, end_date=None, use_tags_as_dir=False, member_id=None,
  780.                bookmark_count=None, oldest_first=False):
  781.  
  782.     search_page = None
  783.     try:
  784.         __config__.loadConfig(path=configfile)  # Reset the config for root directory
  785.  
  786.         search_tags = PixivHelper.decode_tags(tags)
  787.  
  788.         if use_tags_as_dir:
  789.             print "Save to each directory using query tags."
  790.             __config__.rootDirectory += os.sep + PixivHelper.sanitizeFilename(search_tags)
  791.  
  792.         tags = PixivHelper.encode_tags(tags)
  793.  
  794.         i = page
  795.         images = 1
  796.         last_image_id = -1
  797.         skipped_count = 0
  798.  
  799.         offset = 20
  800.         if __br__._isWhitecube:
  801.             offset = 50
  802.         start_offset = (page - 1) * offset
  803.         stop_offset = end_page * offset
  804.  
  805.         PixivHelper.printAndLog('info', 'Searching for: (' + search_tags + ") " + tags)
  806.         flag = True
  807.         while flag:
  808.             (t, search_page) = __br__.getSearchTagPage(tags, i,
  809.                                                   wild_card,
  810.                                                   title_caption,
  811.                                                   start_date,
  812.                                                   end_date,
  813.                                                   member_id,
  814.                                                   oldest_first,
  815.                                                   page)
  816.             if len(t.itemList) == 0:
  817.                 print 'No more images'
  818.                 flag = False
  819.             else:
  820.                 for item in t.itemList:
  821.                     last_image_id = item.imageId
  822.                     print 'Image #' + str(images)
  823.                     print 'Image Id:', str(item.imageId)
  824.                     print 'Bookmark Count:', str(item.bookmarkCount)
  825.                     if bookmark_count is not None and bookmark_count > item.bookmarkCount:
  826.                         PixivHelper.printAndLog('info', 'Skipping imageId= {0} because less than bookmark count limit ({1} > {2}).'.format(item.imageId, bookmark_count, item.bookmarkCount))
  827.                         skipped_count = skipped_count + 1
  828.                         continue
  829.                     result = 0
  830.                     while True:
  831.                         try:
  832.                             if t.availableImages > 0:
  833.                                 # PixivHelper.safePrint("Total Images: " + str(t.availableImages))
  834.                                 total_image = t.availableImages
  835.                                 if(stop_offset > 0 and stop_offset < total_image):
  836.                                     total_image = stop_offset
  837.                                 total_image = total_image - start_offset
  838.                                 # PixivHelper.safePrint("Total Images Offset: " + str(total_image))
  839.                             else:
  840.                                 total_image = ((i - 1) * 20) + len(t.itemList)
  841.                             title_prefix = "Tags:{0} Page:{1} Image {2}+{3} of {4}".format(tags, i, images, skipped_count, total_image)
  842.                             if member_id is not None:
  843.                                 title_prefix = "MemberId: {0} Tags:{1} Page:{2} Image {3}+{4} of {5}".format(member_id,
  844.                                                                                                               tags, i,
  845.                                                                                                               images,
  846.                                                                                                               skipped_count,
  847.                                                                                                               total_image)
  848.                             if not DEBUG_SKIP_PROCESS_IMAGE:
  849.                                 process_image(mode, None, item.imageId, search_tags=search_tags, title_prefix=title_prefix, bookmark_count=item.bookmarkCount, image_response_count=item.imageResponse)
  850.                                 wait()
  851.                             break
  852.                         except KeyboardInterrupt:
  853.                             result = PixivConstant.PIXIVUTIL_KEYBOARD_INTERRUPT
  854.                             break
  855.                         except httplib.BadStatusLine:
  856.                             print "Stuff happened, trying again after 2 second..."
  857.                             time.sleep(2)
  858.  
  859.                     images = images + 1
  860.  
  861.                     if result == PixivConstant.PIXIVUTIL_KEYBOARD_INTERRUPT:
  862.                         choice = raw_input("Keyboard Interrupt detected, continue to next image (Y/N)")
  863.                         if choice.upper() == 'N':
  864.                             PixivHelper.printAndLog("info", "Tags: " + tags + ", processing aborted")
  865.                             flag = False
  866.                             break
  867.                         else:
  868.                             continue
  869.  
  870.             __br__.clear_history()
  871.  
  872.             i = i + 1
  873.  
  874.             del search_page
  875.  
  876.             if end_page != 0 and end_page < i:
  877.                 PixivHelper.printAndLog('info', "End Page reached: " + str(end_page))
  878.                 flag = False
  879.             if t.isLastPage:
  880.                 PixivHelper.printAndLog('info', "Last page: " + str(i - 1))
  881.                 flag = False
  882.             if __config__.enableInfiniteLoop and i == 1001 and not oldest_first:
  883.                 if last_image_id > 0:
  884.                     # get the last date
  885.                     PixivHelper.printAndLog('info', "Hit page 1000, trying to get workdate for last image id: " + str(last_image_id))
  886.                     referer = 'https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' + str(last_image_id)
  887.                     parse_medium_page = PixivBrowserFactory.getBrowser().getPixivPage(referer)
  888.                     image = PixivImage(iid=last_image_id, page=parse_medium_page, dateFormat=__config__.dateFormat)
  889.                     _last_date = image.worksDateDateTime.strftime("%Y-%m-%d")
  890.                     # hit the last page
  891.                     PixivHelper.printAndLog('info', "Hit page 1000, looping back to page 1 with ecd: " + str(_last_date))
  892.                     i = 1
  893.                     end_date = _last_date
  894.                     flag = True
  895.                     last_image_id = -1
  896.                 else:
  897.                     PixivHelper.printAndLog('info', "No more image in the list.")
  898.                     flag = False
  899.  
  900.         print 'done'
  901.     except KeyboardInterrupt:
  902.         raise
  903.     except:
  904.         print 'Error at process_tags():', sys.exc_info()
  905.         __log__.exception('Error at process_tags(): ' + str(sys.exc_info()))
  906.         try:
  907.             if search_page is not None:
  908.                 dump_filename = 'Error page for search tags ' + tags + '.html'
  909.                 PixivHelper.dumpHtml(dump_filename, search_page)
  910.                 PixivHelper.printAndLog('error', "Dumping html to: " + dump_filename)
  911.         except:
  912.             PixivHelper.printAndLog('error', 'Cannot dump page for search tags:' + search_tags)
  913.         raise
  914.  
  915.  
  916. def process_tags_list(mode, filename, page=1, end_page=0, wild_card=True,
  917.                       oldest_first=False, bookmark_count=None,
  918.                       start_date=None, end_date=None):
  919.     global ERROR_CODE
  920.  
  921.     try:
  922.         print "Reading:", filename
  923.         l = PixivTags.parseTagsList(filename)
  924.         for tag in l:
  925.             process_tags(mode, tag, page=page, end_page=end_page, wild_card=wild_card,
  926.                          use_tags_as_dir=__config__.useTagsAsDir, oldest_first=oldest_first,
  927.                          bookmark_count=bookmark_count, start_date=start_date, end_date=end_date)
  928.     except KeyboardInterrupt:
  929.         raise
  930.     except Exception as ex:
  931.         ERROR_CODE = getattr(ex, 'errorCode', -1)
  932.         print 'Error at process_tags_list():', sys.exc_info()
  933.         __log__.exception('Error at process_tags_list(): ' + str(sys.exc_info()))
  934.         raise
  935.  
  936.  
  937. def process_image_bookmark(mode, hide='n', start_page=1, end_page=0, tag=''):
  938.     global np_is_valid
  939.     global np
  940.     try:
  941.         print "Importing image bookmarks..."
  942.         totalList = list()
  943.         image_count = 1
  944.  
  945.         if hide == 'n':
  946.             totalList.extend(get_image_bookmark(False, start_page, end_page, tag))
  947.         elif hide == 'y':
  948.             # public and private image bookmarks
  949.             totalList.extend(get_image_bookmark(False, start_page, end_page, tag))
  950.             totalList.extend(get_image_bookmark(True, start_page, end_page, tag))
  951.         else:
  952.             totalList.extend(get_image_bookmark(True, start_page, end_page, tag))
  953.  
  954.         PixivHelper.printAndLog('info', "Found " + str(len(totalList)) + " image(s).")
  955.         for item in totalList:
  956.             print "Image #" + str(image_count)
  957.             process_image(mode, artist=None, image_id=item)
  958.             image_count = image_count + 1
  959.             wait()
  960.  
  961.         print "Done.\n"
  962.     except KeyboardInterrupt:
  963.         raise
  964.     except:
  965.         print 'Error at process_image_bookmark():', sys.exc_info()
  966.         __log__.exception('Error at process_image_bookmark(): ' + str(sys.exc_info()))
  967.         raise
  968.  
  969.  
  970. def get_image_bookmark(hide, start_page=1, end_page=0, tag=''):
  971.     """Get user's image bookmark"""
  972.     total_list = list()
  973.     i = start_page
  974.     while True:
  975.         if end_page != 0 and i > end_page:
  976.             print "Page Limit reached: " + str(end_page)
  977.             break
  978.  
  979.         url = 'https://www.pixiv.net/bookmark.php?p=' + str(i)
  980.         if hide:
  981.             url = url + "&rest=hide"
  982.         if tag is not None and len(tag) > 0:
  983.             url = url + '&tag=' + PixivHelper.encode_tags(tag)
  984.  
  985.         PixivHelper.printAndLog('info', "Importing user's bookmarked image from page " + str(i))
  986.         PixivHelper.printAndLog('info', "Source URL: " + url)
  987.  
  988.         page = __br__.open(url)
  989.         parse_page = BeautifulSoup(page.read())
  990.         l = PixivBookmark.parseImageBookmark(parse_page)
  991.         total_list.extend(l)
  992.         if len(l) == 0:
  993.             print "No more images."
  994.             break
  995.         else:
  996.             print " found " + str(len(l)) + " images."
  997.  
  998.         i = i + 1
  999.  
  1000.         parse_page.decompose()
  1001.         del parse_page
  1002.  
  1003.     return total_list
  1004.  
  1005.  
  1006. def get_bookmarks(hide, start_page=1, end_page=0, member_id=None):
  1007.     """Get User's bookmarked artists """
  1008.     total_list = list()
  1009.     i = start_page
  1010.     while True:
  1011.         if end_page != 0 and i > end_page:
  1012.             print 'Limit reached'
  1013.             break
  1014.         PixivHelper.printAndLog('info', 'Exporting page ' + str(i))
  1015.         url = 'https://www.pixiv.net/bookmark.php?type=user&p=' + str(i)
  1016.         if hide:
  1017.             url = url + "&rest=hide"
  1018.         if member_id:
  1019.             url = url + "&id=" + member_id
  1020.         PixivHelper.printAndLog('info', "Source URL: " + url)
  1021.  
  1022.         page = __br__.open(url)
  1023.         parse_page = BeautifulSoup(page.read())
  1024.         l = PixivBookmark.parseBookmark(parse_page)
  1025.         if len(l) == 0:
  1026.             print 'No more data'
  1027.             break
  1028.         total_list.extend(l)
  1029.         i = i + 1
  1030.         print str(len(l)), 'items'
  1031.     return total_list
  1032.  
  1033.  
  1034. def process_bookmark(mode, hide='n', start_page=1, end_page=0):
  1035.     try:
  1036.         total_list = list()
  1037.         if hide != 'o':
  1038.             print "Importing Bookmarks..."
  1039.             total_list.extend(get_bookmarks(False, start_page, end_page))
  1040.         if hide != 'n':
  1041.             print "Importing Private Bookmarks..."
  1042.             total_list.extend(get_bookmarks(True, start_page, end_page))
  1043.         print "Result: ", str(len(total_list)), "items."
  1044.         for item in total_list:
  1045.             process_member(mode, item.memberId, item.path)
  1046.     except KeyboardInterrupt:
  1047.         raise
  1048.     except:
  1049.         print 'Error at process_bookmark():', sys.exc_info()
  1050.         __log__.exception('Error at process_bookmark(): ' + str(sys.exc_info()))
  1051.         raise
  1052.  
  1053.  
  1054. def export_bookmark(filename, hide='n', start_page=1, end_page=0, member_id=None):
  1055.     try:
  1056.         total_list = list()
  1057.         if hide != 'o':
  1058.             print "Importing Bookmarks..."
  1059.             total_list.extend(get_bookmarks(False, start_page, end_page, member_id))
  1060.         if hide != 'n':
  1061.             print "Importing Private Bookmarks..."
  1062.             total_list.extend(get_bookmarks(True, start_page, end_page, member_id))
  1063.         print "Result: ", str(len(total_list)), "items."
  1064.         PixivBookmark.exportList(total_list, filename)
  1065.     except KeyboardInterrupt:
  1066.         raise
  1067.     except:
  1068.         print 'Error at export_bookmark():', sys.exc_info()
  1069.         __log__.exception('Error at export_bookmark(): ' + str(sys.exc_info()))
  1070.         raise
  1071.  
  1072.  
  1073. def process_new_illust_from_bookmark(mode, page_num=1, end_page_num=0):
  1074.     try:
  1075.         print "Processing New Illust from bookmark"
  1076.         i = page_num
  1077.         image_count = 1
  1078.         flag = True
  1079.         while flag:
  1080.             print "Page #" + str(i)
  1081.             url = 'https://www.pixiv.net/bookmark_new_illust.php?p=' + str(i)
  1082.             if __config__.r18mode:
  1083.                 url = 'https://www.pixiv.net/bookmark_new_illust_r18.php?p=' + str(i)
  1084.  
  1085.             PixivHelper.printAndLog('info', "Source URL: " + url)
  1086.             page = __br__.open(url)
  1087.             parsed_page = BeautifulSoup(page.read())
  1088.             pb = PixivNewIllustBookmark(parsed_page)
  1089.             if not pb.haveImages:
  1090.                 print "No images!"
  1091.                 break
  1092.  
  1093.             for image_id in pb.imageList:
  1094.                 print "Image #" + str(image_count)
  1095.                 result = process_image(mode, artist=None, image_id=int(image_id))
  1096.                 image_count = image_count + 1
  1097.  
  1098.                 if result == PixivConstant.PIXIVUTIL_SKIP_OLDER:
  1099.                     flag = False
  1100.                     break
  1101.  
  1102.                 wait()
  1103.             i = i + 1
  1104.  
  1105.             parsed_page.decompose()
  1106.             del parsed_page
  1107.  
  1108.             # Non premium is only limited to 100 page
  1109.             # Premium user might be limited to 5000, refer to issue #112
  1110.             if (end_page_num != 0 and i > end_page_num) or i > 5000 or pb.isLastPage:
  1111.                 print "Limit or last page reached."
  1112.                 flag = False
  1113.  
  1114.         print "Done."
  1115.     except KeyboardInterrupt:
  1116.         raise
  1117.     except:
  1118.         print 'Error at process_new_illust_from_bookmark():', sys.exc_info()
  1119.         __log__.exception('Error at process_new_illust_from_bookmark(): ' + str(sys.exc_info()))
  1120.         raise
  1121.  
  1122.  
  1123. def process_from_group(mode, group_id, limit=0, process_external=True):
  1124.     try:
  1125.         print "Download by Group Id"
  1126.         if limit != 0:
  1127.             print "Limit: {0}".format(limit)
  1128.         if process_external:
  1129.             print "Include External Image: {0}".format(process_external)
  1130.  
  1131.         max_id = 0
  1132.         image_count = 0
  1133.         flag = True
  1134.         while flag:
  1135.             url = "https://www.pixiv.net/group/images.php?format=json&max_id={0}&id={1}".format(max_id, group_id)
  1136.             PixivHelper.printAndLog('info', "Getting images from: {0}".format(url))
  1137.             json_response = __br__.open(url)
  1138.             group_data = PixivGroup(json_response)
  1139.             max_id = group_data.maxId
  1140.             if group_data.imageList is not None and len(group_data.imageList) > 0:
  1141.                 for image in group_data.imageList:
  1142.                     if image_count > limit and limit != 0:
  1143.                         flag = False
  1144.                         break
  1145.                     print "Image #{0}".format(image_count)
  1146.                     print "ImageId: {0}".format(image)
  1147.                     process_image(mode, image_id=image)
  1148.                     image_count = image_count + 1
  1149.                     wait()
  1150.  
  1151.             if process_external and group_data.externalImageList is not None and len(group_data.externalImageList) > 0:
  1152.                 for image_data in group_data.externalImageList:
  1153.                     if image_count > limit and limit != 0:
  1154.                         flag = False
  1155.                         break
  1156.                     print "Image #{0}".format(image_count)
  1157.                     print "Member Id   : {0}".format(image_data.artist.artistId)
  1158.                     PixivHelper.safePrint("Member Name  : " + image_data.artist.artistName)
  1159.                     print "Member Token : {0}".format(image_data.artist.artistToken)
  1160.                     print "Image Url   : {0}".format(image_data.imageUrls[0])
  1161.  
  1162.                     filename = PixivHelper.makeFilename(__config__.filenameFormat, imageInfo=image_data,
  1163.                                                         tagsSeparator=__config__.tagsSeparator,
  1164.                                                         tagsLimit=__config__.tagsLimit, fileUrl=image_data.imageUrls[0])
  1165.                     filename = PixivHelper.sanitizeFilename(filename, __config__.rootDirectory)
  1166.                     PixivHelper.safePrint("Filename  : " + filename)
  1167.                     download_image(image_data.imageUrls[0], filename, url, __config__.overwrite, __config__.retry,
  1168.                                    __config__.backupOldFile)
  1169.                     image_count = image_count + 1
  1170.  
  1171.             if (group_data.imageList is None or len(group_data.imageList) == 0) and \
  1172.                (group_data.externalImageList is None or len(group_data.externalImageList) == 0):
  1173.                 flag = False
  1174.             print ""
  1175.  
  1176.     except:
  1177.         print 'Error at process_from_group():', sys.exc_info()
  1178.         __log__.exception('Error at process_from_group(): ' + str(sys.exc_info()))
  1179.         raise
  1180.  
  1181.  
  1182. def header():
  1183.     print 'PixivDownloader2 version', PixivConstant.PIXIVUTIL_VERSION
  1184.     print PixivConstant.PIXIVUTIL_LINK
  1185.     print 'Donate at', PixivConstant.PIXIVUTIL_DONATE
  1186.  
  1187.  
  1188. def get_start_and_end_number(start_only=False):
  1189.     global np_is_valid
  1190.     global np
  1191.  
  1192.     page_num = raw_input('Start Page (default=1): ') or 1
  1193.     try:
  1194.         page_num = int(page_num)
  1195.     except:
  1196.         print "Invalid page number:", page_num
  1197.         raise
  1198.  
  1199.     end_page_num = 0
  1200.     if np_is_valid:
  1201.         end_page_num = np
  1202.     else:
  1203.         end_page_num = __config__.numberOfPage
  1204.  
  1205.     if not start_only:
  1206.         end_page_num = raw_input('End Page (default=' + str(end_page_num) + ', 0 for no limit): ') or end_page_num
  1207.         try:
  1208.             end_page_num = int(end_page_num)
  1209.             if page_num > end_page_num and end_page_num != 0:
  1210.                 print "page_num is bigger than end_page_num, assuming as page count."
  1211.                 end_page_num = page_num + end_page_num
  1212.         except:
  1213.             print "Invalid end page number:", end_page_num
  1214.             raise
  1215.  
  1216.     return page_num, end_page_num
  1217.  
  1218.  
  1219. def get_start_and_end_number_from_args(args, offset=0, start_only=False):
  1220.     global np_is_valid
  1221.     global np
  1222.     page_num = 1
  1223.     if len(args) > 0 + offset:
  1224.         try:
  1225.             page_num = int(args[0 + offset])
  1226.             print "Start Page =", str(page_num)
  1227.         except:
  1228.             print "Invalid page number:", args[0 + offset]
  1229.             raise
  1230.  
  1231.     end_page_num = 0
  1232.     if np_is_valid:
  1233.         end_page_num = np
  1234.     else:
  1235.         end_page_num = __config__.numberOfPage
  1236.  
  1237.     if not start_only:
  1238.         if len(args) > 1 + offset:
  1239.             try:
  1240.                 end_page_num = int(args[1 + offset])
  1241.                 if page_num > end_page_num and end_page_num != 0:
  1242.                     print "page_num is bigger than end_page_num, assuming as page count."
  1243.                     end_page_num = page_num + end_page_num
  1244.                 print "End Page =", str(end_page_num)
  1245.             except:
  1246.                 print "Invalid end page number:", args[1 + offset]
  1247.                 raise
  1248.     return page_num, end_page_num
  1249.  
  1250.  
  1251. def check_date_time(input_date):
  1252.     split = input_date.split("-")
  1253.     return datetime.date(int(split[0]), int(split[1]), int(split[2])).isoformat()
  1254.  
  1255.  
  1256. def get_start_and_end_date():
  1257.     start_date = None
  1258.     end_date = None
  1259.     while True:
  1260.         try:
  1261.             start_date = raw_input('Start Date [YYYY-MM-DD]: ') or None
  1262.             if start_date is not None:
  1263.                 start_date = check_date_time(start_date)
  1264.             break
  1265.         except Exception as e:
  1266.             print str(e)
  1267.  
  1268.     while True:
  1269.         try:
  1270.             end_date = raw_input('End Date [YYYY-MM-DD]: ') or None
  1271.             if end_date is not None:
  1272.                 end_date = check_date_time(end_date)
  1273.             break
  1274.         except Exception as e:
  1275.             print str(e)
  1276.  
  1277.     return start_date, end_date
  1278.  
  1279.  
  1280. def menu():
  1281.     set_console_title()
  1282.     header()
  1283.     print '1. Download by member_id'
  1284.     print '2. Download by image_id'
  1285.     print '3. Download by tags'
  1286.     print '4. Download from list'
  1287.     print '5. Download from bookmarked artists (bookmark.php?type=user)'
  1288.     print '6. Download from bookmarked images (bookmark.php)'
  1289.     print '7. Download from tags list'
  1290.     print '8. Download new illust from bookmarked members (bookmark_new_illust.php)'
  1291.     print '9. Download by Title/Caption'
  1292.     print '10. Download by Tag and Member Id'
  1293.     print '11. Download Member Bookmark'
  1294.     print '12. Download by Group Id'
  1295.     print '------------------------'
  1296.     print 'd. Manage database'
  1297.     print 'e. Export online bookmark'
  1298.     print 'm. Export online user bookmark'
  1299.     print 'r. Reload config.ini'
  1300.     print 'p. Print config.ini'
  1301.     print 'x. Exit'
  1302.  
  1303.     return raw_input('Input: ').strip()
  1304.  
  1305.  
  1306. def menu_download_by_member_id(mode, opisvalid, args):
  1307.     __log__.info('Member id mode.')
  1308.     page = 1
  1309.     end_page = 0
  1310.     if opisvalid and len(args) > 0:
  1311.         for member_id in args:
  1312.             try:
  1313.                 test_id = int(member_id)
  1314.                 process_member(mode, test_id)
  1315.             except:
  1316.                 PixivHelper.printAndLog('error', "Member ID: {0} is not valid".format(member_id))
  1317.                 continue
  1318.     else:
  1319.         member_ids = raw_input('Member ids: ')
  1320.         (page, end_page) = get_start_and_end_number()
  1321.  
  1322.         member_ids = PixivHelper.getIdsFromCsv(member_ids, sep=" ")
  1323.         PixivHelper.printAndLog('info', "Member IDs: {0}".format(member_ids))
  1324.         for member_id in member_ids:
  1325.             process_member(mode, member_id, page=page, end_page=end_page)
  1326.  
  1327.  
  1328. def menu_download_by_member_bookmark(mode, opisvalid, args):
  1329.     __log__.info('Member Bookmark mode.')
  1330.     page = 1
  1331.     end_page = 0
  1332.     if opisvalid and len(args) > 0:
  1333.         for member_id in args:
  1334.             try:
  1335.                 test_id = int(member_id)
  1336.                 process_member(mode, test_id)
  1337.             except:
  1338.                 PixivHelper.printAndLog('error', "Member ID: {0} is not valid".format(member_id))
  1339.                 continue
  1340.     else:
  1341.         member_id = raw_input('Member id: ')
  1342.         tags = raw_input('Filter Tags: ')
  1343.         (page, end_page) = get_start_and_end_number()
  1344.         process_member(mode, member_id.strip(), page=page, end_page=end_page, bookmark=True, tags=tags)
  1345.  
  1346.  
  1347. def menu_download_by_image_id(mode, opisvalid, args):
  1348.     __log__.info('Image id mode.')
  1349.     if opisvalid and len(args) > 0:
  1350.         for image_id in args:
  1351.             try:
  1352.                 test_id = int(image_id)
  1353.                 process_image(mode, None, test_id)
  1354.             except:
  1355.                 PixivHelper.printAndLog('error', "Image ID: {0} is not valid".format(image_id))
  1356.                 continue
  1357.     else:
  1358.         image_ids = raw_input('Image ids: ')
  1359.         image_ids = PixivHelper.getIdsFromCsv(image_ids, sep=" ")
  1360.         for image_id in image_ids:
  1361.             process_image(mode, None, int(image_id))
  1362.  
  1363.  
  1364. def menu_download_by_tags(mode, opisvalid, args):
  1365.     __log__.info('tags mode.')
  1366.     page = 1
  1367.     end_page = 0
  1368.     start_date = None
  1369.     end_date = None
  1370.     bookmark_count = None
  1371.     oldest_first = False
  1372.     wildcard = True
  1373.     if opisvalid and len(args) > 0:
  1374.         wildcard = args[0]
  1375.         if wildcard.lower() == 'y':
  1376.             wildcard = True
  1377.         else:
  1378.             wildcard = False
  1379.         (page, end_page) = get_start_and_end_number_from_args(args, 1)
  1380.         tags = " ".join(args[3:])
  1381.     else:
  1382.         tags = PixivHelper.uni_input('Tags: ')
  1383.         bookmark_count = raw_input('Bookmark Count: ') or None
  1384.         wildcard = raw_input('Use Partial Match (s_tag) [y/n]: ') or 'n'
  1385.         if wildcard.lower() == 'y':
  1386.             wildcard = True
  1387.         else:
  1388.             wildcard = False
  1389.         oldest_first = raw_input('Oldest first[y/n]: ') or 'n'
  1390.         if oldest_first.lower() == 'y':
  1391.             oldest_first = True
  1392.         else:
  1393.             oldest_first = False
  1394.  
  1395.         (page, end_page) = get_start_and_end_number()
  1396.         (start_date, end_date) = get_start_and_end_date()
  1397.     if bookmark_count is not None:
  1398.         bookmark_count = int(bookmark_count)
  1399.     process_tags(mode, tags.strip(), page, end_page, wildcard, start_date=start_date, end_date=end_date,
  1400.                 use_tags_as_dir=__config__.useTagsAsDir, bookmark_count=bookmark_count, oldest_first=oldest_first)
  1401.  
  1402.  
  1403. def menu_download_by_title_caption(mode, opisvalid, args):
  1404.     __log__.info('Title/Caption mode.')
  1405.     page = 1
  1406.     end_page = 0
  1407.     start_date = None
  1408.     end_date = None
  1409.     if opisvalid and len(args) > 0:
  1410.         (page, end_page) = get_start_and_end_number_from_args(args)
  1411.         tags = " ".join(args[2:])
  1412.     else:
  1413.         tags = PixivHelper.uni_input('Title/Caption: ')
  1414.         (page, end_page) = get_start_and_end_number()
  1415.         (start_date, end_date) = get_start_and_end_date()
  1416.  
  1417.     process_tags(mode, tags.strip(), page, end_page, wild_card=False, title_caption=True, start_date=start_date, end_date=end_date, use_tags_as_dir=__config__.useTagsAsDir)
  1418.  
  1419.  
  1420. def menu_download_by_tag_and_member_id(mode, opisvalid, args):
  1421.     __log__.info('Tag and MemberId mode.')
  1422.     member_id = 0
  1423.     tags = None
  1424.  
  1425.     if opisvalid and len(args) >= 2:
  1426.         member_id = int(args[0])
  1427.         (page, end_page) = get_start_and_end_number_from_args(args, 1)
  1428.         tags = " ".join(args[3:])
  1429.         PixivHelper.safePrint("Looking tags: " + tags + " from memberId: " + str(member_id))
  1430.     else:
  1431.         member_id = raw_input('Member Id: ')
  1432.         tags = PixivHelper.uni_input('Tag      : ')
  1433.  
  1434.     process_tags(mode, tags.strip(), member_id=int(member_id), use_tags_as_dir=__config__.useTagsAsDir)
  1435.  
  1436.  
  1437. def menu_download_from_list(mode, opisvalid, args):
  1438.     __log__.info('Batch mode.')
  1439.     global op
  1440.     global __config__
  1441.  
  1442.     list_file_name = __config__.downloadListDirectory + os.sep + 'list.txt'
  1443.     tags = None
  1444.     if opisvalid and op == '4' and len(args) > 0:
  1445.         test_file_name = __config__.downloadListDirectory + os.sep + args[0]
  1446.         if os.path.exists(test_file_name):
  1447.             list_file_name = test_file_name
  1448.         if len(args) > 1:
  1449.             tags = args[1]
  1450.     else:
  1451.         test_tags = PixivHelper.uni_input('Tag : ')
  1452.         if len(test_tags) > 0:
  1453.             tags = test_tags
  1454.  
  1455.     if tags is not None and len(tags) > 0:
  1456.         PixivHelper.safePrint(u"Processing member id from {0} for tags: {1}".format(list_file_name, tags))
  1457.     else:
  1458.         PixivHelper.safePrint("Processing member id from {0}".format(list_file_name))
  1459.  
  1460.     process_list(mode, list_file_name, tags)
  1461.  
  1462.  
  1463. def menu_download_from_online_user_bookmark(mode, opisvalid, args):
  1464.     __log__.info('User Bookmarked Artist mode.')
  1465.     start_page = 1
  1466.     end_page = 0
  1467.     hide = 'n'
  1468.     if opisvalid:
  1469.         if len(args) > 0:
  1470.             arg = args[0].lower()
  1471.             if arg == 'y' or arg == 'n' or arg == 'o':
  1472.                 hide = arg
  1473.             else:
  1474.                 print "Invalid args: ", args
  1475.                 return
  1476.             (start_page, end_page) = get_start_and_end_number_from_args(args, offset=1)
  1477.     else:
  1478.         arg = raw_input("Include Private bookmarks [y/n/o]: ") or 'n'
  1479.         arg = arg.lower()
  1480.         if arg == 'y' or arg == 'n' or arg == 'o':
  1481.             hide = arg
  1482.         else:
  1483.             print "Invalid args: ", arg
  1484.             return
  1485.         (start_page, end_page) = get_start_and_end_number()
  1486.     process_bookmark(mode, hide, start_page, end_page)
  1487.  
  1488.  
  1489. def menu_download_from_online_image_bookmark(mode, opisvalid, args):
  1490.     __log__.info("User's Image Bookmark mode.")
  1491.     start_page = 1
  1492.     end_page = 0
  1493.     hide = False
  1494.     tag = ''
  1495.  
  1496.     if opisvalid and len(args) > 0:
  1497.         arg = args[0].lower()
  1498.         if arg == 'y' or arg == 'n' or arg == 'o':
  1499.             hide = arg
  1500.         else:
  1501.             print "Invalid args: ", args
  1502.             return
  1503.         (start_page, end_page) = get_start_and_end_number_from_args(args, offset=1)
  1504.         if len(args) > 3:
  1505.             tag = args[3]
  1506.     else:
  1507.         arg = raw_input("Include Private bookmarks [y/n/o]: ") or 'n'
  1508.         arg = arg.lower()
  1509.         if arg == 'y' or arg == 'n' or arg == 'o':
  1510.             hide = arg
  1511.         else:
  1512.             print "Invalid args: ", arg
  1513.             return
  1514.         tag = raw_input("Tag (default=All Images): ") or ''
  1515.         (start_page, end_page) = get_start_and_end_number()
  1516.  
  1517.     process_image_bookmark(mode, hide, start_page, end_page, tag)
  1518.  
  1519.  
  1520. def menu_download_from_tags_list(mode, opisvalid, args):
  1521.     __log__.info('Taglist mode.')
  1522.     page = 1
  1523.     end_page = 0
  1524.     oldest_first = False
  1525.     wildcard = True
  1526.     bookmark_count = None
  1527.     start_date = None
  1528.     end_date = None
  1529.  
  1530.     if opisvalid and len(args) > 0:
  1531.         filename = args[0]
  1532.         (page, end_page) = get_start_and_end_number_from_args(args, offset=1)
  1533.     else:
  1534.         filename = raw_input("Tags list filename [tags.txt]: ") or './tags.txt'
  1535.         wildcard = raw_input('Use Wildcard[y/n]: ') or 'n'
  1536.         if wildcard.lower() == 'y':
  1537.             wildcard = True
  1538.         else:
  1539.             wildcard = False
  1540.         oldest_first = raw_input('Oldest first[y/n]: ') or 'n'
  1541.         if oldest_first.lower() == 'y':
  1542.             oldest_first = True
  1543.         else:
  1544.             oldest_first = False
  1545.         bookmark_count = raw_input('Bookmark Count: ') or None
  1546.         (page, end_page) = get_start_and_end_number()
  1547.         (start_date, end_date) = get_start_and_end_date()
  1548.     if bookmark_count is not None:
  1549.         bookmark_count = int(bookmark_count)
  1550.  
  1551.     process_tags_list(mode, filename, page, end_page, wild_card=wildcard, oldest_first=oldest_first,
  1552.                       bookmark_count=bookmark_count, start_date=start_date, end_date=end_date)
  1553.  
  1554.  
  1555. def menu_download_new_illust_from_bookmark(mode, opisvalid, args):
  1556.     __log__.info('New Illust from Bookmark mode.')
  1557.  
  1558.     if opisvalid:
  1559.         (page_num, end_page_num) = get_start_and_end_number_from_args(args, offset=0)
  1560.     else:
  1561.         (page_num, end_page_num) = get_start_and_end_number()
  1562.  
  1563.     process_new_illust_from_bookmark(mode, page_num, end_page_num)
  1564.  
  1565.  
  1566. def menu_download_by_group_id(mode, opisvalid, args):
  1567.     __log__.info('Group mode.')
  1568.     process_external = False
  1569.     limit = 0
  1570.  
  1571.     if opisvalid and len(args) > 0:
  1572.         group_id = args[0]
  1573.         limit = int(args[1])
  1574.         if args[2].lower() == 'y':
  1575.             process_external = True
  1576.     else:
  1577.         group_id = raw_input("Group Id: ")
  1578.         limit = int(raw_input("Limit: "))
  1579.         arg = raw_input("Process External Image [y/n]: ") or 'n'
  1580.         arg = arg.lower()
  1581.         if arg == 'y':
  1582.             process_external = True
  1583.  
  1584.     process_from_group(mode, group_id, limit, process_external)
  1585.  
  1586.  
  1587. def menu_export_online_bookmark(mode, opisvalid, args):
  1588.     __log__.info('Export Bookmark mode.')
  1589.     hide = False
  1590.     filename = raw_input("Filename: ")
  1591.     arg = raw_input("Include Private bookmarks [y/n/o]: ") or 'n'
  1592.     arg = arg.lower()
  1593.     if arg == 'y' or arg == 'n' or arg == 'o':
  1594.         hide = arg
  1595.     else:
  1596.         print "Invalid args: ", arg
  1597.     export_bookmark(filename, hide)
  1598.  
  1599.  
  1600. def menu_export_online_user_bookmark(mode, opisvalid, args):
  1601.     __log__.info('Export Bookmark mode.')
  1602.     member_id = ''
  1603.     filename = raw_input("Filename: ")
  1604.     arg = raw_input("Member Id: ") or ''
  1605.     arg = arg.lower()
  1606.     if arg.isdigit():
  1607.         member_id = arg
  1608.     else:
  1609.         print "Invalid args: ", arg
  1610.     export_bookmark(filename, 'n', 1, 0, member_id)
  1611.  
  1612.  
  1613. def menu_reload_config():
  1614.     __log__.info('Manual Reload Config.')
  1615.     __config__.loadConfig(path=configfile)
  1616.  
  1617.  
  1618. def menu_print_config():
  1619.     __log__.info('Manual Reload Config.')
  1620.     __config__.printConfig()
  1621.  
  1622.  
  1623. def set_console_title(title=''):
  1624.     set_title = 'PixivDownloader {0} {1}'.format(PixivConstant.PIXIVUTIL_VERSION, title)
  1625.     PixivHelper.setConsoleTitle(set_title)
  1626.  
  1627.  
  1628. def setup_option_parser():
  1629.     parser = OptionParser()
  1630.     parser.add_option('-s', '--startaction', dest='startaction',
  1631.                       help='Action you want to load your program with:            ' +
  1632.                             '1 - Download by member_id                              ' +
  1633.                             '2 - Download by image_id                              ' +
  1634.                             '3 - Download by tags                                    ' +
  1635.                             '4 - Download from list                                 ' +
  1636.                             '5 - Download from user bookmark                        ' +
  1637.                             '6 - Download from user\'s image bookmark               ' +
  1638.                             '7 - Download from tags list                           ' +
  1639.                             '8 - Download new illust from bookmark                  ' +
  1640.                             '9 - Download by Title/Caption                           ' +
  1641.                             '10 - Download by Tag and Member Id                     ' +
  1642.                             '11 - Download images from Member Bookmark               ' +
  1643.                             '12 - Download images by Group Id                        ' +
  1644.                             'e - Export online bookmark                              ' +
  1645.                             'm - Export online user bookmark                         ' +
  1646.                             'd - Manage database')
  1647.     parser.add_option('-x', '--exitwhendone', dest='exitwhendone',
  1648.                       help='Exit programm when done. (only useful when not using DB-Manager)',
  1649.                       action='store_true', default=False)
  1650.     parser.add_option('-i', '--irfanview', dest='start_iv',
  1651.                       help='start IrfanView after downloading images using downloaded_on_%date%.txt',
  1652.                       action='store_true', default=False)
  1653.     parser.add_option('-n', '--numberofpages', dest='numberofpages',
  1654.                       help='temporarily overwrites numberOfPage set in config.ini')
  1655.     parser.add_option('-c', '--config', dest='configlocation',
  1656.                       help='load the config file from a custom location',
  1657.                       default=None)
  1658.     return parser
  1659.  
  1660.  
  1661. # Main thread #
  1662. def main_loop(ewd, mode, op_is_valid, selection, np_is_valid, args):
  1663.     global __errorList
  1664.     global ERROR_CODE
  1665.  
  1666.     while True:
  1667.         try:
  1668.             if len(__errorList) > 0:
  1669.                 print "Unknown errors from previous operation"
  1670.                 for err in __errorList:
  1671.                     message = err["type"] + ": " + str(err["id"]) + " ==> " + err["message"]
  1672.                     PixivHelper.printAndLog('error', message)
  1673.                 __errorList = list()
  1674.                 ERROR_CODE = 1
  1675.  
  1676.             if op_is_valid:  # Yavos (next 3 lines): if commandline then use it
  1677.                 selection = op
  1678.             else:
  1679.                 selection = menu()
  1680.  
  1681.             if selection == '1':
  1682.                 menu_download_by_member_id(mode, op_is_valid, args)
  1683.             elif selection == '2':
  1684.                 menu_download_by_image_id(mode, op_is_valid, args)
  1685.             elif selection == '3':
  1686.                 menu_download_by_tags(mode, op_is_valid, args)
  1687.             elif selection == '4':
  1688.                 menu_download_from_list(mode, op_is_valid, args)
  1689.             elif selection == '5':
  1690.                 menu_download_from_online_user_bookmark(mode, op_is_valid, args)
  1691.             elif selection == '6':
  1692.                 menu_download_from_online_image_bookmark(mode, op_is_valid, args)
  1693.             elif selection == '7':
  1694.                 menu_download_from_tags_list(mode, op_is_valid, args)
  1695.             elif selection == '8':
  1696.                 menu_download_new_illust_from_bookmark(mode, op_is_valid, args)
  1697.             elif selection == '9':
  1698.                 menu_download_by_title_caption(mode, op_is_valid, args)
  1699.             elif selection == '10':
  1700.                 menu_download_by_tag_and_member_id(mode, op_is_valid, args)
  1701.             elif selection == '11':
  1702.                 menu_download_by_member_bookmark(mode, op_is_valid, args)
  1703.             elif selection == '12':
  1704.                 menu_download_by_group_id(mode, op_is_valid, args)
  1705.             elif selection == 'e':
  1706.                 menu_export_online_bookmark(mode, op_is_valid, args)
  1707.             elif selection == 'm':
  1708.                 menu_export_online_user_bookmark(mode, op_is_valid, args)
  1709.             elif selection == 'd':
  1710.                 __dbManager__.main()
  1711.             elif selection == 'r':
  1712.                 menu_reload_config()
  1713.             elif selection == 'p':
  1714.                 menu_print_config()
  1715.             elif selection == '-all':
  1716.                 if not np_is_valid:
  1717.                     np_is_valid = True
  1718.                     np = 0
  1719.                     print 'download all mode activated'
  1720.                 else:
  1721.                     np_is_valid = False
  1722.                     print 'download mode reset to', __config__.numberOfPage, 'pages'
  1723.             elif selection == 'x':
  1724.                 break
  1725.  
  1726.             if ewd:  # Yavos: added lines for "exit when done"
  1727.                 break
  1728.             op_is_valid = False  # Yavos: needed to prevent endless loop
  1729.         except KeyboardInterrupt:
  1730.             PixivHelper.printAndLog("info", "Keyboard Interrupt pressed, selection: {0}".format(selection))
  1731.             PixivHelper.clearScreen()
  1732.             print "Restarting..."
  1733.             selection = menu()
  1734.     return np_is_valid, op_is_valid, selection
  1735.  
  1736.  
  1737. def doLogin(password, username):
  1738.     result = False
  1739.     try:
  1740.         if len(__config__.cookie) > 0:
  1741.             result = PixivBrowserFactory.getBrowser(config=__config__).loginUsingCookie()
  1742.  
  1743.         if not result:
  1744.             result = PixivBrowserFactory.getBrowser(config=__config__).login(username, password)
  1745.     except:
  1746.         PixivHelper.printAndLog('error', 'Error at doLogin(): {0}'.format(str(sys.exc_info())))
  1747.         raise PixivException("Cannot Login!", PixivException.CANNOT_LOGIN)
  1748.     return result
  1749.  
  1750.  
  1751. def wait():
  1752.     # Issue#276: add random delay for each post.
  1753.     if __config__.downloadDelay > 0:
  1754.         delay = random.random() * __config__.downloadDelay
  1755.         print("Wait for {0:.3}s".format(delay))
  1756.         time.sleep(delay)
  1757.  
  1758.  
  1759. def main():
  1760.     set_console_title()
  1761.     header()
  1762.  
  1763.     # Option Parser
  1764.     global np_is_valid  # used in process image bookmark
  1765.     global np  # used in various places for number of page overwriting
  1766.     global start_iv  # used in download_image
  1767.     global op
  1768.     global __br__
  1769.     global configfile
  1770.     global ERROR_CODE
  1771.     global __dbManager__
  1772.  
  1773.     parser = setup_option_parser()
  1774.     (options, args) = parser.parse_args()
  1775.  
  1776.     op = options.startaction
  1777.     if op in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', 'd', 'e'):
  1778.         op_is_valid = True
  1779.     elif op is None:
  1780.         op_is_valid = False
  1781.     else:
  1782.         op_is_valid = False
  1783.         parser.error('%s is not valid operation' % op)
  1784.         # Yavos: use print option instead when program should be running even with this error
  1785.  
  1786.     ewd = options.exitwhendone
  1787.     configfile = options.configlocation
  1788.  
  1789.     try:
  1790.         if options.numberofpages is not None:
  1791.             np = int(options.numberofpages)
  1792.             np_is_valid = True
  1793.         else:
  1794.             np_is_valid = False
  1795.     except:
  1796.         np_is_valid = False
  1797.         parser.error('Value %s used for numberOfPage is not an integer.' % options.numberofpages)
  1798.         # Yavos: use print option instead when program should be running even with this error
  1799.         ### end new lines by Yavos ###
  1800.  
  1801.     __log__.info('###############################################################')
  1802.     __log__.info('Starting...')
  1803.     try:
  1804.         __config__.loadConfig(path=configfile)
  1805.         PixivHelper.setConfig(__config__)
  1806.     except:
  1807.         print 'Failed to read configuration.'
  1808.         __log__.exception('Failed to read configuration.')
  1809.  
  1810.     PixivHelper.setLogLevel(__config__.logLevel)
  1811.     if __br__ is None:
  1812.         __br__ = PixivBrowserFactory.getBrowser(config=__config__)
  1813.  
  1814.     selection = None
  1815.     global dfilename
  1816.  
  1817.     # Yavos: adding File for downloadlist
  1818.     now = datetime.date.today()
  1819.     dfilename = __config__.downloadListDirectory + os.sep + 'Downloaded_on_' + now.strftime('%Y-%m-%d') + '.txt'
  1820.     if not re.match(r'[a-zA-Z]:', dfilename):
  1821.         dfilename = PixivHelper.toUnicode(sys.path[0], encoding=sys.stdin.encoding) + os.sep + dfilename
  1822.         # dfilename = sys.path[0].rsplit('\\',1)[0] + '\\' + dfilename #Yavos: only useful for myself
  1823.     dfilename = dfilename.replace('\\\\', '\\')
  1824.     dfilename = dfilename.replace('\\', os.sep)
  1825.     dfilename = dfilename.replace(os.sep + 'library.zip' + os.sep + '.', '')
  1826.  
  1827.     directory = os.path.dirname(dfilename)
  1828.     if not os.path.exists(directory):
  1829.         os.makedirs(directory)
  1830.         __log__.info('Creating directory: ' + directory)
  1831.  
  1832.     # Yavos: adding IrfanView-Handling
  1833.     start_irfan_slide = False
  1834.     start_irfan_view = False
  1835.     if __config__.startIrfanSlide or __config__.startIrfanView:
  1836.         start_iv = True
  1837.         start_irfan_slide = __config__.startIrfanSlide
  1838.         start_irfan_view = __config__.startIrfanView
  1839.     elif options.start_iv is not None:
  1840.         start_iv = options.start_iv
  1841.         start_irfan_view = True
  1842.         start_irfan_slide = False
  1843.  
  1844.     try:
  1845.         __dbManager__ = PixivDBManager.PixivDBManager(target=__config__.dbPath, config=__config__)
  1846.         __dbManager__.createDatabase()
  1847.  
  1848.         if __config__.useList:
  1849.             list_txt = PixivListItem.parseList(__config__.downloadListDirectory + os.sep + 'list.txt', __config__.rootDirectory)
  1850.             __dbManager__.importList(list_txt)
  1851.             print "Updated " + str(len(list_txt)) + " items."
  1852.  
  1853.         if __config__.overwrite:
  1854.             msg = 'Overwrite enabled.'
  1855.             print msg
  1856.             __log__.info(msg)
  1857.  
  1858.         if __config__.dayLastUpdated != 0 and __config__.processFromDb:
  1859.             PixivHelper.printAndLog('info',
  1860.                                     'Only process member where day last updated >= ' + str(__config__.dayLastUpdated))
  1861.  
  1862.         if __config__.dateDiff > 0:
  1863.             PixivHelper.printAndLog('info', 'Only process image where day last updated >= ' + str(__config__.dateDiff))
  1864.  
  1865.         if __config__.useBlacklistTags:
  1866.             global __blacklistTags
  1867.             __blacklistTags = PixivTags.parseTagsList("blacklist_tags.txt")
  1868.             PixivHelper.printAndLog('info', 'Using Blacklist Tags: ' + str(len(__blacklistTags)) + " items.")
  1869.  
  1870.         if __config__.useBlacklistMembers:
  1871.             global __blacklistMembers
  1872.             __blacklistMembers = PixivTags.parseTagsList("blacklist_members.txt")
  1873.             PixivHelper.printAndLog('info', 'Using Blacklist Members: ' + str(len(__blacklistMembers)) + " members.")
  1874.  
  1875.         if __config__.useSuppressTags:
  1876.             global __suppressTags
  1877.             __suppressTags = PixivTags.parseTagsList("suppress_tags.txt")
  1878.             PixivHelper.printAndLog('info', 'Using Suppress Tags: ' + str(len(__suppressTags)) + " items.")
  1879.  
  1880.         username = __config__.username
  1881.         if username == '':
  1882.             username = raw_input('Username ? ')
  1883.         else:
  1884.             msg = 'Using Username: ' + username
  1885.             print msg
  1886.             __log__.info(msg)
  1887.  
  1888.         password = __config__.password
  1889.         if password == '':
  1890.             if os.name == 'nt':
  1891.                 win_unicode_console.disable()
  1892.             password = getpass.getpass('Password ? ')
  1893.             if os.name == 'nt':
  1894.                 win_unicode_console.enable()
  1895.  
  1896.         if np_is_valid and np != 0:  # Yavos: overwrite config-data
  1897.             msg = 'Limit up to: ' + str(np) + ' page(s). (set via commandline)'
  1898.             print msg
  1899.             __log__.info(msg)
  1900.         elif __config__.numberOfPage != 0:
  1901.             msg = 'Limit up to: ' + str(__config__.numberOfPage) + ' page(s).'
  1902.             print msg
  1903.             __log__.info(msg)
  1904.  
  1905.         result = doLogin(password, username)
  1906.  
  1907.         if result:
  1908.             if __config__.overwrite:
  1909.                 mode = PixivConstant.PIXIVUTIL_MODE_OVERWRITE
  1910.             else:
  1911.                 mode = PixivConstant.PIXIVUTIL_MODE_UPDATE_ONLY
  1912.  
  1913.             np_is_valid, op_is_valid, selection = main_loop(ewd, mode, op_is_valid, selection, np_is_valid, args)
  1914.  
  1915.             if start_iv:  # Yavos: adding start_irfan_view-handling
  1916.                 PixivHelper.startIrfanView(dfilename, __config__.IrfanViewPath, start_irfan_slide, start_irfan_view)
  1917.         else:
  1918.             ERROR_CODE = PixivException.NOT_LOGGED_IN
  1919.     except PixivException as pex:
  1920.         PixivHelper.printAndLog('error', pex.message)
  1921.         ERROR_CODE = pex.errorCode
  1922.     except Exception as ex:
  1923.         exc_type, exc_value, exc_traceback = sys.exc_info()
  1924.         traceback.print_exception(exc_type, exc_value, exc_traceback)
  1925.         __log__.exception('Unknown Error: ' + str(exc_value))
  1926.         ERROR_CODE = getattr(ex, 'errorCode', -1)
  1927.     finally:
  1928.         __dbManager__.close()
  1929.         if not ewd:  # Yavos: prevent input on exitwhendone
  1930.             if selection is None or selection != 'x':
  1931.                 raw_input('press enter to exit.')
  1932.         __log__.setLevel("INFO")
  1933.         __log__.info('EXIT: ' + str(ERROR_CODE))
  1934.         __log__.info('###############################################################')
  1935.         sys.exit(ERROR_CODE)
  1936.  
  1937.  
  1938. if __name__ == '__main__':
  1939.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement