auth.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import codecs
  2. import datetime
  3. import json
  4. import os.path
  5. import sys
  6. try:
  7. import logger
  8. import helpers
  9. import pil
  10. except ImportError:
  11. from . import logger
  12. from . import helpers
  13. from . import pil
  14. try:
  15. from instagram_private_api import (
  16. Client, ClientError, ClientLoginError,
  17. ClientCookieExpiredError, ClientLoginRequiredError)
  18. except ImportError:
  19. sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
  20. from instagram_private_api import (
  21. Client, ClientError, ClientLoginError,
  22. ClientCookieExpiredError, ClientLoginRequiredError)
  23. def to_json(python_object):
  24. if isinstance(python_object, bytes):
  25. return {'__class__': 'bytes',
  26. '__value__': codecs.encode(python_object, 'base64').decode()}
  27. raise TypeError(repr(python_object) + ' is not JSON serializable')
  28. def from_json(json_object):
  29. if '__class__' in json_object and json_object.get('__class__') == 'bytes':
  30. return codecs.decode(json_object.get('__value__').encode(), 'base64')
  31. return json_object
  32. def onlogin_callback(api, cookie_file):
  33. cache_settings = api.settings
  34. with open(cookie_file, 'w') as outfile:
  35. json.dump(cache_settings, outfile, default=to_json)
  36. logger.info('New cookie file was made: {0!s}'.format(cookie_file))
  37. logger.separator()
  38. def authenticate(username, password, force_use_login_args=False):
  39. ig_api = None
  40. try:
  41. if force_use_login_args:
  42. logger.binfo("Overriding configuration file login with -u and -p arguments.")
  43. logger.separator()
  44. cookie_file = "{}.json".format(username)
  45. if not os.path.isfile(cookie_file):
  46. # settings file does not exist
  47. logger.warn('Unable to find cookie file: {0!s}'.format(cookie_file))
  48. logger.info('Creating a new one.')
  49. # login new
  50. ig_api = Client(
  51. username, password,
  52. on_login=lambda x: onlogin_callback(x, cookie_file), proxy=pil.proxy)
  53. else:
  54. with open(cookie_file) as file_data:
  55. cached_settings = json.load(file_data, object_hook=from_json)
  56. # logger.info('Using settings file: {0!s}'.format(cookie_file))
  57. device_id = cached_settings.get('device_id')
  58. # reuse auth cached_settings
  59. try:
  60. ig_api = Client(
  61. username, password,
  62. settings=cached_settings, proxy=pil.proxy)
  63. except ClientCookieExpiredError as e:
  64. logger.warn('The current cookie file has expired, creating a new one.')
  65. ig_api = Client(
  66. username, password,
  67. device_id=device_id,
  68. on_login=lambda x: onlogin_callback(x, cookie_file), proxy=pil.proxy)
  69. except (ClientLoginError, ClientError) as e:
  70. logger.separator()
  71. if pil.verbose:
  72. logger.plain(json.dumps(e.error_response))
  73. logger.error('Could not login: {:s}'.format(
  74. json.loads(e.error_response).get("error_title", e.error_response)))
  75. logger.error('{:s}'.format(json.loads(e.error_response).get("message", e.error_response)))
  76. # logger.error('{:s}'.format(e.error_response))
  77. logger.separator()
  78. except Exception as e:
  79. if pil.verbose:
  80. logger.plain(json.dumps(e.error_response))
  81. if str(e).startswith("unsupported pickle protocol"):
  82. logger.warn("This cookie file is not compatible with Python {}.".format(sys.version.split(' ')[0][0]))
  83. logger.warn("Please delete your cookie file '{}.json' and try again.".format(username))
  84. else:
  85. logger.separator()
  86. logger.error('Unexpected exception: {:s}'.format(e))
  87. logger.separator()
  88. except KeyboardInterrupt:
  89. logger.separator()
  90. logger.warn("The user authentication has been aborted.")
  91. logger.separator()
  92. if ig_api:
  93. logger.info('Successfully logged into account: {:s}'.format(str(ig_api.authenticated_user_name)))
  94. if pil.show_cookie_expiry and not force_use_login_args:
  95. try:
  96. cookie_expiry = ig_api.cookie_jar.auth_expires
  97. logger.info('Cookie file expiry date: {:s}'.format(
  98. datetime.datetime.fromtimestamp(cookie_expiry).strftime('%Y-%m-%d at %I:%M:%S %p')))
  99. except AttributeError as e:
  100. logger.warn('An error occurred while getting the cookie file expiry date: {:s}'.format(str(e)))
  101. logger.separator()
  102. return ig_api
  103. else:
  104. return None