Skip to content

Instantly share code, notes, and snippets.

@yue82
Last active June 10, 2016 06:30
Show Gist options
  • Save yue82/e3e1161a6bcc41f454179917998a6540 to your computer and use it in GitHub Desktop.
Save yue82/e3e1161a6bcc41f454179917998a6540 to your computer and use it in GitHub Desktop.
nowplaying tweet
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
from requests_oauthlib import OAuth1Session
import requests
import base64
import json
import os
import sys
class Song(object):
def __init__(self):
self.song = dict()
def load_song_data(self):
cmd = 'rhythmbox-client'
opt = 'print-playing-format'
form = '%tt\t%ta\t%at'
cmdset = [cmd, '--{}={}'.format(opt, form)]
output = subprocess.check_output(cmdset).strip()
if output != '':
songdata = output.split('\t')
self.song['title'] = songdata[0]
self.song['artist'] = songdata[1]
self.song['album'] = songdata[2]
return True
else:
print 'Now No Playing'
return False
def get_songdata(self):
return self.song
def get_info_str(self,
info_format='{title} : {artist} - {album} #NowPlaying'):
return info_format.format(**self.song)
class AlbumJacket(object):
def __init__(self, song, searcher):
self.song_data = song.get_songdata()
self.searcher = searcher
self.search_jacket()
def search_jacket(self, query_format='{artist} {album}'):
query = query_format.format(**self.song_data)
res = self.searcher.search_img(query)
self.jacket_img_url = res
def as_base64(self):
req = requests.get(self.jacket_img_url)
if check_status(req.status_code):
return base64.urlsafe_b64encode(req.content)
return None
class ImageSearcher():
def __init__(self, secrets,
url='https://www.googleapis.com/customsearch/v1'):
self.secrets = secrets
self.url = url
def search_img(self, query, require_field='link'):
search_type = 'image'
num = 1
payload = {'key': self.secrets['key'],
'cx': self.secrets['cx'],
'searchType': search_type,
'num': num,
'q': query}
req = requests.get(self.url, params=payload)
if check_status(req.status_code):
try:
body = json.loads(req.text)
if 'items' in body:
return body['items'][0][require_field]
else:
return body
except:
return None
return None
class Twitter(object):
media_url = 'https://upload.twitter.com/1.1/media/upload.json'
tweet_url = 'https://api.twitter.com/1.1/statuses/update.json'
def __init__(self, secrets):
self.tw = OAuth1Session(secrets['CK'],
secrets['CS'],
secrets['AT'],
secrets['AS'])
def upload_base64_img(self, data):
postdata = {'media_data': data}
req = self.tw.post(self.media_url, files=postdata)
if check_status(req.status_code):
try:
body = json.loads(req.text)
return body['media_id_string']
except:
return None
return None
def tweet_now_playing(self, tweet, media_id):
postdata = {'status': tweet}
if media_id:
postdata['media_ids'] = [int(media_id)]
else:
print 'No jacket image'
req = self.tw.post(self.tweet_url, params=postdata)
if check_status(req.status_code):
print 'POST OK'
def read_secrets(filename):
script_dir = os.path.abspath(os.path.dirname(__file__))
secret_dir = '/'.join(script_dir.split('/')[:-1]) + '/secret'
secret_file = secret_dir + '/' + filename
secrets = {}
with open(secret_file, 'r') as fs:
for line in fs:
k, v = line.strip().split(' ')
secrets[k] = v
return secrets
def check_status(status_code):
if status_code == 200:
return True
func_name = sys._getframe(1).f_code.co_name
print 'Error({}): {}'.format(func_name, status_code)
return False
def main():
tw_secrets = read_secrets('np_tw_secret')
img_secrets = read_secrets('img_srch_secret')
song = Song()
if song.load_song_data():
tweet = song.get_info_str()
img_searcher = ImageSearcher(img_secrets)
jacket = AlbumJacket(song, img_searcher)
tw = Twitter(tw_secrets)
media_id = tw.upload_base64_img(jacket.as_base64())
tw.tweet_now_playing(tweet, media_id)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment