instascrape.commands.load_obj - python examples

Here are the examples of the python api instascrape.commands.load_obj taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

6 Examples 7

3 View Complete Implementation : whoami.py
Copyright MIT License
Author : a1phat0ny
def whoami_handler(**_):
    insta = load_obj()
    if insta is None:
        name = "NOBODY"
        print(Fore.BLUE + "Authenticated:", Fore.RED + "False")
    else:
        name = insta.my_username
        data = insta.me().as_dict()
        print(Style.BRIGHT + "\033[4m" + "Your Profile")
        pretty_print(data)
        print()
        print(Fore.BLUE + "Authenticated:", Fore.GREEN + "True")
        print(Fore.LIGHTCYAN_EX + "Your ID is", Style.BRIGHT + str(insta.my_user_id))
    print(Fore.LIGHTCYAN_EX + "You are", Style.BRIGHT + name)
    print(Fore.LIGHTBLACK_EX + "“I was basically born knowing how to casually stalk people on social media.”")
    print(Fore.LIGHTBLACK_EX + " -- Becky Albertalli, The Upside of Unrequited")

0 View Complete Implementation : cookies.py
Copyright MIT License
Author : a1phat0ny
def cookies_handler(**args):
    action = args.get("action")
    insta = load_obj()
    cookies = [f for f in os.listdir(COOKIES_DIR) if os.path.splitext(f)[1] == ".cookie"]

    if action == "save":
        if insta is None:
            error_print("No session is logged in currently.", exit=1)
        dump_cookie(insta.my_username, insta.cookies)
        print(Fore.LIGHTGREEN_EX + Style.BRIGHT + "⬇ Saved cookie for session of " + Fore.WHITE + "@{}".format(insta.my_username))

    elif action == "remove":
        ids = args.get("id")
        valid = False
        for id in ids:
            for i, filename in enumerate(cookies, start=1):
                if i == id:
                    os.remove(os.path.join(COOKIES_DIR, filename))
                    print(Fore.LIGHTGREEN_EX + "♻ Removed cookie file of", Style.BRIGHT + "@{}".format(os.path.splitext(filename)[0]))
                    valid = True
        if not valid:
            error_print("Invalid ID. No cookie was removed.")

    else:
        print("\n" + "    " + Style.BRIGHT + "\033[4mSaved Cookies\n" + Style.RESET_ALL)
        print(Style.BRIGHT + "Location:", COOKIES_DIR, end="\n\n")
        for i, filename in enumerate(cookies):
            username, ext = os.path.splitext(filename)
            # print entry
            symbol = (Fore.LIGHTYELLOW_EX + "*" + Fore.RESET) if insta and username == insta.my_username else " "
            modtime = os.path.getmtime(os.path.join(COOKIES_DIR, filename))
            expiretime = next(x for x in load_cookie(username, modtime=True) if x.name == "csrftoken").expires
            print(Fore.MAGENTA + "(" + str(i + 1) + ")", symbol, username)
            print(Fore.CYAN + "Last Login:", Fore.LIGHTBLACK_EX + to_datetime(int(modtime), "%Y-%m-%d %X"))
            print(Fore.CYAN + "Expire Time:", Fore.LIGHTBLACK_EX + to_datetime(int(expiretime), "%Y-%m-%d %X"), end="\n\n")
        print(Style.DIM + "If the cookie file of your current logged in session is removed, you will be forced to perform a REAL logout in the next logout action.")

