def __init__(self): try: self.database = Database() except Exception as exception: print("Issue initializing database: ", exception) num_follows = int(os.getenv('NUM_DAILY_FOLLOWS', 100)) self.bot = Bot(max_follows_per_day=num_follows, max_unfollows_per_day=num_follows) self.bot.login()
def upload_content(): content_source_file = open('./utils/ig_users.txt') content_sources = content_source_file.read().split("\n") # captions caption_source_file = open('./utils/captions.csv', 'r') caption_source = caption_source_file.read().split(',\n') # hashtags hashtag_source_file = open('./utils/hashtags.csv', 'r') hashtag_source = hashtag_source_file.read().split(' ') # establish connection to the database database = None try: database = Database() except Exception as exception: print("Error Establishing Connection to Database:\n\n", exception) return # upload content sources to database for source in content_sources: database.insert_new_content_source(source) for caption in caption_source: database.insert_new_caption(caption) for hashtag in hashtag_source: database.insert_new_hashtag(hashtag)
def __init__(self) -> None: self.name = "Player" self.resources = ResourceBag() self.farm = Farm() self.farm.add_out_of_hive_bee(BeeWorker(parent=self)) self.farm.add_out_of_hive_bee(BeeWorker(parent=self)) self.farm.add_out_of_hive_bee(BeeWorker(parent=self)) self.farm.add_out_of_hive_bee(BeeWorker(parent=self, level=2)) # self.farm.add_out_of_hive_bee(BeeWorker(parent=self)) self.farm.add_out_of_hive_bee(BeeWarrior(parent=self)) self.farm.add_out_of_hive_bee(BeeWarrior(parent=self)) # self.farm.add_out_of_hive_bee(BeeWarrior(parent=self)) # self.farm.add_out_of_hive_bee(BeeWarrior(parent=self)) self.farm.add_out_of_hive_bee(BeeQueen(parent=self)) # self.farm.add_out_of_hive_bee(BeeQueen(parent=self)) db = Database.get_instance() r = db.get_resource_by_id(3) r.value = 5 self.resources.append(r) r = db.get_resource_by_id(4) r.value = 5 self.resources.append(r) r = db.get_resource_by_id(5) r.value = 5 self.resources.append(r) r = db.get_resource_by_id(2) r.value = 5 self.resources.append(r)
def init_zones(self) -> None: bg_x, bg_y = self.__bg_map_rect.x, self.__bg_map_rect.y positions = [ (bg_x + 20, bg_y + 75), (bg_x + 83, bg_y + 375), (bg_x + 488, bg_y + 183), (bg_x + 298, bg_y + 33), (bg_x + 415, bg_y + 465), # (bg_x + 285, bg_y + 214), (bg_x + 383, bg_y + 578) ] for i in range(6): zone = MapZone(self, i + 1, position=(positions[i][0], positions[i][1])) self.zones.append(zone) db = Database.get_instance() quest_data = db.get_all_quests() for qd in quest_data: quest = Quest(quest_template=qd, icon_offset=(bg_x, bg_y)) if quest.quest_id in self.__completed_quests: self.zones[quest.zone - 1].add_quest(quest, True) self.path_points.clear() for z in self.zones: for qi in z.quest_icons: self.path_points.append(qi.get_rect().center) [z.lock() for z in self.zones] for i in self.__unlocked_zones: self.zones[i - 1].unlock()
def upgrade(self): self.upgrade_button.lock() bee = self.socket1.bee + self.socket2.bee if not bee: return remove_bag = ResourceBag() db = Database.get_instance() if not isinstance(self.socket1.bee, Bee): r1 = db.get_resource_by_id(self.socket1.bee.resource.r_id) r1.value = 1 remove_bag.append(r1) if not isinstance(self.socket2.bee, Bee): r2 = db.get_resource_by_id(self.socket2.bee.resource.r_id) r2.value = 1 remove_bag.append(r2) self.parent.player.resources -= remove_bag self.kill_bee(self.socket1) self.kill_bee(self.socket2) self.result_socket.unlock() self.result_socket.select() self.result_socket.bee = bee self.reload_bee_info()
def __init__(self, width: int, height: int) -> None: pygame.init() os.environ['SDL_VIDEO_CENTERED'] = '1' pygame.display.set_caption("Bee Island") self.__FPS = 60 self.__size = self.width, self.height = width, height self.__screen = pygame.display.set_mode(self.size) icon = pygame.image.load("{0}/icon.ico".format( resource_path("res/images/"))) pygame.display.set_icon(icon) Localization.set_locale(LocalList.RU) self.database = Database() self.main_player = Player() self.__scene_map = { "Map": MapScene(self, name="Map", player=self.main_player), "Farm": FarmScene(self, name="Farm", player=self.main_player), "Main": MainMenuScene(self, name="Main", player=self.main_player) } self.__current_scene = self.__scene_map["Map"] self.change_scene("Main") self.__prev_scene = None self.__done = False self.__clock = Clock()
def __init__(self, parent: Scene): Menu.__init__(self, parent=parent, bg_name="popup3") self._title_label = TextLabel(parent=self, text=self.parent.localization.get_string("hives"), position=self.position, font_size=16, bold=True) self._title_label.set_position( (self.position[0] + self._bg_image.get_rect().centerx - self._title_label.size[0] / 2 + 10, self.position[1] + 3) ) self.hives_list_view = ListView(parent=self, size=(315, 410), item_padding=(8, 8), item_distance=(0, 15), position=(self.position[0] + 35, self.position[1] + 53)) db = Database.get_instance() wax = db.get_resource_by_id(1) self.__wax_amount = 0 for r in self.parent.player.resources.bag: if r.locale_name == wax.locale_name: self.__wax_amount = r.value self.hover_index = -1 for h in self.parent.nest_group.buttons: if not h.hive: continue self.add_hive_to_list(h) self.parent.nest_group.stop_handle()
def notify_daily_metrics(): try: database = Database() except Exception as exception: print(exception) return # get current photo supply photo_supply = database.getPhotoSupply() # get current caption supply caption_supply = database.getCaptionSupply() # get follower supply follower_supply = database.getFollowerSupply() # get prev day follow successes num_days_ago = 1 target_date = datetime.today() - timedelta(days=int(num_days_ago)) target_year = target_date.year target_month = target_date.month target_day = target_date.day prev_day_follow_success = database.getPreviousDayFollowers( target_day, target_month, target_year) message = "Current Photo Supply: " + str(photo_supply) + "</p>" message = message + "<p>Caption Supply: " + str( caption_supply) + "</p>" message = message + "<p>Follower Supply: " + str( follower_supply) + "</p>" message = message + "<p>Number of New Followers: " + str( prev_day_follow_success) + "</p>" notify_email(message)
def __get_random_resource(self): db = Database.get_instance() r_id = random.choice(self.__items_ids) resource = db.get_resource_by_id(r_id) value = 0 if r_id == 1: value = random.randint(5, 10) elif r_id == 2: value = random.randint(2, 6) elif r_id == 3: value = random.randint(1, 10) elif r_id == 4: value = random.randint(1, 5) elif r_id == 5: value = random.randint(1, 3) resource.value = value return resource
def change_lang(self, right: bool) -> None: if right: self.parent.main_window.change_lang( Localization.get_full_locale().get_next()) else: self.parent.main_window.change_lang( Localization.get_full_locale().get_prev()) self.current_lang_label.set_text( Localization.get_current_locale().upper()) db = Database.get_instance() old_resources = [] for r in self.parent.player.resources.bag: old_resources.append(r) self.parent.player.resources.bag.clear() for i in range(len(old_resources)): r = db.get_resource_by_id(old_resources[i].r_id) r.value = old_resources[i].value self.parent.player.resources.append(r) for b in itertools.chain(self.parent.player.farm.bees_from_all_hives, self.parent.player.farm.out_of_hive_bee_list): b.set_locale_to_bonus()
def followee_retrieval(): L = instaloader.Instaloader() request_count = 0 # establish database connection database = None try: database = Database() except Exception as exception: print( "followee_retrieval: Error establishing a connection to the database..." ) return print("Established Database...") # gets content sources from the database NUM_CONTENT_SOURCES = 1 content_source_info = database.select_limit_content_source_rand( NUM_CONTENT_SOURCES) content_source_username = "" if (content_source_info): content_source_username = content_source_info[1] else: return # to store post information data_columns = [ 'username', 'user id', 'followers count', 'following count', 'is private' ] new_followees = pd.DataFrame(columns=list(data_columns)) total_new_followees = 100 i = 0 print("Getting profile information...") try: profile = instaloader.Profile.from_username(L.context, content_source_username) except Exception as exception: print(exception) return request_count = request_rate_control(request_count) print("Getting Posts...") posts = profile.get_posts() request_count = request_rate_control(request_count) print("Posts received") #print("Number of Posts:", len(list(posts))) for post in posts: likers = (post.get_likes()) request_count = request_rate_control(request_count) #print("Number of Likers: ", len(list(likers))) for liker in likers: request_count = request_rate_control(request_count) print(datetime.now(), "Username") username = liker.username print(datetime.now(), " User ID") user_id = liker.userid print(datetime.now(), "User Followers") followers_count = liker.followers print(datetime.now(), "User Followees") following_count = liker.followees print(datetime.now(), "User State") is_private = liker.is_private print(datetime.now(), "all liker information finished...") print("Inserting New Follower to Database...") database.insert_new_follower(user_id, username, followers_count, following_count, is_private) i += 1 print("i:", i) if i >= total_new_followees: # Final Wait Period before the retrieval of content begins final_wait_period = 400 print("Followee Retrieval Finished, waiting ", final_wait_period, "seconds...") sleep(final_wait_period) return
def __init__(self, parent: Scene) -> None: Menu.__init__(self, parent=parent, bg_name="modify_popup1") self._title_label.set_text( text=self.parent.localization.get_string("modify_title")) self._title_label.set_position( (self.position[0] + self._bg_image.get_rect().centerx - self._title_label.size[0] / 2 + 10, self.position[1] + 3)) self.socket_group = RadioGroup() self.socket1 = BeeSocket(parent=self, socket_type=BeeSocketType.ALL, group=self.socket_group, position=(self.position[0] + 102, self.position[1] + 135)) self.socket1.set_image_by_state(ButtonState.SELECTED, "socket5_normal.png") self.dna_image = pygame.image.load("{0}/dna1.png".format( self._res_dir)).convert_alpha() self.dna_rect = self.dna_image.get_rect() self.dna_rect.x = self.socket1.position[0] + self.socket1.size[1] + 12 self.dna_rect.y = self.socket1.get_rect( ).centery - self.dna_rect.height / 2 self.socket2 = BeeSocket( parent=self, socket_type=BeeSocketType.ALL, group=self.socket_group, position=(self.dna_rect.x + self.dna_rect.width + 7, self.socket1.position[1])) self.socket2.set_image_by_state(ButtonState.SELECTED, "socket5_normal.png") upgrade_label = TextLabel( parent=self, text=self.parent.localization.get_string("upgrade_button"), font_size=18) self.upgrade_button = TextButton( parent=self, normal_image_path="start_quest_btn_normal.png", text_label=upgrade_label, text_padding=(40, 4)) self.upgrade_button.set_image_by_state(ButtonState.HOVERED, "start_quest_btn_hover.png") self.upgrade_button.set_image_by_state(ButtonState.LOCKED, "start_quest_btn_locked.png") self.upgrade_button.lock() self.upgrade_button.set_position( (self.socket1.position[0], self.socket2.position[1] + self.socket2.size[1] + 15)) self.upgrade_button.add_action( {ButtonEventType.ON_CLICK_LB: lambda: self.upgrade()}) self.result_socket = BeeSocket(parent=self, group=self.socket_group, position=(0, 0), socket_type=BeeSocketType.ALL) self.result_socket.set_image_by_state(ButtonState.SELECTED, "socket5_normal.png") self.result_socket.set_image_by_state(ButtonState.LOCKED, "socket3_normal.png") self.result_socket.lock() self.result_socket.set_position( (self.upgrade_button.get_rect().centerx - self.result_socket.size[1] / 2, self.upgrade_button.position[1] + self.upgrade_button.size[1] + 15)) self.result_socket.add_action( {ButtonEventType.ON_CLICK_LB: lambda: self.pick_new_bee()}) self.info_block_image = pygame.image.load( "{0}/modify_popup1_info.png".format(self._res_dir)) self.info_block_rect = self.info_block_image.get_rect() self.info_text_label = TextLabel( parent=self, text=self.parent.localization.get_string("info_label"), font_size=14) self.info_block_rect.x = self.upgrade_button.position[ 0] + self.upgrade_button.size[0] + 95 self.info_block_rect.y = self.position[1] + 71 self.info_text_label.set_position( (self.info_block_rect.centerx - self.info_text_label.size[0] / 2, self.info_block_rect.y)) name_label = MultilineTextLabel(parent=self, font_size=14, line_length=220, position=(self.info_block_rect.x + 25, self.info_block_rect.y + 40)) generation_label = TextLabel( parent=self, font_size=14, position=(name_label.position[0], name_label.position[1] + name_label.size[1])) level_label = TextLabel( parent=self, font_size=14, position=(generation_label.position[0], generation_label.position[1] + generation_label.size[1])) xp_label = TextLabel( parent=self, font_size=14, position=(level_label.position[0], level_label.position[1] + level_label.size[1])) speed_label = TextLabel( parent=self, font_size=14, position=(xp_label.position[0], xp_label.position[1] + xp_label.size[1])) hp_label = TextLabel( parent=self, font_size=14, position=(speed_label.position[0], speed_label.position[1] + speed_label.size[1])) bonus_list_label = MultilineTextLabel( parent=self, font_size=14, line_length=220, position=(hp_label.position[0], hp_label.position[1] + hp_label.size[1])) self.info_group = RenderGroup(parent=self, data={ "b_name": name_label, "b_gen": generation_label, "b_level": level_label, "b_exp": xp_label, "b_speed": speed_label, "b_hp": hp_label, "b_bonus": bonus_list_label }) self.bee_list_view = ListView( parent=self, size=(625, 253), padding=(30, 9), item_distance=(15, 15), position=(self.position[0] + 9, self.info_block_rect.y + self.info_block_rect.height - 6)) self.bee_list_view.set_image("{0}/modify_popup1_bee_list.png".format( self._res_dir)) db = Database.get_instance() worker_dna_name = db.get_resource_by_id(3).locale_name warrior_dna_name = db.get_resource_by_id(4).locale_name queen_dna_name = db.get_resource_by_id(5).locale_name jelly_name = db.get_resource_by_id(2).locale_name dna_list = [] for r in self.parent.player.resources.bag: if r.locale_name == worker_dna_name: for i in range(r.value): dna_list.append( DNAEntity(parent=self, dna_type="worker", r=r)) if r.locale_name == warrior_dna_name: for i in range(r.value): dna_list.append( DNAEntity(parent=self, dna_type="warrior", r=r)) if r.locale_name == queen_dna_name: for i in range(r.value): dna_list.append( DNAEntity(parent=self, dna_type="queen", r=r)) if r.locale_name == jelly_name: for i in range(r.value): dna_list.append( DNAEntity(parent=self, dna_type="jelly", r=r)) for b in itertools.chain(dna_list, self.parent.player.farm.out_of_hive_bee_list, self.parent.player.farm.bees_from_all_hives): self.add_bee_to_list(b) self.socket1.add_action( {ButtonEventType.ON_CLICK_LB: lambda: self.add_bee_to_socket()}) self.socket1.add_action({ ButtonEventType.ON_CLICK_RB: lambda: self.remove_bee_from_socket(self.socket1) }) self.socket1.add_action({ ButtonEventType.ON_HOVER_OUT: lambda: self.reload_bee_info(self.socket1.bee) }) self.socket2.add_action( {ButtonEventType.ON_CLICK_LB: lambda: self.add_bee_to_socket()}) self.socket2.add_action({ ButtonEventType.ON_CLICK_RB: lambda: self.remove_bee_from_socket(self.socket2) }) self.socket2.add_action({ ButtonEventType.ON_HOVER_OUT: lambda: self.reload_bee_info(self.socket2.bee) }) self.clear_bee_info() self.parent.nest_group.stop_handle()
def content_retrieval(): L = instaloader.Instaloader() database = None request_count = 0 try: database = Database() except Exception as exception: print("Error Establishing Connection to Database:\n\n", exception) # get source IDs and usernames from database # returns format [content_source_id, content_source_username] content_source_info = database.select_content_sources() print("Number of Content Sources: ", len(content_source_info)) j = 0 # get posts from two days ago to yesterday since = datetime.now() + timedelta(days=-2) until = datetime.now() + timedelta(days=-1) # to store post information data_columns = ['username', 'likes_per_follower', 'post_id', 'url'] new_posts = pd.DataFrame(columns=list(data_columns)) i = 0 # number of posts currently found k = 0 # number of sources covered so far username_to_id = {} for source in content_source_info: k = k + 1 print("\n\nStarting Content Source #", k) content_source_id = source[0] content_username = source[1] username_to_id[content_username] = content_source_id print("Gathering Profile...") try: profile = instaloader.Profile.from_username( L.context, content_username) except Exception as exception: print("Problem finding", content_username, "...") print(exception) continue request_count = request_rate_control(request_count) follower_count = profile.followers print("Profile: ", content_username) print("Follower Count: ", follower_count) request_count = request_rate_control(request_count) # check user's posts, save pictures print("Gathering Posts from Profile...") posts = profile.get_posts() request_count = request_rate_control(request_count) for post in takewhile(lambda p: p.date > since, dropwhile(lambda p: p.date > until, posts)): if post.typename == 'GraphImage': new_posts.loc[i] = [ post.owner_username, post.likes / follower_count, post.mediaid, post.url ] i = i + 1 print("Viable post found, count is now ", i) request_count = request_rate_control(request_count) # instagram gets cranky when tired j = j + 1 print("J: ", j) request_count = request_rate_control(request_count) # find top n new posts n = 5 # number of posts to save if (i < n): n = i new_posts = new_posts.sort_values('likes_per_follower', ascending=False) new_posts = new_posts.iloc[0:n, :] usernames = [] photo_urls = [] for username in new_posts["username"].values: usernames.append(username) for url in new_posts["url"].values: photo_urls.append(url) # get content_source_id and insert url, ID to database for username, url in zip(usernames, photo_urls): source_id = username_to_id[username] database.insert_new_photo(url, source_id)
class InstagramBot(object): database = None bot = None def __init__(self): try: self.database = Database() except Exception as exception: print("Issue initializing database: ", exception) num_follows = int(os.getenv('NUM_DAILY_FOLLOWS', 100)) self.bot = Bot(max_follows_per_day=num_follows, max_unfollows_per_day=num_follows) self.bot.login() def setup_schedule(self): self.start_content_posting() self.start_follow_routine() def start_follow_routine(self): # looking back num_days = os.getenv('FOLLOW_WAIT_PERIOD_IN_DAYS', 2) num_days = 0 past_requested_users_info = self.get_past_requests_to_follow(num_days) # get a list of the current users following the account current_followers_uuid = self.get_current_followers() num_unfollows = len(past_requested_users_info) unfollow_times = self.follow_routine_schedule(num_unfollows) # insert follow backs to follow_success in the database for follower_info in past_requested_users_info: follower_id = follower_info[0] instagram_uuid = follower_info[1] if (instagram_uuid in current_followers_uuid): self.database.insert_new_follower_success(follower_id) # unfollow each of the users that were requested n days ago unfollow_instance = unfollow_times.pop() schedule.every().day.at(unfollow_instance).do( self.unfollow_user, instagram_uuid) # Next Batch: Get number of follows for the day and list of users to follow NUM_DAILY_FOLLOWS = int(os.getenv('NUM_DAILY_FOLLOWS', 300)) daily_follow_info = self.database.select_daily_follows( NUM_DAILY_FOLLOWS) # get an time at which to follow each of the users follow_instances = self.follow_routine_schedule(NUM_DAILY_FOLLOWS) # schedule a job to follow each user and record in the database that # they have been requested for account, instance in zip(daily_follow_info, follow_instances): follower_id = account[0] instagram_uuid = account[1] bot.follow(instagram_uuid) schedule.every().day.at(instance).do(self.follow_user, follower_id, instagram_uuid) def follow_user(self, follower_id, instagram_uuid): bot.follow(instagram_uuid) self.database.insert_new_follower_request(follower_id) return schedule.CancelJob def unfollow_user(self, instagram_uuid): bot.unfollow(instagram_id) return schedule.CancelJob # returns [] with instagram_uuid's of current followers of the account def get_current_followers(self): current_followers = self.bot.followers return current_followers def get_past_requests_to_follow(self, num_days_ago): target_date = datetime.today() - timedelta(days=int(num_days_ago)) target_year = target_date.year target_month = target_date.month target_day = target_date.day past_follow_info = self.database.select_past_follow_requests( target_day, target_month, target_year) return past_follow_info # returns list of str in the format 'HH:MM:SS' def follow_routine_schedule(self, num_instances): instances = [] FOLLOW_PERIOD_START = os.getenv('FOLLOW_PERIOD_BEGIN', '05:00:00') period_start_parts = FOLLOW_PERIOD_START.split(":") hours_base = int(period_start_parts[0]) minute_base = int(period_start_parts[1]) seconds_base = int(period_start_parts[2]) FOLLOW_PERIOD_IN_SEC = int( os.getenv('FOLLOW_PERIOD_LENGTH_IN_SEC', 25000)) for i in range(0, num_instances): # generate num_seconds = random.randint(0, FOLLOW_PERIOD_IN_SEC) seconds_place = int(num_seconds % 60) minutes_place = int((num_seconds / 60) % 60) hours_place = int(((num_seconds / 60) / 60) % 60) # add new time places to start time base hours_place = hours_base + hours_place if (hours_place < 10): hours_place = "0" + str(hours_place) minutes_place = minute_base + minutes_place if (minutes_place < 10): minutes_place = "0" + str(minutes_place) seconds_place = seconds_base + seconds_place if (seconds_place < 10): seconds_place = "0" + str(seconds_place) current_instance = str(hours_place) + ":" + str( minutes_place) + ":" + str(seconds_place) instances.append(current_instance) return instances def start_content_posting(self): num_posts = self.decide_num_posts() post_times = [] # select n post times for i in range(0, num_posts): post_time = self.get_post_time() # ensure that each new post time is not within min minutes of another post time MIN_POST_PERIOD: int = int(os.getenv('MIN_POST_PERIOD', 20)) for x in post_times: current_post_time_compare = int(post_time.replace(":", "")) temp_post_time_compare = int(x.replace(":", "")) while (abs(current_post_time_compare - temp_post_time_compare) < MIN_POST_PERIOD): post_time = self.get_post_time() current_post_time_compare = int(post_time.replace(":", "")) post_times.append(post_time) for post_time in post_times: # download selected photo, tuple in the form (photo_id, photo_url, content_source_id, photo_credits) photo_info = self.select_photo() photo_id = photo_info[0] photo_credits = photo_info[3] #(caption_id, caption) caption_info = self.get_caption() caption = caption_info[1] # select hashtags # array of tuples in the form (hashtag_id, hashtag) hashtag_info = self.get_hashtags() hashtag_string = "" for x in hashtag_info: hashtag_string = hashtag_string + x[1] # combine caption, credit, and hastags into txt file titled with photo id base_caption_file = open('./PostStaging/captionBase.txt', 'r') base_caption = base_caption_file.read() base_caption_file.close() final_caption = base_caption.replace("%c", caption) final_caption = final_caption.replace("%r", photo_credits) final_caption = final_caption.replace("%h", hashtag_string) final_caption_file_location = "./PostStaging/DailyContent/" + photo_id + ".txt" final_caption_file = open(final_caption_file_location, 'w') final_caption_file.write(final_caption) final_caption_file.close() # schedule job at post_time[i] with argument of photo_id schedule.every().day.at(post_time).do(self.post_photo, photo_info, caption_info, hashtag_info) # number between 1 and n def decide_num_posts(self) -> int: # default number of posts a day is 3 MAX_NUM_POSTS: int = int(os.getenv('NUM_DAILY_POSTS_MAX', 3)) MIN_NUM_POSTS: int = int(os.getenv('NUM_DAILY_POSTS_MIN', 3)) number_of_posts = random.randint(MIN_NUM_POSTS, MAX_NUM_POSTS) return number_of_posts # get urls from database # returns tuple in the form of (photo_id, photo_url, content_source_username) def select_photo(self): # tuple format (photo_id, photo_url, content_source_id, content_source_username) post_content = self.database.get_photo_for_posting() photo_id = "" photo_url = "" if (post_content == None): print("Couldn't find URLs") else: photo_id = post_content[0] photo_url = post_content[1] # attempt to download photo, if it fails get another photo and try again while (self.download_photo(photo_id, photo_url) == False): # upon failure of download, register issue in database table (url_invalid) issue_desc = "Problem downloading URL" self.database.insert_url_issue(photo_id, issue_desc) post_content = self.database.get_photo_for_posting() if (post_content == None): # raise alert print("Couldn't find any more URLs") return None photo_id = post_content[0] photo_url = post_content[1] return post_content # download photo via urls to staging directory def download_photo(self, photo_id, photo_url) -> bool: photo_location = "./PostStaging/DailyContent/" + photo_id + ".jpg" try: urllib.request.urlretrieve(photo_url, photo_location) except Exception as exception: print("Error with downloading URL: \n\n", exception) return False return True # get caption from database # returns tuple in the form of (caption_id, caption) def get_caption(self): caption_info = self.database.select_caption() if (caption_info): return caption_info return None # returns a string for the scheduled time for the post # format is 'HH:MM' where HH is in range 0-24 def get_post_time(self) -> str: peak_post_base = os.getenv('PEAK_HOURS_START', '10:00') base_split = peak_post_base.split(':') hours_place = int(base_split[0]) minutes_place = int(base_split[1]) post_offset = self.decide_post_time_offset() hours_offset = int(post_offset / 60) minutes_offset = int(post_offset % 60) hours_place = hours_place + hours_offset minutes_place = minutes_place + minutes_offset # add leading 0 to minutes values less than 10 if (minutes_place < 10): minutes_place = "0" + str(minutes_place) post_time = str(hours_place) + ":" + str(minutes_place) + ":00" return post_time # randomly decide on number between 0 and length of peak hours in minutes def decide_post_time_offset(self) -> int: duration_of_peak = int(os.getenv('PEAK_LEN_MIN', 540)) return random.randint(0, duration_of_peak) def get_hashtags(self): hashtag_info = self.database.select_hashtag_cluster() if (hashtag_info): return hashtag_info return None # post photo via instabot def post_photo(self, photo_info, caption_info, hashtag_info): photo_id = photo_info[0] photo_address = "./PostStaging/DailyContent/" + photo_id + ".jpg" caption_file_address = "./PostStaging/DailyContent/" + photo_id + ".txt" caption_file = open(caption_file_address, 'r') caption = caption_file.read() # instabot does its thing here some_id = bot.upload_photo(photo_address, caption) instagram_id = "instagram_id (temp)" # add post information into post # returns the uuid for that specific post, used in hashtag_log # (uuid, instagram_id, timestamp, photo_id, content_source_id, caption_id) content_source_id = photo_info[2] caption_id = caption_info[0] post_id = self.database.insert_new_post(instagram_id, photo_id, content_source_id, caption_id) # add hashtag log information # (hashtag_id, photo_id) for hashtag in hashtag_info: hashtag_id = hashtag[0] insert_result = self.database.insert_new_hashtag_log( photo_id, hashtag_id) if (insert_result == False): print("Issue logging hashtag: ", hashtag_id, hashtag[1]) return schedule.CancelJob