# Glorious Gification of HipChat Rooms

To counter yesterday’s post on Iterating the GitHub API, how about something a little more lighthearted today: GIFs1.

Animated GIFs are an amusing–if arguably useful–way of communicating. But hey, if something is worth doing, it’s worth OVERDOING, no2?

So I wrote a script to upload my entire collection of GIFs to a HipChat room3:

#!/usr/bin/env python3

import os
import random
import re
import requests
import sys
import time

ACCESS_TOKEN = '{redacted}'
ROOM_ID = 8675309
GIF_PATH = '{redacted}'
TIMEOUT = 60

from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText

'Authorization': 'Bearer {}'.format(ACCESS_TOKEN),
'Accept-Charset': 'UTF-8',
'Content-Type': 'multipart/related',
}

url = 'https://api.hipchat.com/v2/room/{}/share/file'.format(ROOM_ID)

paths = [
os.path.join(path, file)
for path, dirs, files in os.walk(GIF_PATH)
for file in files
if file.endswith('.gif')
]
random.shuffle(paths)

for path in paths:
print(path)

raw_body = MIMEMultipart('related')
with open(path, 'rb') as fin:
'Content-Disposition',
'attachment',
name = 'file',
filename = path.split('/')[-1]
)
raw_body.attach(img)

time.sleep(TIMEOUT)


The main reason that this script is at all interesting is that the API excepts (and requires) a multipart/related request, but the Requests won’t send one. So instead we have to pull in Python’s email libraries in order to generate the request body. It’s a bit annoying, but an interesting dive into some of the more esoteric details of web requests.

Also, I’ve been on a kick of using slightly more complicated list comprehension:

paths = [
os.path.join(path, file)
for path, dirs, files in os.walk(GIF_PATH)
for file in files
if file.endswith('.gif')
]


Basically, if you put multiple for loops in a list comprehension body, it will return a single iterable, nested from the first to the last. So this is equivalent to:

paths = []
for path, dirs, files in os.walk(GIF_PATH):
for file in files:
if file.endswith('.gif'):
os.path.join(path, file)


It’s arguable which is more Pythonic (probably the latter), but I do find it interesting what impact writing piles of functional code (Racket) will do to code in other languages.

And, that’s it. Short and sweet. Use responsibly.

1. gif, not jif ↩︎