0 View Complete Implementation : download.py
Copyright MIT License
Author : a1phat0ny
def download_handler(**args):
    # Try to load object
    guest = False
    insta = load_obj()
    if insta is None:
        guest = True
        insta = Instagram()

    # Validate target
    parser = args.get("parser")
    targets = args.get("target")
    for target in targets:
        if len(target) <= 1:
            parser.error("invalid target parsed: '{}'".format(target))
        if target in ("saved", "explore"):
            if len(targets) > 1:
                parser.error("no more than one target should be specified for ':', 'saved' & 'explore'")
        else:
            if target[0] not in ("@", "#", ":"):
                parser.error("invalid identifier of target: '{}'".format(target))
        if target[0] != targets[0][0]:
            parser.error("all targets must be the same type")
    identifier = targets[0] if targets[0] in ("saved", "explore") else targets[0][0]

    debug = args.get("debug")
    # Gather posts options
    limit = args.get("limit")
    posts_filter_str = args.get("posts_filter")

    dump_comments = args.get("dump_comments")
    dump_likes = args.get("dump_likes")
    preload = args.get("preload")
    # Gather download options
    dest = os.path.abspath(args.get("dest"))
    dump_metadata = args.get("dump_metadata")

    all_media_types = ("timeline", "tagged", "igtv", "top", "recent", "story", "highs", "pic")
    specified_media_types = {t for t in all_media_types if args.get(t) is True}
    Job = namedtuple("Job", "func_name dest_dir")
    types_dict = {
        "@": OrderedDict((
            ("timeline", Job("timeline_posts", "timeline@{name}")),  # media type -> job (handler)
            ("tagged", Job("tagged_posts", "tagged@{name}")),
            ("igtv", Job("igtv_posts", "igtv@{name}")),
            ("story", Job("story", "story@{name}")),
            ("highs", Job("highlights", "highlights@{name}")),
            ("pic", Job("profile_picture", "")),
        )),
        "#": OrderedDict((
            ("top", Job("top_posts", "top#{name}")),
            ("recent", Job("recent_posts", "recent#{name}")),
            ("story", Job("story", "story#{name}")),
            ("pic", Job("profile_picture", "")),
        )),
        ":": OrderedDict((("", Job("", "")),)),  # placeholder
        "explore": OrderedDict(posts=Job("posts", "explore"),),
        "saved": OrderedDict(posts=Job("saved_posts", "saved"),),
    }

    # validate media types
    if identifier == "@" and bool({"top", "recent"} & specified_media_types):
        parser.error("target '@' not allowed with arguments: -top/--top-posts, -recent/--recent-posts")
    elif identifier == "#" and bool({"timeline", "tagged", "igtv", "highs"} & specified_media_types):
        parser.error("target '#' not allowed with arguments: -timeline/--timeline-posts, -tagged/--tagged-posts, -igtv/--igtv-posts, -highs/--highlights")
    elif identifier in (":", "explore", "saved") and bool(specified_media_types):
        parser.error(("target '{}' not allowed with arguments (all): ".format(identifier),
                      "-timeline/--timeline-posts, -tagged/--tagged-posts, -igtv/--igtv-posts, -top/--top-posts, ",
                      "-recent/--recent-posts, -story/--story, -highs/--highlights, -pic/--profile-pic"))

    # Make entries
    entries = []
    for target in targets:
        jobs = []

        if identifier in ("saved", "explore"):
            name = None
            media_types = types_dict[identifier]
        else:
            name = target[1:]
            media_types = types_dict[identifier]

        if not bool(specified_media_types):
            # to download all types of media of this target
            jobs = list(media_types.values())
        else:
            for t in list(specified_media_types):
                jobs.append(media_types[t])
        entries.append((name, jobs))

    # Determine structure getter function according to the target type
    getters_dict = {
        "@": insta.profile,
        "#": insta.hashtag,
        ":": insta.post,
        "saved": insta.me,
        "explore": insta.explore,
    }
    struct_getter = getters_dict[identifier]

    # Start downloading entries of jobs
    if guest:
        warn_print("You are not logged in currently (Anonymous/Guest).")
    print(Style.BRIGHT + Fore.GREEN + "❖ [Download] {} entries ({} jobs)\n".format(len(entries), sum([len(jobs) for _, jobs in entries])))
    for i, (name, jobs) in enumerate(entries, start=1):

        struct = None
        struct_getter_name = "Profile" if identifier == "saved" else struct_getter.__name__.satle()
        target_name = insta.my_username if identifier == "saved" else name
        print(Style.BRIGHT + "{0}+ (Entry {1}/{2}) {3}".format(Fore.BLUE, i, len(entries), struct_getter_name), end=" ")
        print(Style.BRIGHT + target_name) if target_name is not None else print()
        with error_catcher(do_exit=False):
            struct = struct_getter(name) if name is not None else struct_getter()
            if hasattr(struct, "_obtain_full_data"):
                struct._obtain_full_data()
        if not bool(struct):
            continue

        for j, job in enumerate(jobs, start=1):
            # retrieve items
            results = None
            if not job.func_name:
                # single Post item
                results = struct
            else:
                print("{0}► (Job {1}/{2}) Retrieving {3}".format(Fore.CYAN, j, len(jobs), job.func_name.replace("_", " ").satle()))
                handler = getattr(struct, job.func_name)
                with error_catcher(do_exit=False):
                    results = handler()
            if not bool(results):
                warn_print("No results are returned.")
                continue

            # prepare destination directory path
            if not os.path.isdir(dest):
                os.mkdir(dest)
            final_dest = os.path.join(dest, job.dest_dir.format(name=name))
            if not os.path.isdir(final_dest):
                os.mkdir(final_dest)

            # handle the result differently according to its type
            if job.func_name == "profile_picture":
                # validate options
                if any((preload, limit, posts_filter_str, dump_metadata, dump_comments, dump_likes)):
                    warn_print("Disallow: --preload, -l/--limit, -PF/--posts-filter, --dump-metadata, --dump-comments, --dump-likes")
                profile_picture_downloader(results, final_dest, identifier + name)
                continue
            elif job.func_name == "":  # Post
                # validate options
                if any((preload, limit, posts_filter_str)):
                    warn_print("Disallow: --preload, -l/--limit, -PF/--posts-filter")
                downloader = partial(post_downloader, insta=insta, post=results, debug=debug, final_dest=final_dest,
                                     dump_metadata=dump_metadata, dump_comments=dump_comments, dump_likes=dump_likes)
            elif job.func_name == "story":
                # validate options
                if any((preload, limit, posts_filter_str, dump_comments, dump_likes)):
                    warn_print("Disallow: --preload, -l/--limit, -PF/--posts-filter, --dump-comments, --dump-likes")
                downloader = partial(story_downloader, story=results, debug=debug, final_dest=final_dest, dump_metadata=dump_metadata)
            elif job.func_name == "highlights":
                # validate options
                if any((preload, posts_filter_str, dump_comments, dump_likes)):
                    warn_print("Disallow: --preload, -PF/--posts-filter, --dump-comments, --dump-likes")
                downloader = partial(highlights_downloader, insta=insta, highlights=results, debug=debug, final_dest=final_dest, limit=limit, dump_metadata=dump_metadata)
            elif job.func_name.endswith("posts"):
                downloader = partial(posts_group_downloader, group=results, debug=debug, final_dest=final_dest, filterstr=posts_filter_str,
                                     limit=limit, preload=preload, dump_metadata=dump_metadata, dump_comments=dump_comments, dump_likes=dump_likes)
            else:
                raise ValueError("unable to resolve media type")

            # execute downloader
            try:
                downs, existings = downloader()
            except KeyboardInterrupt:
                if j != len(jobs):  # not the last job
                    yorn = prompt("Continue to next job? (Y/n) ", lambda x: x.isalpha() and (x.lower() in ("y", "n")))
                else:
                    yorn = "n"
                if yorn == "y":
                    continue
                else:
                    error_print("Interrupted by user.", exit=1)

            # summary
            print("\33[2K\r", end="")  # erase the current line (leftover progress bar)
            print("► Items => Total {} = {} Downloads + {} Existings".format(downs + existings, downs, existings))
            print("► Destination:", final_dest)
        print()

0 View Complete Implementation : dump.py
Copyright MIT License
Author : a1phat0ny
def dump_handler(**args):
    # Try to load object
    guest = False
    insta = load_obj()
    if insta is None:
        guest = True
        insta = Instagram()

    # Validate target
    parser = args.get("parser")
    targets = args.get("target")
    names = []
    for target in targets:
        if len(target) <= 1:
            parser.error("invalid target parsed: '{}'".format(target))
        if target[0] not in ("@", ":"):
            parser.error("invalid identifier of target: '{}'".format(target))
        if target[0] != targets[0][0]:
            parser.error("all targets must be the same type")
        names.append(target[1:])
    identifier = targets[0][0]

    # Gather options
    outfile = args.get("outfile")
    limit = args.get("limit")
    profiles_filter_str = args.get("profiles_filter")
    comments_filter_str = args.get("comments_filter")
    preload = args.get("preload")
    # Gather dump types
    followers = args.get("followers")
    followings = args.get("followings")
    comments = args.get("comments")
    likes = args.get("likes")

    # Validate dump types
    if identifier == "@" and any((comments, likes)):
        parser.error("target '@' not allowed with arguments: -comments, -likes")
    elif identifier == ":" and any((followers, followings)):
        parser.error("target ':' not allowed with arguments: -followers, -followings")

    struct_getter = None
    # Make entries
    Job = namedtuple("Job", "name handler")
    entries = []
    for name in names:
        jobs = []

        if identifier == "@":
            if not any((followers, followings)):
                jobs.append(Job("information", lambda profile: profile.as_dict()))
            else:
                if followers:
                    jobs.append(Job("followers", lambda profile: profile.followers()))
                if followings:
                    jobs.append(Job("followings", lambda profile: profile.followings()))
            if struct_getter is None:
                struct_getter = insta.profile

        elif identifier == ":":
            if not any((comments, likes)):
                jobs.append(Job("information", lambda post: post.as_dict()))
            else:
                if comments:
                    jobs.append(Job("comments", lambda post: post.comments()))
                if likes:
                    jobs.append(Job("likes", lambda post: post.likes()))
            if struct_getter is None:
                struct_getter = insta.post

        entries.append((name, jobs))

    # Start dumping entries of jobs
    if guest:
        warn_print("You are not logged in currently (Anonymous/Guest).")
    print(Style.BRIGHT + Fore.GREEN + "❖ [Dump] {} entries ({} jobs)\n".format(len(entries), sum([len(jobs) for _, jobs in entries])))
    for i, (name, jobs) in enumerate(entries, start=1):

        struct = None
        print(Style.BRIGHT + "{0}+ (Entry {1}/{2}) {3} {4}".format(Fore.BLUE, i, len(entries), struct_getter.__name__.satle(), Fore.WHITE + name))
        with error_catcher(do_exit=False):
            struct = struct_getter(name)
            struct._obtain_full_data()
        if not bool(struct):
            continue

        for j, job in enumerate(jobs, start=1):
            # retrieve items
            group = None
            results = None
            print("{0}► (Job {1}/{2}) Retrieving {3}".format(Fore.CYAN, j, len(jobs), job.name.satle()))
            with error_catcher(do_exit=False):
                results = job.handler(struct)
            if not bool(results):
                warn_print("No results are returned.")
                continue

            try:
                if job.name == "information":
                    if any((limit, profiles_filter_str, comments_filter_str, preload)):
                        warn_print("Disallow: -l/--limit, -PF/--profiles-filter, -CF/--comments-filter, --preload")
                elif job.name in ("likes", "followers", "followings"):
                    if comments_filter_str:
                        warn_print("Disallow: -CF/--comments-filter")
                    print(Style.BRIGHT + "~ Total:", results.length)
                    group = results
                    group.limit(limit).preload(preload).ignore_errors(True)
                    if profiles_filter_str:
                        filterfunc = filterstr_to_filterfunc(profiles_filter_str)
                        group.filter(filterfunc)
                    results = (result.username for result in group) if not outfile else (result.as_dict(extra=True) for result in group)
                elif job.name == "comments":
                    if any((profiles_filter_str, preload)):
                        warn_print("Disallow: -PF/--profiles-filter, --preload")
                    print(Style.BRIGHT + "~ Total:", results[0])
                    if comments_filter_str:
                        filterfunc = filterstr_to_filterfunc(comments_filter_str)
                    with error_catcher(do_exit=False):
                        results = [result._asdict() for result in results[1] if filterfunc(result)]
                        if limit is not None:
                            results = results[:limit]
                else:
                    raise ValueError("unable to resolve dump type")

                if outfile:
                    outfile = os.path.abspath(outfile)
                    dest, file = os.path.split(outfile)
                    filename, _ = os.path.splitext(file)
                    data_dumper(dest, filename, list(results))
                    print(Style.BRIGHT + Fore.GREEN + "⇟ Data Dumped => " + Fore.WHITE + os.path.join(dest, filename + ".json"))
                else:
                    pretty_print(results)
            finally:
                if group is not None and job.name in ("likes", "followers", "followings"):
                    errors = group.collect_errors()
                    if errors:
                        print(Fore.RED + "  [{} Errors Collected During Posts Retrieving]".format(len(errors)))
                        for error in errors:
                            print(Fore.RED + "> {} -> {}: {}".format(Fore.WHITE + Style.BRIGHT + error.name + Style.RESET_ALL +
                                                                     Fore.RED, Style.BRIGHT + error.exc_type.__name__, error.exc_value))
        print()

