예제 #1
0
 def download_photos(self,
                     photos_list,
                     base_path,
                     rename,
                     force_overwrite=False,
                     log_to_widget=True,
                     thread_update_signal=None):
     for i in range(len(photos_list)):
         photo = photos_list[i]
         log.d("API", "Downloading full-size photos", log_to_widget)
         filename, skipped = self.download_file(photo['url'], base_path,
                                                rename, i, "",
                                                force_overwrite,
                                                log_to_widget)
         if filename is not None:
             photo['local_path'] = str(os.path.abspath(filename))
         if 'processedFiles' in photo:
             processed_files = photo['processedFiles']
             small_photo = processed_files[len(processed_files) - 1]
             log.d("API", "Downloading small photo", log_to_widget)
             filename, skipped = self.download_file(
                 small_photo['url'],
                 base_path + "/small/",
                 rename,
                 i,
                 "_small",
                 force_overwrite,
                 log_to_widget=log_to_widget)
             if filename is not None:
                 small_photo['local_path'] = str(os.path.abspath(filename))
예제 #2
0
 def write_data_to_file(self,
                        data,
                        base_path,
                        log_to_widget=True,
                        thread_update_signal=None):
     log.d("API", "Data written to: " + str(base_path), log_to_widget)
     with open(base_path + 'data.yaml', 'w') as fp:
         yaml.dump(data, fp)
예제 #3
0
 def pause(self, log_to_widget=True, thread_update_signal=None):
     '''
     In order to appear as a real Tinder user using the app...
     When making many API calls, it is important to pause a...
     realistic amount of time between actions to not make Tinder...
     suspicious!
     '''
     nap_length = 3 * random()
     log.d("API", 'Napping for %f seconds...' % nap_length)
     sleep(nap_length)
예제 #4
0
 def update_matches_widgets(self):
     log.d("FEATURES", str("Updating Matches widgets"))
     self.update_widgets(
         self.app.matches, self.app.new_matches, self.get_matches_button,
         self.reload_matches_button, self.download_matches_data_button,
         self.download_matches_amount, self.rename_matches_images_checkbox,
         self.force_matches_download_checkbox, self.matches_new_counter,
         self.matches_counter, self.matches_photos_checkbox,
         self.matches_instagram_checkbox)
     self.matches_messages_checkbox.setEnabled(
         self.download_matches_data_button.isEnabled())
예제 #5
0
 def save_to_yaml(self):
     try:
         print("Saving yaml...")
         log.i("LOGIN_F", self.config_file)
         log.d("LOGIN_F", self.config)
         with open(self.config_file, 'w') as fy:
             yaml.dump(self.config, fy)
         self.statusBar.showMessage("Credentials Saved to " +
                                    str(self.config_file))
     except Exception as e:
         log.e("LOGIN_F", "Exceptipn: " + str(e))
예제 #6
0
 def download_messages(self,
                       match_data,
                       log_to_widget=True,
                       thread_update_signal=None):
     log.d("API", "Downloading match messages", log_to_widget)
     messages = self.get_messages(match_data, 100, None, log_to_widget,
                                  thread_update_signal)
     log.d(
         "API", "Downloaded messages: " +
         str(match_data["_id"] + ": " + str(messages)), log_to_widget)
     if messages is not None and 'data' in messages:
         return messages['data']['messages']
     return []
예제 #7
0
 def update_recommendations_widgets(self):
     log.d("FEATURES", str("Updating Recommendations Widgets"))
     self.update_widgets(
         self.app.recommendations, self.app.new_recommendations,
         self.get_recommendations_button,
         self.reload_recommendations_button,
         self.download_recommendations_data_button,
         self.download_recommendations_amount,
         self.rename_recommendations_images_checkbox,
         self.force_recommendations_download_checkbox,
         self.recommendations_new_counter, self.recommendations_counter,
         self.recommendations_photos_checkbox,
         self.recommendations_instagram_checkbox)
예제 #8
0
    def download_person_data(self,
                             data,
                             base_folder,
                             photos,
                             insta,
                             messages,
                             rename_images,
                             force_overwrite=False,
                             log_to_widget=True,
                             thread_update_signal=None):
        person_data, type = self.get_person_data(data)
        id = person_data['_id']
        name = person_data['name']
        path = base_folder + "/" + str(name) + "_" + str(id) + "/"
        person_data['path'] = str(os.path.abspath(path))
        log.i(
            "API", "Downloading " + type + ": " + name + " " + id + " to: " +
            str(person_data['path']), log_to_widget)
        if os.path.exists(path):
            log.d("API", "Person path already exists: " + person_data['path'],
                  log_to_widget)
        else:
            os.makedirs(path)
            log.d("API", "Person path created: " + person_data['path'],
                  log_to_widget)
        person_data['local_path'] = str(os.path.abspath(path))

        if insta and 'instagarm' in person_data:
            self.download_instagram_photos(person_data['instagram'], path,
                                           rename_images, force_overwrite,
                                           log_to_widget, thread_update_signal)

        if photos and 'photos' in person_data:
            self.download_photos(person_data['photos'], path, rename_images,
                                 force_overwrite, log_to_widget,
                                 thread_update_signal)

        if messages and 'match' in type:
            data['messages'] = self.download_messages(data, log_to_widget,
                                                      thread_update_signal)

        data['AI_Dating_metadata'] = {}
        data['AI_Dating_metadata']['last_updated_datetime'] = str(
            datetime.now().strftime("%d-%b-%Y %H:%M:%S"))
        data['AI_Dating_metadata']['last_updated_timestamp'] = str(
            datetime.utcnow())

        self.write_data_to_file(data, path, log_to_widget,
                                thread_update_signal)
        return data
예제 #9
0
 def all_matches(self,
                 amount=60,
                 message=0,
                 page_token=None,
                 log_to_widget=True,
                 thread_update_signal=None):
     try:
         url = self.host + '/v2/matches?locale=en&count=' + str(
             amount) + '&message=' + str(message) + '&is_tinder_u=false'
         log.d("API", "All matches page: " + str(page_token), log_to_widget)
         if page_token:
             url = url + '&page_token=' + page_token
         r = requests.get(url, headers=self.headers)
         json = r.json()
         log.d("API", "All matches keys " + str(json.keys()), log_to_widget)
         log.d("API", "All matches data " + str(json['data'].keys()),
               log_to_widget)
         log.d(
             "API", "All matches data matches  " +
             str(len(json['data']['matches'])) + " " +
             str(json['data']['matches'][0].keys()), log_to_widget)
         log.d("API", "All matches meta " + str(json['meta'].keys()),
               log_to_widget)
         log.i(
             "API", "all_matches: Got response. Status: " +
             str(json['meta']['status']) + ": " +
             utils.error_code_to_message[json['meta']['status']],
             log_to_widget)
         if 'next_page_token' in json['data']:
             new_data = self.all_matches(amount, message,
                                         json['data']['next_page_token'])
             for match in new_data['data']['matches']:
                 match[
                     'page_token'] = page_token  # This will be needed to get messages
             json['data']['matches'] = json['data']['matches'] + new_data[
                 'data']['matches']
             self.page_token = json['data']['next_page_token']
         elif message <= 0:
             new_data = self.all_matches(amount, 1, None)
             json['data']['matches'] = json['data']['matches'] + new_data[
                 'data']['matches']
         log.i("API", "Total matches " + str(len(json['data']["matches"])),
               log_to_widget)
         return json
     except requests.exceptions.RequestException as e:
         log.e(
             "API", "Something went wrong. Could not get your match info:" +
             str(e), log_to_widget)
예제 #10
0
 def update_fb_token(self, token):
     print(self.config)
     try:
         self.config['facebook']['auth_token'] = token
         log.d("LOGIN_F", self.config)
         if 'error' in self.config['facebook']['auth_token']:
             Exception("Error: " + self.config['facebook']['auth_token'])
         self.linedEdit_fb_token.setText(
             self.config['facebook']['auth_token'])
         self.button_fb_spinner.hideSpinner()
     except Exception as e:
         log.e("LOGIN_F", "Exception Getting token: " + str(e))
         self.config['facebook']['auth_token'] = ""
         self.linedEdit_fb_token.setText("ERROR")
     QApplication.processEvents()
     self.statusBar.clearMessage()
예제 #11
0
 def get_match_info(self, log_to_widget=True, thread_update_signal=None):
     matches = self.get_updates()['matches']
     now = datetime.utcnow()
     match_info = {}
     for match in matches[:len(matches)]:
         try:
             person = match['person']
             person_id = person['_id']  # This ID for looking up person
             name = person['name']
             id = match['id']
             msg_count = match['message_count']
             photos = self.get_photos(person)
             bio = ""
             if 'bio' in person.keys():
                 bio = person['bio']
             gender = person['gender']
             avg_succ_rate = self.get_avg_successRate(person)
             messages = match['messages']
             age = self.calculate_age(match['person']['birth_date'])
             distance = self.get_person(person_id)['results']['distance_mi']
             last_activity_date = match['last_activity_date']
             match_info[person_id] = {
                 "name": name,
                 "match_id": id,  # This ID for messaging
                 "message_count": msg_count,
                 "photos": photos,
                 "bio": bio,
                 "gender": gender,
                 "avg_successRate": avg_succ_rate,
                 "messages": messages,
                 "age": age,
                 "distance": distance,
                 "last_activity_date": last_activity_date,
             }
             log.d("API", name + "_" + id)
         except Exception as ex:
             template = "An exception of type {0} occurred. Arguments:\n{1!r}"
             message = template.format(type(ex).__name__, ex.args)
             log.e("API", message)
             # continue
     log.i("API", "All data stored in variable: match_info")
     filename = self.data_folder + 'match_info.json'
     with open(filename, 'w') as fp:
         json.dump(match_info, fp)
         log.i("API",
               "All data dumped to file: " + str(os.path.abspath(filename)))
     return match_info
예제 #12
0
 def completeBackgroundTask(self, info="", tag=None):
     self.updateBackgroundTaskInfo(info)
     if tag is not None and tag in self.background_tasks_list:
         self.background_tasks_list.remove(tag)
     self.background_completed += 1
     if self.background_completed >= self.background_count_total:
         self.background_count_total = 0
         self.background_completed = 0
         self.spinner.hideSpinner()
         self.updateBackgroundTaskInfo("All tasks completed!")
         self.background_count_label.setVisible(False)
     self.updateBackgroundTaskCount()
     log.d(
         "THREADS", "Completed background task " + str(info) + " " +
         str(self.background_completed) + "/" +
         str(self.background_count_total) + " Tasks: " +
         str(self.background_tasks_list), False)
예제 #13
0
    def get_profile(self, doAsync=True, force_update=False):
        try:
            with open(self.profile_file, "r") as pf:
                data = json.load(pf)
            log.d("APP", "Profile file read: " + str(data))
            self.setProfileData(data, download_data=False)
        except Exception as e:
            log.e("APP", "No profile found")

        if self.profile_info is None or force_update:
            self.get_api_data(doAsync,
                              self.tinder_api.get_self, [], {},
                              finished_callback=self.setProfileData,
                              callback_kwargs={'download_data': True},
                              update_callback=self.updateBackgroundTaskInfo,
                              info="Getting profile data",
                              tag="ProfileGetter")
예제 #14
0
 def download_instagram_photos(self,
                               instagram_data,
                               base_path,
                               rename,
                               force_overwrite=False,
                               log_to_widget=True,
                               thread_update_signal=None):
     if 'photos' not in instagram_data.keys():
         log.d("API", "NO instagram photos", log_to_widget)
         return
     log.d("API", "Downloading instagram photos", log_to_widget)
     for i in range(len(instagram_data['photos'])):
         filename, skipped = self.download_file(
             instagram_data['photos'][i]['image'], base_path + "instagram/",
             rename, i, "", force_overwrite, log_to_widget)
         if filename is not None:
             instagram_data['photos'][i]['local_path'] = str(
                 os.path.abspath(filename))
예제 #15
0
    def setProfileData(self, new_data, download_data=False):
        log.d("APP", "New profile info, download: " + str(download_data))
        if new_data is not None:
            self.profile_info = new_data
        if self.profile_info is None:
            return
        if self.window is not None and self.window.chat_widget is not None:
            self.window.chat_widget.setLeftId(self.profile_info["_id"])

        if download_data:
            self.get_api_data(True,
                              self.tinder_api.download_person_data, [
                                  self.profile_info, self.profile_folder, True,
                                  True, False, True
                              ], {"force_overwrite": True},
                              finished_callback=self.updateProfileData,
                              update_callback=self.updateBackgroundTaskInfo,
                              info="Downloading Profile data to: " +
                              str(self.profile_folder),
                              tag="ProfileDownloader")
예제 #16
0
 def addBackgroundTask(self, task, info=""):
     if task.tag is not None:
         while task.tag in self.background_tasks_list:
             string_matches = re.match(r"(.*)([0-9]+)", task.tag)
             if string_matches is not None:
                 # print("string_matches: " +str(string_matches.groups()))
                 task.tag = string_matches.group(1) + str(
                     int(string_matches.group(2)) + 1)
             else:
                 task.tag += "_1"
         self.background_tasks_list.append(task.tag)
     self.updateBackgroundTaskInfo(info)
     self.background_count_total += 1
     if self.background_count_total <= 1:
         self.spinner.showSpinner()
         self.background_count_label.setVisible(True)
     self.updateBackgroundTaskCount()
     log.d(
         "THREADS", "Added new background task " + str(info) + " " +
         str(self.background_completed) + "/" +
         str(self.background_count_total) + " Tasks: " +
         str(self.background_tasks_list), False)
     self.thread_pool.start(task)
예제 #17
0
 def get_auth_token(self,
                    fb_auth_token,
                    fb_user_id,
                    log_to_widget=True,
                    thread_update_signal=None):
     log.d("API", "get_auth_token: " + fb_auth_token + "\t" + fb_user_id,
           log_to_widget)
     if "error" in fb_auth_token:
         return {"error": "could not retrieve fb_auth_token"}
     if "error" in fb_user_id:
         return {"error": "could not retrieve fb_user_id"}
     url = self.host + '/v2/auth/login/facebook'
     req = requests.post(url,
                         headers=self.headers,
                         data=json.dumps({
                             'token': fb_auth_token,
                             'facebook_id': fb_user_id
                         }))
     try:
         log.d("API", "Sending JSON request", log_to_widget)
         json_request = req.json()
         log.i("API",
               "Token JSON status: " + str(json_request['meta']['status']),
               log_to_widget)
         tinder_auth_token = json_request["data"]["api_token"]
         self.headers.update({"X-Auth-Token": tinder_auth_token})
         self.get_headers.update({"X-Auth-Token": tinder_auth_token})
         self.get_message_headers.update(
             {"X-Auth-Token": tinder_auth_token})
         log.s("API", "You have been successfully authorized!")
         return tinder_auth_token
     except Exception as e:
         log.e("API", "Error getting Tinder Token " + str(e), log_to_widget)
         return {
             "error":
             "Something went wrong. Sorry, but we could not authorize you."
         }
예제 #18
0
 def download_file(self,
                   url,
                   base_path,
                   rename,
                   index,
                   postfix="",
                   force_overwrite=False,
                   log_to_widget=True,
                   thread_update_signal=None):
     try:
         file_name = str(index) + postfix + ".jpg"
         if not rename:
             file_name = (url.split("/")[-1] + '.jpg').split('?')[0]
         full_filename = base_path + file_name
         if not os.path.exists(base_path):
             os.makedirs(base_path)
             log.d("API", "File path created: " + base_path, log_to_widget)
         if not os.path.exists(full_filename) or force_overwrite:
             self.browser.open(url)
             with open(full_filename, "wb") as image_file:
                 image_file.write(self.browser.response.content)
                 if force_overwrite:
                     log.d("API", "Forcing Re-Download: " + full_filename,
                           log_to_widget)
                 else:
                     log.i("API", "Downloading: " + full_filename,
                           log_to_widget)
                 return full_filename, False
         else:
             log.d(
                 "API",
                 "File already downloaded (force_overwrite=False): " +
                 full_filename, log_to_widget)
             return full_filename, True
     except Exception as e:
         log.e("API", "EXCEPTION!: " + str(e), log_to_widget)
         return None, False
예제 #19
0
 def setMatches(self, data):
     log.d("APP", "updateMatches called")
     self.new_matches = None
     self.matches = data
     self.updateMatchesWidgets()
예제 #20
0
 def setRecommendations(self, data):
     log.d("APP", "setRecommendations called")
     self.new_recommendations = None
     self.recommendations = data
     self.updateRecommendationsWidgets()
예제 #21
0
 def person_data_received(self, data):
     self.window.json_view.load_data(data["data"])
     log.d("PERSON_DATA", +str(data))
예제 #22
0
 def showEvent(self, e):
     if self.parsed_args.css:
         log.d("LOGIN_W", "Shown!")
     # Do something with the event here
     super(LoginWindow, self).showEvent(e)  # Do the default action on the parent class QLineEdit
예제 #23
0
 def focusOutEvent(self, e):
     if self.parsed_args.css:
         log.d("LOGIN_W", "Focus Out!")
         self.app.updateStyle()
     # Do something with the event here
     super(LoginWindow, self).focusOutEvent(e)  # Do the default action on the parent class QLineEdit
예제 #24
0
    def reload_data_from_disk(self,
                              folder_path,
                              merged_filename,
                              photos,
                              insta,
                              messages,
                              force_overwrite=False,
                              log_to_widget=True,
                              thread_update_signal=None):
        list = []
        try:
            for subdir, dirs, files in os.walk(folder_path):
                total_dirs = len(dirs)
                for i in range(len(dirs)):
                    data_path = os.path.join(subdir, dirs[i]) + "/"
                    data_file_path = data_path + "data.yaml"
                    try:
                        if os.path.exists(data_file_path):
                            with open(data_file_path) as yf:
                                data = yaml.safe_load(yf)
                                person_data, type = self.get_person_data(data)
                                person_data['path'] = os.path.abspath(
                                    data_path
                                )  # Updating the data path just in case
                                if photos and 'photos' in person_data:
                                    self.download_photos(
                                        person_data['photos'],
                                        data_path,
                                        True,
                                        force_overwrite,
                                        log_to_widget=log_to_widget)

                                if insta and 'instagram' in person_data and 'photos' in person_data[
                                        'instagram']:
                                    self.download_instagram_photos(
                                        person_data['instagram'],
                                        data_path,
                                        True,
                                        force_overwrite,
                                        log_to_widget=log_to_widget)
                                if messages and 'match' in type:
                                    data['messages'] = self.download_messages(
                                        data, log_to_widget)
                                log.d("API", "Updating " + type + " data file",
                                      log_to_widget)

                                data['AI_Dating_metadata'] = {}
                                data['AI_Dating_metadata'][
                                    'last_updated_datetime'] = str(
                                        datetime.now().strftime(
                                            "%d-%b-%Y %H:%M:%S"))
                                data['AI_Dating_metadata'][
                                    'last_updated_timestamp'] = str(
                                        datetime.utcnow())

                                self.write_data_to_file(
                                    data, data_path, log_to_widget,
                                    thread_update_signal)
                                log.d("API", "Updated", log_to_widget)
                                list.append(data)
                            log.i(
                                "API",
                                str(i + 1) + "/" + str(total_dirs) + " - " +
                                str(dirs[i]) + " " + person_data['name'],
                                log_to_widget)
                        else:
                            log.i(
                                "API",
                                str(i + 1) + "/" + str(total_dirs) + " - " +
                                str(dirs[i]) + " SKIPPED", log_to_widget)
                    except Exception as e:
                        log.e("API", "Exception reloading data " + str(e),
                              log_to_widget)
                    if thread_update_signal is not None:
                        thread_update_signal.emit(
                            str(folder_path) + "\t" + str(i + 1) + "/" +
                            str(total_dirs))
                break
        except Exception as e:
            log.e("API", "Exception in reloading from disk: " + str(e),
                  log_to_widget)
        try:
            with open(merged_filename, "w+") as f:
                json.dump(list, f)
        except Exception as e:
            log.e(
                "API", "Could not save merged file " + merged_filename + ": " +
                str(e), log_to_widget)
        return list