commit dd7c82f249c88cb65eddc39fd184986a5badc7e8 Author: Pulguer Gonzalo Date: Mon Nov 1 19:48:15 2021 -0300 initial commit diff --git a/info_imp.py b/info_imp.py new file mode 100644 index 0000000..8a034c0 --- /dev/null +++ b/info_imp.py @@ -0,0 +1,8 @@ +datinho = { + 'sp_client_id':'7ef58947fe58464084bf88523f36542d', + 'sp_client_secret': '578c39b1ada744b5946478890245e8c5', + 'sp_playlist_id': '5efDZLiNO0NPP1mIOAAIBi', + 'ig_user': '333randomsong', + 'ig_pw': 'Botinhocr7', + 'BITLY_TOKEN':"a4c2f103a860122aeef89e25ef7e37f0fb9ba1b7" + } diff --git a/instab.py b/instab.py new file mode 100644 index 0000000..37d249a --- /dev/null +++ b/instab.py @@ -0,0 +1,96 @@ +import info_imp +import songrand +import requests +import shutil +import os +from os.path import exists +from instabot import Bot +import glob +import bitly_api + +# If cookie.json exists, deletes it (won't log in if cooke.json exists) + +cookie_del = glob.glob("config/*cookie.json") +if cookie_del != []: + os.remove(cookie_del[0]) + +# Instagram Bot Credentials +user = info_imp.datinho['ig_user'] +pw = info_imp.datinho['ig_pw'] + +# Lists to be storage the lists from songrand.py functions + +songs = [] +name = [] +cover = [] +cov3r = [] + +# Call songrand.py functions to get the lists + +songrand.getCover(cover) +songrand.getSongList(songs) +songrand.getNameSong(name) + +# Picks the number + +number = songrand.pickNumber(songs) + +# Picks the song picked randomly through songrand.py function pickNumber, stores the value in number + +fate1 = songrand.pickList(number, songs) +fate2 = songrand.pickList(number, name) + +# Sorts the cover links + +cov3r = sorted(set(cover), key=lambda x:cover.index(x)) + +# Picks the cover of the song picked before, number it's multiplied by 3 because there are 3 different resolutions for each song +# This way we get the best resolution, since the best resolution gets downloaded first + +fate3 = songrand.pickList(number*3, cov3r) + +# Gets the name of the cover downloaded in this folder + +filename = fate3.split("/")[-1] + +# Bitly shortener to shorten the spotify song link + +BITLY_ACCESS_TOKEN = info_imp.datinho['BITLY_TOKEN'] +access = bitly_api.Connection(access_token = BITLY_ACCESS_TOKEN) +full_link = fate1 +short_url = access.shorten(full_link) +furl = short_url['url'] + +# Caption for the post + +cap = fate2 + ' ' + furl + +# Download the cover pic in .JPEG format + +r = requests.get(fate3, stream = True) + +if r.status_code == 200: + r.raw.decode_content = True + with open(filename,'wb') as f: + shutil.copyfileobj(r.raw, f) + +# InstaBot logs in the account and posts the cover (filename) with the captions (cap) + +bot = Bot() +bot.login(username = user, password = pw) +bot.upload_photo(filename, + caption = cap) + +# We create a new variable so we can delete the picture after we posted it + +filew = filename + '.REMOVE_ME' + +# When the image is uploaded, it renames to filew because of InstaBot, so we check if filename exists. If filename exists, we delete it + +val1 = os.path.exists(filename) +if val1 == True: + os.remove(filename) +elif os.path.exists(filew) == True: + os.remove(filew) + +# If filename doesn't exist, we do the same with filew diff --git a/songrand.py b/songrand.py new file mode 100644 index 0000000..f5ed2a4 --- /dev/null +++ b/songrand.py @@ -0,0 +1,69 @@ +import info_imp +import json +import test +import random + +client_id = info_imp.datinho['sp_client_id'] +client_secret = info_imp.datinho['sp_client_secret'] + +sp = test.SpotifyAPI(client_id, client_secret) + +songs = [] +name = [] +cover = [] + +# Uses the getSong function from songrand.py to get a list of all the songs URLs in playlist + +def getSongList(lista): + dict1 = sp.getPlayTracks() + dict2 = dict1['items'] + for songs in dict2: + dict3 = songs['track'] + for songs_def in dict3['external_urls'].values(): + lista.append(songs_def) + return lista + +# Uses the getNameSong function from sonrand.py to get a list of all the songs names in playlist + +def getNameSong(lista): + dict1 = sp.getPlayTracks() + dict2 = dict1['items'] + for songs in dict2: + dict3 = songs['track'] + for songs_def in dict3['external_ids'].values(): + lista.append(dict3['name']) + return lista + +# Uses the getCover function from songrand.py to get a list of all the song cover URLs in playlist + +def getCover(lista): + dict1 = sp.getPlayTracks() + dict2 = dict1['items'] + for songs in dict2: + dict3 = songs['track'] + for songs_def in dict3['album'].values(): + dict4 = dict3['album'] + for things1 in dict4['images']: + dict5 = dict4['images'] + for things2 in dict5: + dict6 = things2 + for things3 in dict6: + if things3 not in lista: + lista.append(dict6['url']) + return lista + + +# Picks a random number between 0 and len(lista)-1 to fit list indexes + +def pickNumber(lista): + num = len(lista) - 1 + pick = random.randrange(0, num) + return pick + +# Picks the element [numberGaveByPickNumberFunction] and returns that value + +def pickList(num, lista): + fin3 = lista[num] + return fin3 + + diff --git a/test.py b/test.py new file mode 100644 index 0000000..c303fdd --- /dev/null +++ b/test.py @@ -0,0 +1,93 @@ +import info_imp +import json +import base64 +import datetime +from urllib.parse import urlencode +import requests + +client_id = info_imp.datinho['sp_client_id'] +client_secret = info_imp.datinho['sp_client_secret'] + +class SpotifyAPI(object): + access_token = None + access_token_expires = datetime.datetime.now() + access_token_did_expire = True + client_id = None + client_secret = None + token_url = "https://accounts.spotify.com/api/token" + + def __init__(self, client_id, client_secret, *args, **kwargs): + super().__init__(*args, **kwargs) + self.client_id = client_id + self.client_secret = client_secret + + def get_client_credentials(self): + """ + Returns a base64 encoded string + """ + if client_secret == None or client_id == None: + raise Exception("You must set client_id and client_secret") + client_creds = f"{client_id}:{client_secret}" + client_creds_b64 = base64.b64encode(client_creds.encode()) + return client_creds_b64.decode() + + def get_token_headers(self): + client_creds_b64 = self.get_client_credentials() + return { + "Authorization": f"Basic {client_creds_b64}" + } + + def get_token_data(self): + return { + "grant_type": "client_credentials" + } + + def perform_auth(self): + token_url = self.token_url + token_data = self.get_token_data() + token_headers = self.get_token_headers() + r = requests.post(token_url, data=token_data, headers=token_headers) + if r.status_code not in range(200, 299): + raise Exception("Could not authenticate client.") + # return False + data = r.json() + now = datetime.datetime.now() + access_token = data['access_token'] + expires_in = data['expires_in'] # seconds + expires = now + datetime.timedelta(seconds=expires_in) + self.access_token = access_token + self.access_token_expires = expires + self.access_token_did_expire = expires < now + return True + + def get_access_token(self): + token = self.access_token + expires = self.access_token_expires + now = datetime.datetime.now() + if expires < now: + self.perform_auth() + return self.get_access_token() + elif token == None: + self.perform_auth() + return self.get_access_token() + return token + + def get_resource_header(self): + access_token = self.get_access_token() + headers = { + "Authorization": f"Bearer {access_token}" + } + return headers + + def getPlayTracks(self): + playlist_id = info_imp.datinho['sp_playlist_id'] + endpoint = f"https://api.spotify.com/v1/playlists/{playlist_id}/tracks" + access_token = self.get_access_token() + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/x-www-form-urlencoded" + } + r = requests.get(endpoint, headers=headers) + return r.json() + +