Skip to content

Instantly share code, notes, and snippets.

@dvaruas
Last active May 20, 2022 09:46
Show Gist options
  • Save dvaruas/2cf949033514af30f04da1b12003a059 to your computer and use it in GitHub Desktop.
Save dvaruas/2cf949033514af30f04da1b12003a059 to your computer and use it in GitHub Desktop.
compare stamps missing in friend's collection (@Slowly)
import json
import os
import sys
from typing import Any, Callable, Set, Optional
import urllib.request
# The friend's name for whom you want to fetch the stamps, my_friends.json has
# the name present in it.
FRIEND_NAME = "MyImaginaryFriend"
# ----- API endpoint --------
FETCH_INFO_PATH: str = "https://api.getslowly.com/users/{user_id}/extend"
# ---------------------------
def fetchurl_n_process(
url: str, processing_func: Optional[Callable[[Any], Any]] = None
) -> Optional[Any]:
print("fetching for URL: {}".format(url))
x = None
with urllib.request.urlopen(url) as furl:
resp = furl.read()
x = json.loads(resp)
if processing_func == None:
return x
try:
return processing_func(x)
except Exception as e:
print("An error occured while processing: {}".format(e))
return None
def fetchfile_n_process(
file_path: str, processing_func: Optional[Callable[[Any], Any]] = None
) -> Optional[Any]:
print("fetching file: {}".format(file_path))
data = None
with open(file_path, "r") as fr:
file_str = fr.read().strip(" ;\n\t")
data = json.loads(file_str)
if processing_func == None:
return data
try:
return processing_func(data)
except Exception as e:
print("An error occured while processing: {}".format(e))
return None
if __name__ == "__main__":
# Get all of my current stamps
def get_my_stamps(jsonObj: Any) -> Set[str]:
my_stamps = set()
for item in jsonObj["items"]:
my_stamps.add(item["item_slug"])
return my_stamps
my_stamps: Optional[Set[str]] = fetchfile_n_process(
file_path=os.path.join(os.path.dirname(__file__), "my_info.json"),
processing_func=get_my_stamps,
)
if my_stamps == None or len(my_stamps) == 0:
sys.exit("Got no stamps for myself, something went wrong!")
print("My total stamps is = {}".format(len(my_stamps)))
# Get the id for the friend in FRIEND_NAME
def get_user_id(jsonObj: Any) -> Optional[int]:
for f in jsonObj["friends"]:
if f["name"] == FRIEND_NAME:
return f["user_id"]
return None
my_friends_id: Optional[int] = fetchfile_n_process(
file_path=os.path.join(os.path.dirname(__file__), "my_friends.json"),
processing_func=get_user_id,
)
if my_friends_id == None:
sys.exit("Could not get the friends ID, something went wrong!")
# Fetch the stamps for my friend
def get_user_stamps(jsonObj: Any) -> Optional[Set[str]]:
return set(jsonObj["stamp_collection"]["data"])
their_stamps: Optional[Set[str]] = fetchurl_n_process(
url=FETCH_INFO_PATH.format(user_id=my_friends_id),
processing_func=get_user_stamps,
)
if their_stamps == None:
sys.exit(
"Oops! Nothing was found. The user probably has stamp collection set as private"
)
# Diff the two stamps
diff = sorted(my_stamps.difference(their_stamps))
# Show the result of the diff
for i, stamp_name in enumerate(diff):
print("{:3d} : {}".format(i, stamp_name))
{
"friends": [
{
...,
"user_id": 1234567,
"name": "MyImaginaryFriend",
...,
},
...,
],
"hidden": [],
"requests": 0
}
{
"id": 1234567,
"name": "my name",
"original_name": "my.name",
...,
"items": [
{
"id": 21468319,
"user": 3390369,
"item_type": "stamp",
"item_slug": "free",
"item_name": "Stamp",
"country": null,
"count": 0,
"created_at": "2020-08-30 09:15:13",
"updated_at": "2020-08-30 09:15:13"
},
{
"id": 21468320,
"user": 3390369,
"item_type": "zodiac",
"item_slug": "libra",
"item_name": "Libra",
"country": null,
"count": 0,
"created_at": "2020-08-30 09:15:13",
"updated_at": "2020-08-30 09:15:13"
},
{
"id": 21468321,
"user": 3390369,
"item_type": "stamp",
"item_slug": "hello",
"item_name": "Hello World",
"country": null,
"count": 0,
"created_at": "2020-08-30 09:15:13",
"updated_at": "2020-08-30 09:15:13"
},
...,
],
"excluded_tags": [],
...,
}

Usage guidelines

Q: Why would someone want this?
A: Previously I had made a stamps sent tracker here. This allowed one to track which stamps they have already sent to their friend (in order to prevent sending duplicates and having your friend 😞). Now that slowly allows stamp collections for a penpal to be public officially, we can take advantage of that information to choose from our stamp set whatever they are missing in their collection.

This script is as clean and user-friendly as I could make it.
Meaning - it isn't and needs some getting your hands dirty! 😝

ATTENTION: This script won't work for penpals who have their stamp collection set to hidden. They need to have it public.

Files you need

Save all below files in the same directory.

  • my_friends.json: See given sample file. This needs to be filled up by you (check howto in steps below).
  • my_info.json: See given sample file. This needs to be filled up by you (check howto in steps below).
  • fetch.py: The main python script. Run simply with python3 fetch.py. Follow the steps below before running.

Steps

  • Open developer tools in your Browser (I'm using the Chrome browser, there would be similar tools for other browsers as well).
  • Open the slowly desktop site.
  • Go to the network tab in developer tools to check out all the requests the browser made when you visited the slowly desktop site.
  • Find a request which looks like this - https://api.getslowly.com/web/me?token=someLongRandomStringWhichIsActuallyAToken.
    • The response to this request is a JSON object, which contains information about your account (and your stamps which we are interested in here).
    • Copy the value of this field and dump it in the file my_info.json.
    • Note: Everytime a new stamp is added to collection, redo this step.
  • Find a request which looks like this - https://api.getslowly.com/users/me/friends/v2?requests=1&dob=true&token=someLongRandomStringWhichIsActuallyAToken.
    • The response to this request is a JSON object, which contains information about your current friends.
    • Copy the value of this field and dump it in the file my_friends.json.
    • Note: Everytime you make new friends, redo this step.
  • Now fill in the name of your friend in FRIEND_NAME of fetch.py.
  • Run python3 fetch.py.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment