Skip to content

Enhanced Breakdown of `main.py` with Detailed Explanations and Examples

sujay1599 edited this page Jul 20, 2024 · 1 revision

Enhanced Breakdown of main.py with Detailed Explanations and Examples

The main.py file is the primary entry point for the InstagramTheftyScraperPosterHuman project. It orchestrates the overall workflow of scraping, uploading, and performing human-like actions on Instagram to avoid detection.

Overview

  • Initialization: Sets up logging, directories, and files.
  • Loading Configuration: Loads the configuration settings from config.yaml.
  • Instagram Login: Logs into Instagram using encrypted credentials.
  • Main Loop: Continuously scrapes and uploads reels while performing human-like actions to avoid detection.

Detailed Code Breakdown

Import Statements

import logging
import os
import random
import json
from time import time, sleep
from tqdm import tqdm
from config_setup import load_config
from auth import login, decrypt_credentials
from instagrapi import Client
from scrape import scrape_reels, perform_human_actions
from upload import upload_reels_with_new_descriptions, get_unuploaded_reels, load_uploaded_reels
from utils import initialize_status_file, read_status, update_status, random_sleep, log_random_upload_times, log_random_waits, initialize_json_file
import subprocess
  • logging: Used for logging information and errors.
  • os: Provides functions to interact with the operating system.
  • random: Provides functions for generating random numbers.
  • json: Used for reading and writing JSON files.
  • time, sleep: Provides time-related functions.
  • tqdm: Used for displaying progress bars.
  • config_setup: Contains functions for loading the configuration.
  • auth: Contains functions for logging into Instagram and decrypting credentials.
  • instagrapi: Provides the Client class for interacting with Instagram.
  • scrape: Contains functions for scraping reels and performing human-like actions.
  • upload: Contains functions for uploading reels.
  • utils: Contains utility functions for managing status, logging, and sleeping.

Default Tags

DEFAULT_TAGS = [
    'instagram', 'instadaily', 'LikeForFollow', 'LikesForLikes', 'LikeForLikes', 
    'FollowForFollow', 'LikeForLike', 'FollowForFollowBack', 'FollowBack', 
    'FollowMe', 'instalike', 'comment', 'follow', 'memes', 'funnymemes', 
    'memestagram', 'dankmemes', 'memelord', 'instamemes', 'instagood', 'love', 
    'photooftheday', 'picoftheday', 'likeforlikes', 'likes', 'followme', 
    'photography', 'beautiful', 'fashion', 'smile', 'me', 'followforfollowback', 
    'l', 'likeforfollow', 'myself', 'likeforlike', 'bhfyp', 'f', 'followback', 
    'followers', 'followforfollow', 'style', 'photo', 'happy', 'instamood', 
    'nature', 'trending', 'art', 'india', 'viral', 'explore', 'model', 'travel'
]
  • DEFAULT_TAGS: A list of default hashtags to be used in the configuration.

Logging and Directory Initialization

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Ensure the downloads directory exists
downloads_dir = 'downloads'
if not os.path.exists(downloads_dir):
    os.makedirs(downloads_dir)
    logging.info(f"Created directory: {downloads_dir}")

# Delete old files if they exist
for file in ['status.json', 'last_scraped_timestamp.txt', 'random-upload-times.json', 'random-waits.json']:
    if os.path.exists(file):
        os.remove(file)
        logging.info(f"Deleted {file}")

# Initialize files
initialize_status_file()
logging.info("Initialized status file")

# Initialize random-upload-times.json and random-waits.json
initialize_json_file('random-upload-times.json')
initialize_json_file('random-waits.json')
  • logging.basicConfig(): Configures logging to display messages with a specific format.
  • downloads_dir: Ensures the downloads directory exists, creating it if necessary.
  • Deleting old files: Deletes old status and log files if they exist.
  • initialize_status_file(): Initializes the status file.
  • initialize_json_file(): Initializes the JSON files for logging random waits and upload times.

Loading Configuration and Logging into Instagram

config = load_config()
logging.info("Loaded configuration")

INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD = decrypt_credentials(config)
logging.info("Decrypted Instagram credentials")

cl = Client()

login(cl, INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD, 'session.json')
logging.info("Logged in to Instagram")
  • load_config(): Loads the configuration settings from config.yaml.
  • decrypt_credentials(config): Decrypts the Instagram credentials using the provided key.
  • Client(): Creates an instance of the Instagram Client.
  • login(cl, INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD, 'session.json'): Logs into Instagram using the provided credentials and session file.

Sleep with Progress Bar

def sleep_with_progress_bar(duration):
    for _ in tqdm(range(int(duration)), desc="Sleeping", unit="s"):
        sleep(1)
  • sleep_with_progress_bar(duration): Sleeps for the specified duration while displaying a progress bar.

Main Function

def main():
    status = read_status()
    logging.info("Read initial status")

    uploaded_reels = load_uploaded_reels('upload_log.txt')
    logging.info(f"Loaded uploaded reels: {len(uploaded_reels)} reels")

    custom_tags = config.get('custom_tags', [])
    tags = custom_tags if custom_tags else DEFAULT_TAGS

    while True:
        current_time = time()
        logging.debug(f"Current time: {current_time}")

        last_scrape_time = status.get('last_scrape_time', 0) or 0
        last_upload_time = status.get('last_upload_time', 0) or 0
        logging.debug(f"Last scrape time: {last_scrape_time}, Last upload time: {last_upload_time}")

        if (current_time - last_scrape_time) >= config['scraping']['scrape_interval_minutes'] * 60:
            if config['scraping']['enabled']:
                for profile in config['scraping']['profiles'].split():
                    logging.info(f"Scraping profile: {profile}")
                    scraped_reels = scrape_reels(cl, profile, config['scraping']['num_reels'], last_scrape_time, uploaded_reels, status['reels_scraped'])
                    status['reels_scraped'].extend(scraped_reels)
                    update_status(last_scrape_time=current_time, reels_scraped=status['reels_scraped'])
                    logging.info("Updated status after scraping")
                logging.info("Finished scraping reels from profiles")
                logging.info("Displaying dashboard before waiting phase")
                subprocess.run(["python", "dashboard.py"])

                # Randomly perform human-like actions
                if random.random() < 0.5:
                    perform_human_actions(cl, tags)
                wait_time = random_sleep(60, 90, action="uploading phase")  # Increased wait time before moving to uploading
                logging.info(f"Waited for {wait_time:.2f} seconds before moving to the uploading phase")
                sleep_with_progress_bar(wait_time)

        if (current_time - last_upload_time) >= config['uploading']['upload_interval_minutes'] * 60:
            if config['uploading']['enabled']:
                logging.info("Starting upload process")
                unuploaded_reels = get_unuploaded_reels('downloads', status['reels_scraped'], uploaded_reels)
                if not unuploaded_reels:
                    logging.info("No new reels to upload, initiating scraping protocol.")
                    for profile in config['scraping']['profiles'].split():
                        logging.info(f"Scraping profile: {profile}")
                        scraped_reels = scrape_reels(cl, profile, config['scraping']['num_reels'], last_scrape_time, uploaded_reels, status['reels_scraped'])
                        status['reels_scraped'].extend(scraped_reels)
                        update_status(last_scrape_time=current_time, reels_scraped=status['reels_scraped'])
                        logging.info("Updated status after scraping")
                    logging.info("Finished scraping reels from profiles")
                    logging.info("Displaying dashboard before waiting phase")
                    subprocess.run(["python", "dashboard.py"])
                else:
                    upload_reels_with_new_descriptions(cl, config, unuploaded_reels, uploaded_reels, 'upload_log.txt')
                    update_status(last_upload_time=current_time)
                    logging.info("Finished uploading reels")

                    # Randomly perform human-like actions
                    if random.random() < 0.5:
                        perform_human_actions(cl, tags)

                    logging.info("Displaying dashboard before waiting phase")
                    subprocess.run(["python", "dashboard.py"])

        # Randomly perform human-like actions during the waiting period
        if random.random() < 0.5:
            perform_human_actions(cl, tags)

        total_wait_time = config['uploading']['upload_interval_minutes'] * 60
        elapsed_time = 0

        while elapsed_time < total_wait_time:
            remaining_time = total_wait_time - elapsed_time
            interval = min(remaining_time, random.uniform(60, 300))  # Pause every 1 to 5 minutes
            sleep_with_progress_bar(interval)
            elapsed_time += interval
            if random.random() < 0.2:
                logging.info("Performing human-like actions during

 wait time")
                perform_human_actions(cl, tags)
                logging.info(f"Waiting for {config['uploading']['upload_interval_minutes'] - elapsed_time // 60} minutes before next upload")

        next_upload_time = datetime.now() + timedelta(seconds=total_wait_time)
        logging.info(f"Next upload at: {next_upload_time.strftime('%Y-%m-%d %H:%M:%S')}")

if __name__ == "__main__":
    main()
  • status = read_status(): Reads the initial status from the status file.
  • uploaded_reels = load_uploaded_reels('upload_log.txt'): Loads the list of uploaded reels.
  • custom_tags = config.get('custom_tags', []): Retrieves custom tags from the configuration.
  • while True: Main loop that continuously performs scraping, uploading, and human-like actions.
  • if (current_time - last_scrape_time) >= config['scraping']['scrape_interval_minutes'] * 60: Checks if it is time to scrape new reels.
  • if (current_time - last_upload_time) >= config['uploading']['upload_interval_minutes'] * 60: Checks if it is time to upload new reels.
  • total_wait_time: Calculates the total wait time before the next upload.
  • elapsed_time: Tracks the elapsed time during the waiting period.
  • while elapsed_time < total_wait_time: Pauses at random intervals and performs human-like actions during the waiting period.
  • next_upload_time: Logs the next upload time.

This detailed breakdown provides a comprehensive understanding of how the main.py script orchestrates the overall workflow of the InstagramTheftyScraperPosterHuman project.