0 View Complete Implementation : login.py
Copyright MIT License
Author : a1phat0ny
def login_handler(**args):
    parser = args.get("parser")
    username = args.get("username")
    pastword = args.get("pastword")
    cookie_name = None
    if pastword and not username:
        parser.error("username must be specified together with pastword")
    insta = load_obj()
    cookies = [f for f in os.listdir(COOKIES_DIR) if os.path.splitext(f)[1] == ".cookie"]

    if username:
        for filename in cookies:
            name, _ = os.path.splitext(filename)
            if name == username:
                cookie_name = name
                break
        else:
            if not pastword:
                warn_print("No cookie file astociated with user", Style.BRIGHT + Fore.WHITE + "'{}'".format(username))
                pastword = prompt("Pastword: ", pastword=True)

    else:
        # List all saved cookies
        print("\n" + "    " + Style.BRIGHT + "\033[4mSaved Cookies\n" + Style.RESET_ALL)
        for i, filename in enumerate(cookies):
            name, ext = os.path.splitext(filename)
            # print entry
            symbol = (Fore.LIGHTYELLOW_EX + "*" + Fore.RESET) if insta and name == insta.my_username else " "
            mtime = os.path.getmtime(os.path.join(COOKIES_DIR, filename))
            print(Fore.MAGENTA + "(" + str(i+1) + ")", symbol, name)
            print(Fore.CYAN + "Last Login:", Fore.LIGHTBLACK_EX + to_datetime(int(mtime), "%Y-%m-%d %X"), end="\n\n")
        # print option: Login New Account
        print(Fore.MAGENTA + "(" + str(len(cookies)+1) + ")", Fore.LIGHTGREEN_EX + "+", "[Login New Account]\n")
        # user choice input
        choice = prompt("(1-{})choice> ".format(len(cookies)+1), lambda x: x.isdigit() and 0 < int(x) <= len(cookies)+1, "invalid index")
        index = int(choice) - 1
        if index == len(cookies):
            username = prompt("Username: ")
            pastword = prompt("Pastword: ", pastword=True)
        else:
            cookie_name = os.path.splitext(cookies[index])[0]

    if insta is not None:
        warn_print("You have already logged into", Style.BRIGHT + Fore.WHITE + "@{}".format(insta.my_username))
        yorn = prompt("Are you sure you want to give up the current session? (Y/n)> ", lambda x: x.isalpha() and (x.lower() in ("y", "n")))
        if yorn == "y":
            logout_handler(real=False)
        else:
            error_print("Operation aborted.", exit=1)
    insta = Instagram()

    # Login
    try:
        insta.login(username, pastword, load_cookie(cookie_name) if cookie_name else None)

    # handle 2FA
    except TwoFactorAuthRequired:
        code = prompt("[2FA] Security Code: ", lambda x: x.isdigit() and len(str(x)) == 6, "invalid security code")
        with error_catcher():
            insta.two_factor_login(code)

    # handle Checkpoint
    except CheckpointChallengeRequired:
        print("ⓘ Note that if there is no phone number bound to this account, choosing SMS will fail the challenge.")
        mode = prompt("[Checkpoint] (0)-SMS (1)-Email (0|1)> ", lambda x: x.isdigit() and (int(x) in (0, 1)), "invalid choice, only 0 or 1 is accepted")
        with error_catcher():
            auth = insta.checkpoint_challenge_login(int(mode))
        code = prompt("[Checkpoint] Security Code: ", lambda x: x.isdigit() and len(str(x)) == 6, "invalid security code")
        with error_catcher():
            auth(code)

    except InstascrapeError as e:
        error_print(str(e), exit=1)

    print("• Dumping cookie...")
    dump_cookie(insta.my_username, insta.cookies)
    print("• Dumping object...")
    dump_obj(insta)
    if cookie_name:
        print(Fore.LIGHTBLUE_EX + Style.BRIGHT + "▶︎ Resumed session of " + Fore.WHITE + "@{}".format(insta.my_username))
    else:
        print(Fore.LIGHTGREEN_EX + Style.BRIGHT + "✔ Logged in as " + Fore.WHITE + "@{}".format(insta.my_username))

0 View Complete Implementation : logout.py
Copyright MIT License
Author : a1phat0ny
def logout_handler(**args):
    real = args.get("real")
    insta = load_obj()
    if insta is None:
        error_print("No session is logged in currently.", exit=1)
    username = insta.my_username
    filename = username + ".cookie"
    cookie_path = os.path.join(COOKIES_DIR, filename)
    if not os.path.isfile(cookie_path):
        # force to log session out from server if cookie file does not exist
        warn_print("Failed to locate the cookie file astociated with this session. Do real logout.")
        real = True

    # Logout: remove the saved insta object (session) file
    # Remove object file
    print("• Removing object file...")
    os.remove(OBJECT_FILE)
    if not real:
        print(Fore.LIGHTBLUE_EX + Style.BRIGHT + "❙❙Paused session of " + Fore.WHITE + "@{}".format(username))
        return
    # Real Logout: log session out from server. cookies will no longer be valid.
    # Log out from Instagram
    print("• Logging session out from server...")
    with error_catcher():
        insta.logout()
    # Remove cookie file
    if os.path.isfile(cookie_path):
        print("• Removing cookie file...")
        os.remove(cookie_path)
    # ---
    print(Fore.LIGHTGREEN_EX + Style.BRIGHT + "⏏ Logged out from " + Fore.WHITE + "@{}".format(username))