Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

179 rader
6.7 KiB

  1. # Standard library packages
  2. import logging
  3. import datetime
  4. import os
  5. import pickle
  6. from urllib.parse import urlparse
  7. import requests
  8. from jps2sm.utils import GetConfig
  9. logger = logging.getLogger('main.' + __name__)
  10. def jpopsuki(url, test_login=False):
  11. """
  12. Get content from JPS
  13. :param url:
  14. :param test_login: Disable test login
  15. :return: data
  16. """
  17. config = GetConfig()
  18. jps_login_url = "https://jpopsuki.eu/login.php"
  19. jps_test_url = "https://jpopsuki.eu"
  20. jps_success = '<div id="extra1"><span></span></div>'
  21. login_data = {'username': config.jps_user, 'password': config.jps_pass}
  22. jps_session = MyLoginSession(jps_login_url, login_data, jps_test_url, jps_success, test_login)
  23. return jps_session.retrieveContent(url)
  24. def sugoimusic(url, method="get", post_data=None, post_data_files=None, test_login=False):
  25. """
  26. Get/Post content to SM
  27. :param post_data_files: Files to send in POST
  28. :param post_data: Parameters to send in POST
  29. :param method: HTML method
  30. :param url: URL to parse
  31. :param test_login: Disable test login
  32. :return: data
  33. """
  34. config = GetConfig()
  35. sm_login_url = "https://sugoimusic.me/login.php"
  36. sm_test_url = "https://sugoimusic.me/"
  37. sm_success = "Enabled users"
  38. login_data = {'username': config.sm_user, 'password': config.sm_pass}
  39. sm_session = MyLoginSession(sm_login_url, login_data, sm_test_url, sm_success, test_login)
  40. return sm_session.retrieveContent(url, method, post_data, post_data_files)
  41. class MyLoginSession:
  42. """
  43. Taken from: https://stackoverflow.com/a/37118451/2115140
  44. New features added in jps2sm
  45. Originally by: https://stackoverflow.com/users/1150303/domtomcat
  46. a class which handles and saves login sessions. It also keeps track of proxy settings.
  47. It does also maintains a cache-file for restoring session data from earlier
  48. script executions.
  49. """
  50. def __init__(self,
  51. loginUrl,
  52. loginData,
  53. loginTestUrl,
  54. loginTestString,
  55. test_login=False,
  56. sessionFileAppendix='_session.dat',
  57. maxSessionTimeSeconds=30 * 60,
  58. proxies=None,
  59. userAgent='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1',
  60. forceLogin=False,
  61. **kwargs):
  62. """
  63. save some information needed to login the session
  64. you'll have to provide 'loginTestString' which will be looked for in the
  65. responses html to make sure, you've properly been logged in
  66. 'proxies' is of format { 'https' : 'https://user:pass@server:port', 'http' : ...
  67. 'loginData' will be sent as post data (dictionary of id : value).
  68. 'maxSessionTimeSeconds' will be used to determine when to re-login.
  69. """
  70. urlData = urlparse(loginUrl)
  71. self.proxies = proxies
  72. self.loginData = loginData
  73. self.loginUrl = loginUrl
  74. self.loginTestUrl = loginTestUrl
  75. self.maxSessionTime = maxSessionTimeSeconds
  76. self.sessionFile = urlData.netloc + sessionFileAppendix
  77. self.userAgent = userAgent
  78. self.loginTestString = loginTestString
  79. self.login(forceLogin, test_login, **kwargs)
  80. def modification_date(self, filename):
  81. """
  82. return last file modification date as datetime object
  83. """
  84. t = os.path.getmtime(filename)
  85. return datetime.datetime.fromtimestamp(t)
  86. def login(self, forceLogin=False, test_login=False, **kwargs):
  87. """
  88. login to a session. Try to read last saved session from cache file. If this fails
  89. do proper login. If the last cache access was too old, also perform a proper login.
  90. Always updates session cache file.
  91. """
  92. wasReadFromCache = False
  93. # logger.debug('loading or generating session...')
  94. if os.path.exists(self.sessionFile) and not forceLogin:
  95. time = self.modification_date(self.sessionFile)
  96. # only load if file less than 30 minutes old
  97. lastModification = (datetime.datetime.now() - time).seconds
  98. if lastModification < self.maxSessionTime:
  99. with open(self.sessionFile, "rb") as f:
  100. self.session = pickle.load(f)
  101. wasReadFromCache = True
  102. # logger.debug("loaded session from cache (last access %ds ago) " % lastModification)
  103. if not wasReadFromCache:
  104. self.session = requests.Session()
  105. self.session.headers.update({'user-agent': self.userAgent})
  106. res = self.session.post(self.loginUrl, data=self.loginData,
  107. proxies=self.proxies, **kwargs)
  108. if 'Your username or password was incorrect.' in res.text: # check if login was sucessful
  109. raise Exception("could not log into provided site '%s'"
  110. " (username or password was incorrect)"
  111. % self.loginUrl)
  112. logger.debug('created new session with login')
  113. self.saveSessionToCache()
  114. if test_login:
  115. # test login
  116. logger.debug('Loaded session from cache and testing login...')
  117. res = self.session.get(self.loginTestUrl)
  118. if res.text.lower().find(self.loginTestString.lower()) < 0:
  119. os.remove(self.sessionFile) # delete the session file if login fails
  120. logger.debug(res.text)
  121. raise Exception("could not log into provided site '%s'"
  122. " (did not find successful login string)"
  123. % self.loginUrl)
  124. def saveSessionToCache(self):
  125. """
  126. save session to a cache file
  127. """
  128. # always save (to update timeout)
  129. with open(self.sessionFile, "wb") as f:
  130. pickle.dump(self.session, f)
  131. logger.debug('updated session cache-file %s' % self.sessionFile)
  132. def retrieveContent(self, url, method="get", postData=None, postDataFiles=None, **kwargs):
  133. """
  134. return the content of the url with respect to the session.
  135. If 'method' is not 'get', the url will be called with 'postData'
  136. as a post request.
  137. """
  138. if method == 'get':
  139. res = self.session.get(url, proxies=self.proxies, **kwargs)
  140. else:
  141. res = self.session.post(url, data=postData, proxies=self.proxies, files=postDataFiles, **kwargs)
  142. # the session has been updated on the server, so also update in cache
  143. self.saveSessionToCache()
  144. return res