DEV Community

Cover image for Creating an IG top 9 without using creepy 3rd party apps
Daniel Schep
Daniel Schep

Posted on

7

Creating an IG top 9 without using creepy 3rd party apps

It's that time of year again when everyone on Instagram is posting their #top9. I wanted one too, but I don't trust whatever app people are authenticating with their Instagram accounts because it shares more with a 3rd party than I care to do. (TL;DR: use the script in this gist)

Fortunately, a quick googling led me to the igramscraper python library

Then the first step was using it's get_medias function:

posts = instagram.get_medias("_schep", 50) # use your account of course!
Enter fullscreen mode Exit fullscreen mode

Next, we need to filter to only this year's photos and sort by likes and grab the top 9. For this we use the standard library datetime module, a list comprehension, sorted and a slice to limit the result to 9.

this_year_photos = [
    post
    for post in posts
    if datetime.fromtimestamp(post.created_time).year == 2019
    and post.type == post.TYPE_IMAGE
]

top9 = sorted(this_year_photos, key=lambda post: -post.likes_count)[:9]
Enter fullscreen mode Exit fullscreen mode

Now we have a list of your top 9 most liked photos of 2019! Next we need to download them and create your top9 image. For this we use the popular requests and Pillow libraries:

img = Image.new("RGB", (1080, 1080)) # create the new image
for post in top9:
    # download and open the image
    tile = Image.open(requests.get(post.image_high_resolution_url, stream=True).raw)
    # resize the image
    tile = tile.resize((360, 360), Image.ANTIALIAS)
    # paste it into our new image
    img.paste(tile, (i % 3 * 360, i // 3 * 360))
Enter fullscreen mode Exit fullscreen mode

The call to img.paste is a little bit obtuse. I'm using the modulo(%) operator to determine what column the image is on then multiplying by the size of the image and using the floor division(//) operator to determine the row.

Then we save it!

img.save("my-top9.jpg")
Enter fullscreen mode Exit fullscreen mode

If you have non-square images in your top 9, you might notice that they are deformed. To deal with this, we crop our tile before resizing it:

if tile.size[0] > tile.size[1]:
    tile = tile.crop(
        (
            (tile.size[0] - tile.size[1]) / 2,
            0,
            (tile.size[0] - tile.size[1]) / 2 + tile.size[1],
            tile.size[1],
        )
    )
elif tile.size[0] < tile.size[1]:
    tile = tile.crop(
        (
            0,
            (tile.size[1] - tile.size[0]) / 2,
            tile.size[0],
            (tile.size[1] - tile.size[0]) / 2 + tile.size[0],
        )
    )
Enter fullscreen mode Exit fullscreen mode

🎉 We've just created our own top9 image with out having to authenticate our account with a creep 3rd party IG app!

Check out the full source code for an easy to use version of this script in this Gist:

"""
An Instagram Top 9 generator that doesn't require connecting your account
to an untrustworthy 3rd party Instagram app.
Install the requirements with `pip3 install igramscraper Pillow click`
then run `python3 top9.py`
When done, you will have a YOURUSERNAME-top9.jpg in your working directory.
"""
from datetime import datetime
from igramscraper.instagram import Instagram
from PIL import Image
import click
import requests
instagram = Instagram()
@click.command()
@click.option(
"--user",
prompt="Your Instagram account (without @)",
help="The instagram username to create a top 9 for",
)
@click.option(
"--login-user",
help="The instagram username to login with. Doesn't log in if omitted.",
)
@click.option(
"--tfa",
help="Use two factor auth during login",
)
def top9(user, tfa=False, login_user=None):
if login_user:
password = click.prompt("Your Instagram password")
instagram.with_credentials(login_user, password)
instagram.login(two_step_verificator=tfa)
now = datetime.utcnow()
if now.month > 7:
this_year = now.year
else:
this_year = now.year - 1
posts = None
count = 0
prev = None
while (
posts is None
or datetime.fromtimestamp(posts[-1].created_time).year >= this_year
):
count += 50
posts = instagram.get_medias(user, count)
last = datetime.fromtimestamp(posts[-1].created_time)
if prev == last:
break
prev = last
this_year_photos = [
post
for post in posts
if datetime.fromtimestamp(post.created_time).year == this_year
and post.type in (post.TYPE_IMAGE, post.TYPE_SIDECAR)
]
top9 = sorted(this_year_photos, key=lambda post: -post.likes_count)[:9]
img = Image.new("RGB", (1080, 1080))
for i, post in enumerate(top9):
tile = Image.open(requests.get(post.image_high_resolution_url, stream=True).raw)
if tile.size[0] > tile.size[1]:
tile = tile.crop(
(
(tile.size[0] - tile.size[1]) / 2,
0,
(tile.size[0] - tile.size[1]) / 2 + tile.size[1],
tile.size[1],
)
)
elif tile.size[0] < tile.size[1]:
tile = tile.crop(
(
0,
(tile.size[1] - tile.size[0]) / 2,
tile.size[0],
(tile.size[1] - tile.size[0]) / 2 + tile.size[0],
)
)
tile = tile.resize((360, 360), Image.ANTIALIAS)
print(f"{post.likes_count} likes - {post.link}")
img.paste(tile, (i % 3 * 360, i // 3 * 360))
img.save(f"{user}-top9.jpg")
if __name__ == "__main__":
top9()
view raw top9.py hosted with ❤ by GitHub

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (2)

Collapse
 
theague profile image
Kody James Ague •

Can you explain how to use this as if I'm 5 years old?

Collapse
 
dschep profile image
Daniel Schep • • Edited
  1. Make sure you have python3
  2. python3 -m venv top9-venv
  3. . ./top9-venv/bin/activate
  4. pip install click Pillow igramscraper
  5. wget https://gist.githubusercontent.com/dschep/28bf9848d76d4790df1330a246cc90cc/raw/3638a090ad770dcdb5cee9917ba80f3665ee8582/top9.py
  6. python top9.py

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay