Skip to content

Instantly share code, notes, and snippets.

@othercodes
Last active February 15, 2024 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save othercodes/ab221b1259633eec8be0194a596a5b88 to your computer and use it in GitHub Desktop.
Save othercodes/ab221b1259633eec8be0194a596a5b88 to your computer and use it in GitHub Desktop.
Small birthday present in python.
#!/usr/bin/python3
# acceptance criteria:
# - works without installing non-standard py3 modules
# - tested on *nix distros
# func ideas stub:
# DONE: fortune http://www.yerkee.com/api (computers science all)
# cat: hey you have your own! go to othercodes./cat http://thecatapi.com/
# pokemon https://pokeapi.co/ https://pokeapi.co/docsv2/#pokemon
# DONE: 8bit: http://the8bitdrummer.com/ or https://go.twitch.tv/the8bitdrummer !nextstream
# DONE (basic): easter_egg (make me happy|dreamy with youtube playlists management (API) or pulling a list from dropbox (?) with links)
# DONE chuck: http://www.icndb.com/api/ + https://api.chucknorris.io/
# xkcd: https://xkcd.com/json.html
# chatbot https://www.cleverbot.com/api/
# DONE magic 8ball api: magic 8-ball api (seriously, watch interstate 60!! ) https://en.wikipedia.org/wiki/Magic_8-Ball
# skate ipsum http://skateipsum.com/get/3/1/JSON
# java jokes?
# DONE: happy_bday: freedom + stuff
import requests
import json
import random
import webbrowser
from html.parser import HTMLParser
# 8ball answers list, 50% yes, 25% maybe, 25% no
EIGHT_BALL_OPTIONS_EN = ['It is certain', 'It is decidedly so', 'Without a doubt', 'Yes definitely', 'You may rely on it', 'As I see it, yes', 'Most likely', 'Outlook good', 'Yes', 'Signs point to yes', 'Reply hazy try again', 'Ask again later', 'Better not tell you now', 'Cannot predict now', 'Concentrate and ask again', 'Don\'t count on it', 'My reply is no', 'My sources say no', 'Outlook not so good', 'Very doubtful']
EIGHT_BALL_OPTIONS_ES = ['En mi opinión, sí', 'Es cierto', 'Es decididamente así', 'Probablemente', 'Buen pronóstico', 'Todo apunta a que sí', 'Sin duda', 'Sí', 'Sí - definitivamente', 'Debes confiar en ello', 'Respuesta vaga, vuelve a intentarlo', 'Pregunta en otro momento', 'Será mejor que no te lo diga ahora', 'No puedo predecirlo ahora', 'Concéntrate y vuelve a preguntar', 'No cuentes con ello', 'Mi respuesta es no', 'Mis fuentes me dicen que no', 'Las perspectivas no son buenas', 'Muy dudoso']
# URLs for APIs
FORTUNE_URL = 'http://www.yerkee.com/api/fortune/'
CHUCK_URL1 = 'https://api.chucknorris.io/jokes/random'
CHUCK_URL2 = 'http://api.icndb.com/jokes/random'
EASTER_EGG_URL = 'https://www.dropbox.com/s/1y3mcsxr2tik4vb/youtube_vids.json?dl=1'
class JerodParser(HTMLParser, object):
'''
Extending HTMLParser to override handle_data() and handle_starttag()
problem: HTMLParser does not allow getting data in the specific node
solution: for each node parent methods are called, it we find the tag we can flag the node:
next call to handle_data() will process the node
'''
def __init__(self):
super(JerodParser, self).__init__()
# used to flag the node where we need to process content
self.flag = False
def handle_data(self, data):
'''
method to look for data within tags
<h4 class="text-xs-center">[Next Stream Tuesday 31st at 16:30 EDT] Use !nextstream for a countdown! Drumstream!!!</h4></div>
TODO: will break after page structure changes
UPD: it broke :( current format doesn't use 'Next Stream' substring
'''
# in previous call to handle_starttag() we found h4 class='text-xs-center' so the flag is set to True
if self.flag:
# stripping leading and trailing whitespaces
print("Found next stream info: %s" % data.strip())
self.flag = False
def handle_starttag(self, tag, attributes):
# searching for h4 class='text-xs-center'
if tag != 'h4':
return
if attributes[0][1] == 'text-xs-center':
self.flag = True
def happy_bday():
# bah, no pretty printing
print("-->8--\nHappy 11101th birthday!\n\nNot going to wish stuff bla-bla-bla, just going to say this:\nThere are no limits to who you can be. \nFind yourself.\nTrust yourself.\nFind something that you love doing so much that you cannot stop. And then get good at it :)\n\nhttps://www.youtube.com/watch?v=LlY90lG_Fuw\n--8<--")
def fortune(request):
args = request.split()
# fortune type is passed
if len(args) == 2:
# fortune computers|science|all
if args[1] in ['computers', 'science', 'all']:
url = FORTUNE_URL + args[1]
else:
print("Sorry, I don't recognize the fortune type...")
return
else:
# we gracefully proceed if args != 2
fortune_type = input("What kind of fortune do you want? [computers|science|all]\n==>")
if fortune_type in ['computers', 'science', 'all']:
url = FORTUNE_URL + fortune_type
else:
print("Sorry, I don't recognize this fortune type, here is a random fortune cookie for you:\n")
url = FORTUNE_URL + 'all'
response = requests.get(url)
fortune = json.loads(response.text)
print(fortune['fortune'])
def eight_bit():
page = requests.get('http://the8bitdrummer.com/')
page_parser = JerodParser()
page_parser.feed(page.text)
page_parser.close()
def eight_ball():
q = input("Ask me a YES/NO question. Careful, you may not like the answer...\n==>")
print(random.choice(EIGHT_BALL_OPTIONS_EN))
def chuck1(joke_type = None):
if joke_type == 'geek':
url = CHUCK_URL1 + '?category=dev'
elif joke_type == 'nsfw':
url = CHUCK_URL1 + '?category=explicit'
else:
print("Bah, here is a random Chucky for you:")
url = CHUCK_URL1
response = requests.get(url)
joke = json.loads(response.text)
print(joke['value'])
def chuck2(joke_type = None):
if joke_type == 'geek':
url = CHUCK_URL2 + '?limitTo=[nerdy]'
elif joke_type == 'nsfw':
url = CHUCK_URL2 + '?limitTo=[explicit]'
else:
print("Bah, here is a random Chucky for you:")
url = CHUCK_URL2
response = requests.get(url)
joke = json.loads(response.text)
print(joke['value']['joke'])
def chuck(request):
'''
gets Chuck Norris jokes: geek|nsfw
'''
# there are 2 sources of jokes, parsers have to be different
args = request.split()
# joke type is passed
if len(args) == 2:
if args[1] in ['geek', 'nsfw', 'all']:
random.choice([chuck1, chuck2])(args[1])
else:
print("Sorry, I don't recognize the joke type...")
# we gracefully proceed if args != 2
else:
joke_type = input("What kind of joke do you want? [geek|nsfw|all]\n==>")
if joke_type in ['geek', 'nsfw', 'all']:
random.choice([chuck1, chuck2])(joke_type)
else:
print("Sorry I don't recognize this joke type, here is a random fortune cookie:\n")
random.choice([chuck1, chuck2])()
def play_youtube(request):
args = request.split()
if len(args) != 2:
print("You need to pass the category")
return
response = requests.get(EASTER_EGG_URL)
data = json.loads(response.text)
try:
category = data[args[1]]
except KeyError:
print("Sorry, category %s is not found." % args[1])
return
webbrowser.open('https://www.youtube.com/watch?v=%s' % random.choice(category), new = 2)
def main():
while True:
request = input("\n.\n..\n...\nWhat do you want? [fortune|8bit|8ball|chuck|help|quit]\n=>")
if request in ('q', 'quit'):
break
elif 'help' in request:
print("Come onnnn, what's the fun in reading help? Explore.")
elif 'fortune' in request:
fortune(request)
elif '8bit' == request:
eight_bit()
elif '8ball' in request:
eight_ball()
elif 'chuck' in request:
chuck(request)
elif 'make_me' in request:
play_youtube(request)
else:
print("Option not recognized, try again.")
if __name__ == "__main__":
main()
happy_bday()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment