it does birds now
parent
a3700d588c
commit
186780ac25
|
@ -5,3 +5,4 @@
|
|||
/trivia.questions
|
||||
/trivia.scores
|
||||
/config.json
|
||||
/brids.urls
|
||||
|
|
128
main.py
128
main.py
|
@ -1,3 +1,19 @@
|
|||
# {
|
||||
# 'speciesCode': 'dowwoo',
|
||||
# 'comName': 'Downy Woodpecker',
|
||||
# 'sciName': 'Dryobates pubescens',
|
||||
# 'locId': 'L36986367',
|
||||
# 'locName': 'Home',
|
||||
# 'obsDt': '2024-12-14 17:06',
|
||||
# 'howMany': 1,
|
||||
# 'lat': 36.0006572,
|
||||
# 'lng': -95.0865753,
|
||||
# 'obsValid': True,
|
||||
# 'obsReviewed': False,
|
||||
# 'locationPrivate': True,
|
||||
# 'subId': 'S205413945'
|
||||
# }
|
||||
|
||||
from random import choice
|
||||
import requests
|
||||
from time import sleep
|
||||
|
@ -15,7 +31,7 @@ host = "localhost"
|
|||
port = 6667
|
||||
nick = config["nick"]
|
||||
realname = "a bot by ~nebula"
|
||||
helptext = "!trivia, !trscores, !aitrivia, !aiscores for trivia game. contact ~nebula for help, feedback or problem reports. https://git.tilde.town/nebula/mysterious_cube"
|
||||
helptext = "!birds, !trivia, !trscores, !aitrivia, !aiscores. contact ~nebula for help, feedback or problem reports. https://git.tilde.town/nebula/mysterious_cube"
|
||||
channels = config["channels"]
|
||||
|
||||
channel_re = re.compile(r"PRIVMSG (#*\w+)")
|
||||
|
@ -28,12 +44,23 @@ llama_headers = {
|
|||
"Authorization": config["llama_key"]
|
||||
}
|
||||
|
||||
geonames_url = "http://api.geonames.org/searchJSON"
|
||||
geonames_user = config["geonames_user"]
|
||||
|
||||
ebird_url = "https://api.ebird.org/v2/data/obs/geo/recent"
|
||||
ebird_key = config["ebird_key"]
|
||||
|
||||
google_url = "https://customsearch.googleapis.com/customsearch/v1"
|
||||
google_key = config["google_key"]
|
||||
google_cx = config["google_cx"]
|
||||
|
||||
trivia_questions_file = "trivia.questions"
|
||||
trivia_state_file = "trivia.state"
|
||||
trivia_score_file = "trivia.scores"
|
||||
trivia_unselected_file = "trivia.unselected"
|
||||
ai_state_file = "trivia.aistate"
|
||||
ai_score_file = "trivia.aiscores"
|
||||
bird_url_file = "brids.urls"
|
||||
|
||||
try:
|
||||
with open(trivia_questions_file, "r") as f:
|
||||
|
@ -71,6 +98,12 @@ try:
|
|||
except FileNotFoundError:
|
||||
ai_scores = {}
|
||||
|
||||
try:
|
||||
with open(bird_url_file, "r") as f:
|
||||
bird_urls = load(f)
|
||||
except FileNotFoundError:
|
||||
bird_urls = {}
|
||||
|
||||
def write_state():
|
||||
with open(trivia_state_file, "w") as f:
|
||||
dump(trivia_state, f)
|
||||
|
@ -82,6 +115,68 @@ def write_state():
|
|||
dump(ai_scores, f)
|
||||
with open(ai_state_file, "w") as f:
|
||||
dump(ai_state, f)
|
||||
with open(bird_url_file, "w") as f:
|
||||
dump(bird_urls, f)
|
||||
|
||||
def get_location(query):
|
||||
params = {
|
||||
"username": geonames_user,
|
||||
"q": query,
|
||||
"maxRows": 1
|
||||
}
|
||||
try:
|
||||
response = requests.get(geonames_url, params=params)
|
||||
data = response.json()["geonames"][0]
|
||||
if "lat" not in data:
|
||||
return None
|
||||
else:
|
||||
return data
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def cache_bird_url(sciName):
|
||||
global bird_urls
|
||||
if sciName in bird_urls.keys():
|
||||
return bird_urls[sciName]
|
||||
search = requests.get(google_url, params={
|
||||
"q": sciName,
|
||||
"key": google_key,
|
||||
"cx": google_cx
|
||||
})
|
||||
data = search.json()
|
||||
try:
|
||||
link = data["items"][0]["link"]
|
||||
bird_urls[sciName] = link
|
||||
write_state()
|
||||
return link
|
||||
except (IndexError, KeyError):
|
||||
return None
|
||||
|
||||
def get_birds(location):
|
||||
params = {
|
||||
"key": ebird_key,
|
||||
"dist": 50,
|
||||
"lat": location["lat"],
|
||||
"lng": location["lng"]
|
||||
}
|
||||
request = requests.get(ebird_url, params=params)
|
||||
data = request.json()[:4]
|
||||
line = f"Location: {location['name']}; "
|
||||
for sighting in data:
|
||||
url = cache_bird_url(sighting['sciName']).rstrip("/id")
|
||||
line += f"{sighting['comName']} [ {url} ]; "
|
||||
return line.rstrip("; ")
|
||||
|
||||
def post_birds(channel, username, arguments):
|
||||
if not arguments:
|
||||
return "Posts recently sighted birds. Give a location name with this command, eg !birds Dodge City, KS"
|
||||
location = get_location(arguments)
|
||||
if not location:
|
||||
return f"No data found for {arguments}"
|
||||
birds = get_birds(location)
|
||||
if not birds:
|
||||
return f"No data found for {arguments}"
|
||||
return birds
|
||||
|
||||
def get_question(ai_enabled=False):
|
||||
global trivia_questions
|
||||
|
@ -274,7 +369,9 @@ class IRCBot():
|
|||
self.sendline(f"JOIN {channel}")
|
||||
|
||||
def sendline(self, line):
|
||||
return self.s.send(bytes(f"{line}\r\n", "UTF-8"))
|
||||
if line:
|
||||
return self.s.send(bytes(f"{line}\r\n", "UTF-8"))
|
||||
return None
|
||||
|
||||
def send(self, channel, content):
|
||||
if isinstance(content, list):
|
||||
|
@ -310,22 +407,24 @@ class IRCBot():
|
|||
name = None
|
||||
if name and not channel.startswith("#"):
|
||||
channel = name
|
||||
for command, callback in self.commands:
|
||||
if line.lower().endswith(command):
|
||||
try:
|
||||
arguments = line[line.index(command) + len(command) + 1:]
|
||||
except (IndexError, ValueError):
|
||||
arguments = None
|
||||
result = callback(channel, name, arguments)
|
||||
if result:
|
||||
self.send(channel, result)
|
||||
try:
|
||||
message_body = line[line.index(" :") + 2:]
|
||||
except (IndexError, ValueError):
|
||||
message_body = ""
|
||||
if message_body:
|
||||
for callback in self.searchers:
|
||||
callback(message_body)
|
||||
result = callback(message_body)
|
||||
if result:
|
||||
self.send(channel, result)
|
||||
for command, callback in self.commands:
|
||||
if message_body.lower().startswith(command):
|
||||
try:
|
||||
arguments = line[line.index(command) + len(command) + 1:]
|
||||
except (IndexError, ValueError):
|
||||
arguments = None
|
||||
result = callback(channel, name, arguments)
|
||||
if result:
|
||||
self.send(channel, result)
|
||||
|
||||
def run():
|
||||
bot = IRCBot(
|
||||
|
@ -335,6 +434,7 @@ def run():
|
|||
[ # endswith commands
|
||||
("!help", post_help),
|
||||
("!rollcall", post_help),
|
||||
("!birds", post_birds),
|
||||
("!trivia", post_question),
|
||||
("!aitrivia", post_ai_question),
|
||||
("!trscores", post_top_scores),
|
||||
|
@ -354,5 +454,5 @@ def run():
|
|||
sleep(0.5)
|
||||
bot.command_loop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
# if __name__ == "__main__":
|
||||
# run()
|
||||
|
|
Loading…
Reference in New Issue