Advertisement
Guest User

Untitled

a guest
Apr 21st, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.98 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. import urllib.request, urllib.parse, http.cookiejar
  4. from bs4 import BeautifulSoup
  5.  
  6. class piuWrapper():
  7.     # This entire wrapper is built around SQL injections that haven't been patched yet.
  8.     # THIS CAN BREAK AT ANY TIME BY ANDAMIRO IMPROVING SECURITY
  9.  
  10.     def __init__(self, username, password):
  11.         self.username = username
  12.         self.password = password
  13.        
  14.         self.cookieJar = http.cookiejar.CookieJar()
  15.         self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor())
  16.  
  17.     def login(self):
  18.         # The website expects usernames to be e-mail addresses.
  19.    
  20.         url = 'https://[redacted]/piu.login_check.php?'
  21.         credentials = urllib.parse.urlencode({
  22.             'mb_id' : self.username,
  23.             'mb_password' : self.password
  24.             })
  25.         self.opener.open(url, credentials.encode())
  26.         # loginSuccess = self.verifyLogin()
  27.         # return loginSuccess
  28.  
  29.     def scrapeID():
  30.         # Search profile page HTML for profile IDs.
  31.         pass
  32.  
  33.         url = 'http://[redacted]/piu.mypage/piu.my_profile.php'
  34.         resp = self.opener.open(url)
  35.         html = resp.read().decode('ascii', 'ignore')
  36.  
  37.     def getScore(self, chartID, primeID):
  38.         resp = self.scrapeScore(chartID, primeID)
  39.         scoreInfo = self.scoreExtract(resp, chartID)
  40.  
  41.         return scoreInfo
  42.  
  43.     def scrapeScore(self, chartID, primeID):
  44.         # Takes advantage of a bool blind attack to report individual song/chart play data.
  45.         # Data reported is date of best money score, best money score, and best grade.
  46.         # Best grade is not necessarily tied to best money score Rank Mode is not accounted for.
  47.  
  48.         url = 'http://[redacted]/piu.item_shop/piu.item_check_window.php?'
  49.  
  50.         userPlay = urllib.parse.urlencode({
  51.             'unlock_mode_code_no' : chartID,
  52.             'this_item_prime_member_no' : primeID
  53.             })
  54.  
  55.  
  56.         resp = self.opener.open(url, userPlay.encode())
  57.  
  58.         return resp
  59.  
  60.     def scoreExtract(self, resp, chartID):
  61.         # Takes the HTTPResponse and turns it into a readable string.
  62.         # Parses the HTML to locate the table containing song info.
  63.         # Finally returns song title, difficulty, and PR info as an array.
  64.  
  65.         html = resp.read().decode('ascii', 'ignore')
  66.         soup = BeautifulSoup(html, "html.parser")
  67.         table = soup.find("table", attrs={"class":"step_window_info"})
  68.         scoreInfo = []
  69.  
  70.         if table == None:
  71.             pass
  72.  
  73.         else:
  74.             headers = [header.text for header in table.find_all('th')]
  75.             items = [item.text for item in table.find_all('td')]
  76.  
  77.             #scoreInfo.append(chartID)
  78.  
  79.             for header in headers:
  80.                 if "Lv." not in header:
  81.                     continue
  82.                 else:
  83.  
  84.                     scoreInfo.append(header)
  85.  
  86.             for item in items:
  87.                 if 'Has no Data' in item:
  88.                     scoreInfo.append('Never Played')
  89.                 else:
  90.                     scoreInfo.append(item)
  91.  
  92.         return scoreInfo
  93.  
  94. # Separate file below
  95. #############################################################################################################
  96.  
  97. import csv, argparse, threading, random, time, os
  98. from queue import Queue
  99. from bs4 import BeautifulSoup
  100.  
  101. # Local file
  102. from piuWrapper import piuWrapper
  103.  
  104. def main():
  105.     start_time = time.clock
  106.  
  107.     # Simple arguments for simple programs
  108.     parser = argparse.ArgumentParser()
  109.     parser.add_argument('-u', dest='username', help='Username/E-mail Address (Required)')
  110.     parser.add_argument('-p', dest='password', help='Password (Required)')
  111.     parser.add_argument('-P', dest='primeID', help='Specify your Prime ID (if known).')
  112.     parser.add_argument('-d', dest='dryrun', action='store_true', default='store_false', help='Runs program and simulates fetching data instead of actually fetching data.')
  113.     # parser.add_argument('-P', dest='profile', help='The profile/ID you want to scrape.')
  114.     parser.add_argument('-f', dest='filename', default='Score_Log{0}.csv', help='Specify the output file name.')
  115.     parser.add_argument('-c', dest='chartIDRequest', default=0, help='Request score for specific chart by ID.')
  116.     # parser.add_argument('C', help='Request score for specific chart by name (Not yet functional)')
  117.  
  118.     args = vars(parser.parse_args())
  119.  
  120.     username = args['username']
  121.     password = args['password']
  122.     filename = args['filename']
  123.     chartIDRequest = args['chartIDRequest']
  124.     primeID = args['primeID']
  125.     dryrun = args['dryrun']
  126.  
  127.     chartIDMax = 2565
  128.     threads = 12
  129.     fileInc = 1
  130.  
  131.     ############################################################
  132.     # if dryrun != True:
  133.     #   if chartIDRequest > 0:
  134.     #       print(piugame.fakeGetScore(chartIDRequest))
  135.  
  136.     #   else:
  137.     #       for chartID in range(chartIDMax + 1):
  138.     #           if chartID is not 0:
  139.     #               scoreInfo = fakeGetScore(chartID)
  140.     #               print(scoreInfo)
  141.     #           else:
  142.     #               continue
  143.  
  144.     piugame = piuWrapper(username, password)
  145.     piugame.login()
  146.     # TODO: Verify succesful login.
  147.  
  148.     allSongInfo = []
  149.  
  150.     if dryrun == True:
  151.         pass
  152.     else:
  153.         lock = threading.Lock() # threading.Lock() synchronizes console output between threads.
  154.  
  155.         q = Queue()
  156.  
  157.         def threadedGetScore(chartID, primeID):
  158.             print('Fetching chart ID {0}\'s score'.format(chartID))
  159.             sleepytime = random.randrange(10, 30)
  160.             time.sleep = sleepytime/100
  161.             songInfo = piugame.getScore(chartID, primeID)
  162.             with lock:
  163.                 allSongInfo.append(songInfo)
  164.                     # with lock:
  165.                     #   writer.writerow([songInfo])
  166.         def worker():
  167.             while True:
  168.                 queueJob = q.get()
  169.                 chartID = queueJob['chartID']
  170.                 primeID = queueJob['primeID']
  171.                 songInfo = threadedGetScore(chartID, primeID)
  172.                 q.task_done()
  173.                 #return songInfo
  174.  
  175.         start = time.perf_counter()
  176.         for chartID in range(chartIDMax):
  177.             queueJob = {'chartID' : chartID, 'primeID' : primeID}
  178.             q.put(queueJob)
  179.  
  180.         for n in range(threads):
  181.             t = threading.Thread(target=worker)
  182.             t.daemon = True     # Thread dies when main thread exits.
  183.             t.start()
  184.  
  185.         q.join()
  186.  
  187.         print('Sorting. . .')
  188.  
  189.     while os.path.exists(filename.format(fileInc)):
  190.         fileInc += 1
  191.  
  192.     with open(filename.format(fileInc), 'w', newline='') as csvfile:
  193.         allSongInfo.sort()
  194.         writer = csv.writer(csvfile, delimiter=';', quotechar='|')
  195.         writer.writerows(allSongInfo)
  196.  
  197.     exeTime = (time.clock() - start_time)/60
  198.     print('Execution done in {} minutes'.format())
  199.     input('Done! Step on the center panel to quit.')
  200.  
  201. if __name__ == '__main__':
  202.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement