marvin_actions
Make actions for Marvin, one function for each action.
1#! /usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4""" 5Make actions for Marvin, one function for each action. 6""" 7from urllib.parse import quote_plus 8import calendar 9import datetime 10import json 11import logging 12import random 13import requests 14 15 16LOG = logging.getLogger("action") 17 18def getAllActions(): 19 """ 20 Return all actions in an array. 21 """ 22 return [ 23 marvinExplainShell, 24 marvinGoogle, 25 marvinLunch, 26 marvinVideoOfToday, 27 marvinWhoIs, 28 marvinHelp, 29 marvinSource, 30 marvinBudord, 31 marvinQuote, 32 marvinWeather, 33 marvinSun, 34 marvinSayHi, 35 marvinSmile, 36 marvinStrip, 37 marvinTimeToBBQ, 38 marvinNameday, 39 marvinUptime, 40 marvinStream, 41 marvinPrinciple, 42 marvinJoke, 43 marvinCommit 44 ] 45 46 47# Load all strings from file 48with open("marvin_strings.json", encoding="utf-8") as f: 49 STRINGS = json.load(f) 50 51 52def getString(key, key1=None): 53 """ 54 Get a string from the string database. 55 """ 56 data = STRINGS[key] 57 if isinstance(data, list): 58 res = data[random.randint(0, len(data) - 1)] 59 elif isinstance(data, dict): 60 if key1 is None: 61 res = data 62 else: 63 res = data[key1] 64 if isinstance(res, list): 65 res = res[random.randint(0, len(res) - 1)] 66 elif isinstance(data, str): 67 res = data 68 else: 69 raise ValueError("Unsupported datatype in strings.json") 70 71 return res 72 73 74def marvinSmile(row): 75 """ 76 Make Marvin smile. 77 """ 78 msg = None 79 if any(r in row for r in ["smile", "le", "skratta", "smilies"]): 80 msg = getString("smile") 81 return msg 82 83 84def wordsAfterKeyWords(words, keyWords): 85 """ 86 Return all items in the words list after the first occurence 87 of an item in the keyWords list. 88 """ 89 kwIndex = [] 90 for kw in keyWords: 91 if kw in words: 92 kwIndex.append(words.index(kw)) 93 94 if not kwIndex: 95 return None 96 97 return words[min(kwIndex)+1:] 98 99 100def marvinGoogle(row): 101 """ 102 Let Marvin present an url to google. 103 """ 104 query = wordsAfterKeyWords(row, ["google", "googla"]) 105 if not query: 106 return None 107 108 searchStr = " ".join(query) 109 url = "https://www.google.se/search?q=" 110 url += quote_plus(searchStr) 111 msg = getString("google") 112 return msg.format(url) 113 114 115def marvinExplainShell(row): 116 """ 117 Let Marvin present an url to the service explain shell to 118 explain a shell command. 119 """ 120 query = wordsAfterKeyWords(row, ["explain", "förklara"]) 121 if not query: 122 return None 123 cmd = " ".join(query) 124 url = "https://explainshell.com/explain?cmd=" 125 url += quote_plus(cmd, "/:") 126 msg = getString("explainShell") 127 return msg.format(url) 128 129 130def marvinSource(row): 131 """ 132 State message about sourcecode. 133 """ 134 msg = None 135 if any(r in row for r in ["källkod", "source"]): 136 msg = getString("source") 137 138 return msg 139 140 141def marvinBudord(row): 142 """ 143 What are the budord for Marvin? 144 """ 145 msg = None 146 if any(r in row for r in ["budord", "stentavla"]): 147 if any(r in row for r in ["#1", "1"]): 148 msg = getString("budord", "#1") 149 elif any(r in row for r in ["#2", "2"]): 150 msg = getString("budord", "#2") 151 elif any(r in row for r in ["#3", "3"]): 152 msg = getString("budord", "#3") 153 elif any(r in row for r in ["#4", "4"]): 154 msg = getString("budord", "#4") 155 elif any(r in row for r in ["#5", "5"]): 156 msg = getString("budord", "#5") 157 158 return msg 159 160 161def marvinQuote(row): 162 """ 163 Make a quote. 164 """ 165 msg = None 166 if any(r in row for r in ["quote", "citat", "filosofi", "filosofera"]): 167 msg = getString("hitchhiker") 168 169 return msg 170 171 172def videoOfToday(): 173 """ 174 Check what day it is and provide a url to a suitable video together with a greeting. 175 """ 176 weekday = datetime.date.today().strftime("%A") 177 day = getString("video-of-today", weekday) 178 msg = day.get("message") 179 180 if day: 181 msg += " En passande video är " + day.get("url") 182 else: 183 msg += " Jag har ännu ingen passande video för denna dagen." 184 185 return msg 186 187 188def marvinVideoOfToday(row): 189 """ 190 Show the video of today. 191 """ 192 msg = None 193 if any(r in row for r in ["idag", "dagens"]): 194 if any(r in row for r in ["video", "youtube", "tube"]): 195 msg = videoOfToday() 196 197 return msg 198 199 200def marvinWhoIs(row): 201 """ 202 Who is Marvin. 203 """ 204 msg = None 205 if all(r in row for r in ["vem", "är"]): 206 msg = getString("whois") 207 208 return msg 209 210 211def marvinHelp(row): 212 """ 213 Provide a menu. 214 """ 215 msg = None 216 if any(r in row for r in ["hjälp", "help", "menu", "meny"]): 217 msg = getString("menu") 218 219 return msg 220 221 222def marvinSayHi(row): 223 """ 224 Say hi with a nice message. 225 """ 226 msg = None 227 if any(r in row for r in [ 228 "snälla", "hej", "tjena", "morsning", "morrn", "mår", "hallå", 229 "halloj", "läget", "snäll", "duktig", "träna", "träning", 230 "utbildning", "tack", "tacka", "tackar", "tacksam" 231 ]): 232 smile = getString("smile") 233 hello = getString("hello") 234 friendly = getString("friendly") 235 msg = f"{smile} {hello} {friendly}" 236 237 return msg 238 239 240def marvinLunch(row): 241 """ 242 Help decide where to eat. 243 """ 244 lunchOptions = { 245 'stan centrum karlskrona kna': 'karlskrona', 246 'ängelholm angelholm engelholm': 'angelholm', 247 'hässleholm hassleholm': 'hassleholm', 248 'malmö malmo malmoe': 'malmo', 249 'göteborg goteborg gbg': 'goteborg' 250 } 251 252 data = getString("lunch") 253 254 if any(r in row for r in ["lunch", "mat", "äta", "luncha"]): 255 places = data.get("location").get("bth") 256 for keys, value in lunchOptions.items(): 257 if any(r in row for r in keys.split(" ")): 258 places = data.get("location").get(value) 259 260 lunchStr = getString("lunch", "message") 261 return lunchStr.format(places[random.randint(0, len(places) - 1)]) 262 263 return None 264 265 266def marvinSun(row): 267 """ 268 Check when the sun goes up and down. 269 """ 270 msg = None 271 if any(r in row for r in ["sol", "solen", "solnedgång", "soluppgång", "sun"]): 272 try: 273 url = getString("sun", "url") 274 r = requests.get(url, timeout=5) 275 sundata = r.json() 276 # Formats the time from the response to HH:mm instead of hh:mm:ss 277 sunrise = sundata["results"]["sunrise"].split()[0][:-3] 278 sunset = sundata["results"]["sunset"].split()[0][:-3] 279 # The api uses AM/PM notation, this converts the sunset to 12 hour time 280 sunsetHour = int(sunset.split(":")[0]) + 12 281 sunset = str(sunsetHour) + sunset[-3:] 282 msg = getString("sun", "msg").format(sunrise, sunset) 283 return msg 284 285 except Exception as e: 286 LOG.error("Failed to get sun times: %s", e) 287 return getString("sun", "error") 288 289 return msg 290 291 292def marvinWeather(row): 293 """ 294 Check what the weather prognosis looks like. 295 """ 296 msg = "" 297 if any(r in row for r in ["väder", "vädret", "prognos", "prognosen", "smhi"]): 298 forecast = "" 299 observation = "" 300 301 try: 302 station_req = requests.get(getString("smhi", "station_url"), timeout=5) 303 weather_code:int = int(station_req.json().get("value")[0].get("value")) 304 305 weather_codes_req = requests.get(getString("smhi", "weather_codes_url"), timeout=5) 306 weather_codes_arr: list = weather_codes_req.json().get("entry") 307 308 current_weather_req = requests.get(getString("smhi", "current_weather_url"), timeout=5) 309 current_w_data: list = current_weather_req.json().get("timeSeries")[0].get("parameters") 310 311 for curr_w in current_w_data: 312 if curr_w.get("name") == "t": 313 forecast = curr_w.get("values")[0] 314 315 for code in weather_codes_arr: 316 if code.get("key") == weather_code: 317 observation = code.get("value") 318 319 msg = f"Karlskrona just nu: {forecast} °C. {observation}." 320 321 except Exception as e: 322 LOG.error("Failed to get weather: %s", e) 323 msg: str = getString("smhi", "failed") 324 325 return msg 326 327 328def marvinStrip(row): 329 """ 330 Get a comic strip. 331 """ 332 msg = None 333 if any(r in row for r in ["strip", "comic", "nöje", "paus"]): 334 msg = commitStrip(randomize=any(r in row for r in ["rand", "random", "slump", "lucky"])) 335 return msg 336 337 338def commitStrip(randomize=False): 339 """ 340 Latest or random comic strip from CommitStrip. 341 """ 342 msg = getString("commitstrip", "message") 343 344 if randomize: 345 first = getString("commitstrip", "first") 346 last = getString("commitstrip", "last") 347 rand = random.randint(first, last) 348 url = getString("commitstrip", "urlPage") + str(rand) 349 else: 350 url = getString("commitstrip", "url") 351 352 return msg.format(url=url) 353 354 355def marvinTimeToBBQ(row): 356 """ 357 Calcuate the time to next barbecue and print a appropriate msg 358 """ 359 msg = None 360 if any(r in row for r in ["grilla", "grill", "grillcon", "bbq"]): 361 url = getString("barbecue", "url") 362 nextDate = nextBBQ() 363 today = datetime.date.today() 364 daysRemaining = (nextDate - today).days 365 366 if daysRemaining == 0: 367 msg = getString("barbecue", "today") 368 elif daysRemaining == 1: 369 msg = getString("barbecue", "tomorrow") 370 elif 1 < daysRemaining < 14: 371 msg = getString("barbecue", "week") % nextDate 372 elif 14 < daysRemaining < 200: 373 msg = getString("barbecue", "base") % nextDate 374 else: 375 msg = getString("barbecue", "eternity") % nextDate 376 377 msg = url + ". " + msg 378 return msg 379 380def nextBBQ(): 381 """ 382 Calculate the next grillcon date after today 383 """ 384 385 MAY = 5 386 SEPTEMBER = 9 387 388 after = datetime.date.today() 389 spring = thirdFridayIn(after.year, MAY) 390 if after <= spring: 391 return spring 392 393 autumn = thirdFridayIn(after.year, SEPTEMBER) 394 if after <= autumn: 395 return autumn 396 397 return thirdFridayIn(after.year + 1, MAY) 398 399 400def thirdFridayIn(y, m): 401 """ 402 Get the third Friday in a given month and year 403 """ 404 THIRD = 2 405 FRIDAY = -1 406 407 # Start the weeks on saturday to prevent fridays from previous month 408 cal = calendar.Calendar(firstweekday=calendar.SATURDAY) 409 410 # Return the friday in the third week 411 return cal.monthdatescalendar(y, m)[THIRD][FRIDAY] 412 413 414def marvinNameday(row): 415 """ 416 Check current nameday 417 """ 418 msg = None 419 if any(r in row for r in ["nameday", "namnsdag"]): 420 try: 421 now = datetime.datetime.now() 422 raw_url = "https://api.dryg.net/dagar/v2.1/{year}/{month}/{day}" 423 url = raw_url.format(year=now.year, month=now.month, day=now.day) 424 r = requests.get(url, timeout=5) 425 nameday_data = r.json() 426 names = nameday_data["dagar"][0]["namnsdag"] 427 parsed_names = formatNames(names) 428 if names: 429 msg = getString("nameday", "somebody").format(parsed_names) 430 else: 431 msg = getString("nameday", "nobody") 432 except Exception as e: 433 LOG.error("Failed to get nameday: %s", e) 434 msg = getString("nameday", "error") 435 return msg 436 437def formatNames(names): 438 """ 439 Parses namedata from nameday API 440 """ 441 if len(names) > 1: 442 return " och ".join([", ".join(names[:-1])] + names[-1:]) 443 return "".join(names) 444 445def marvinUptime(row): 446 """ 447 Display info about uptime tournament 448 """ 449 msg = None 450 if "uptime" in row: 451 msg = getString("uptime", "info") 452 return msg 453 454def marvinStream(row): 455 """ 456 Display info about stream 457 """ 458 msg = None 459 if any(r in row for r in ["stream", "streama", "ström", "strömma"]): 460 msg = getString("stream", "info") 461 return msg 462 463def marvinPrinciple(row): 464 """ 465 Display one selected software principle, or provide one as random 466 """ 467 msg = None 468 if any(r in row for r in ["principle", "princip", "principer"]): 469 principles = getString("principle") 470 principleKeys = list(principles.keys()) 471 matchedKeys = [k for k in row if k in principleKeys] 472 if matchedKeys: 473 msg = principles[matchedKeys.pop()] 474 else: 475 msg = principles[random.choice(principleKeys)] 476 return msg 477 478def getJoke(): 479 """ 480 Retrieves joke from api.chucknorris.io/jokes/random?category=dev 481 """ 482 try: 483 url = getString("joke", "url") 484 r = requests.get(url, timeout=5) 485 joke_data = r.json() 486 return joke_data["value"] 487 except Exception as e: 488 LOG.error("Failed to get joke: %s", e) 489 return getString("joke", "error") 490 491def marvinJoke(row): 492 """ 493 Display a random Chuck Norris joke 494 """ 495 msg = None 496 if any(r in row for r in ["joke", "skämt", "chuck norris", "chuck", "norris"]): 497 msg = getJoke() 498 return msg 499 500def getCommit(): 501 """ 502 Retrieves random commit message from whatthecommit.com/index.html 503 """ 504 try: 505 url = getString("commit", "url") 506 r = requests.get(url, timeout=5) 507 res = r.text.strip() 508 msg = f"Använd detta meddelandet: '{res}'" 509 return msg 510 except Exception as e: 511 LOG.error("Failed to get commit message: %s", e) 512 return getString("commit", "error") 513 514def marvinCommit(row): 515 """ 516 Display a random commit message 517 """ 518 msg = None 519 if any(r in row for r in ["commit", "-m"]): 520 msg = getCommit() 521 return msg
19def getAllActions(): 20 """ 21 Return all actions in an array. 22 """ 23 return [ 24 marvinExplainShell, 25 marvinGoogle, 26 marvinLunch, 27 marvinVideoOfToday, 28 marvinWhoIs, 29 marvinHelp, 30 marvinSource, 31 marvinBudord, 32 marvinQuote, 33 marvinWeather, 34 marvinSun, 35 marvinSayHi, 36 marvinSmile, 37 marvinStrip, 38 marvinTimeToBBQ, 39 marvinNameday, 40 marvinUptime, 41 marvinStream, 42 marvinPrinciple, 43 marvinJoke, 44 marvinCommit 45 ]
Return all actions in an array.
53def getString(key, key1=None): 54 """ 55 Get a string from the string database. 56 """ 57 data = STRINGS[key] 58 if isinstance(data, list): 59 res = data[random.randint(0, len(data) - 1)] 60 elif isinstance(data, dict): 61 if key1 is None: 62 res = data 63 else: 64 res = data[key1] 65 if isinstance(res, list): 66 res = res[random.randint(0, len(res) - 1)] 67 elif isinstance(data, str): 68 res = data 69 else: 70 raise ValueError("Unsupported datatype in strings.json") 71 72 return res
Get a string from the string database.
75def marvinSmile(row): 76 """ 77 Make Marvin smile. 78 """ 79 msg = None 80 if any(r in row for r in ["smile", "le", "skratta", "smilies"]): 81 msg = getString("smile") 82 return msg
Make Marvin smile.
85def wordsAfterKeyWords(words, keyWords): 86 """ 87 Return all items in the words list after the first occurence 88 of an item in the keyWords list. 89 """ 90 kwIndex = [] 91 for kw in keyWords: 92 if kw in words: 93 kwIndex.append(words.index(kw)) 94 95 if not kwIndex: 96 return None 97 98 return words[min(kwIndex)+1:]
Return all items in the words list after the first occurence of an item in the keyWords list.
101def marvinGoogle(row): 102 """ 103 Let Marvin present an url to google. 104 """ 105 query = wordsAfterKeyWords(row, ["google", "googla"]) 106 if not query: 107 return None 108 109 searchStr = " ".join(query) 110 url = "https://www.google.se/search?q=" 111 url += quote_plus(searchStr) 112 msg = getString("google") 113 return msg.format(url)
Let Marvin present an url to google.
116def marvinExplainShell(row): 117 """ 118 Let Marvin present an url to the service explain shell to 119 explain a shell command. 120 """ 121 query = wordsAfterKeyWords(row, ["explain", "förklara"]) 122 if not query: 123 return None 124 cmd = " ".join(query) 125 url = "https://explainshell.com/explain?cmd=" 126 url += quote_plus(cmd, "/:") 127 msg = getString("explainShell") 128 return msg.format(url)
Let Marvin present an url to the service explain shell to explain a shell command.
131def marvinSource(row): 132 """ 133 State message about sourcecode. 134 """ 135 msg = None 136 if any(r in row for r in ["källkod", "source"]): 137 msg = getString("source") 138 139 return msg
State message about sourcecode.
142def marvinBudord(row): 143 """ 144 What are the budord for Marvin? 145 """ 146 msg = None 147 if any(r in row for r in ["budord", "stentavla"]): 148 if any(r in row for r in ["#1", "1"]): 149 msg = getString("budord", "#1") 150 elif any(r in row for r in ["#2", "2"]): 151 msg = getString("budord", "#2") 152 elif any(r in row for r in ["#3", "3"]): 153 msg = getString("budord", "#3") 154 elif any(r in row for r in ["#4", "4"]): 155 msg = getString("budord", "#4") 156 elif any(r in row for r in ["#5", "5"]): 157 msg = getString("budord", "#5") 158 159 return msg
What are the budord for Marvin?
162def marvinQuote(row): 163 """ 164 Make a quote. 165 """ 166 msg = None 167 if any(r in row for r in ["quote", "citat", "filosofi", "filosofera"]): 168 msg = getString("hitchhiker") 169 170 return msg
Make a quote.
173def videoOfToday(): 174 """ 175 Check what day it is and provide a url to a suitable video together with a greeting. 176 """ 177 weekday = datetime.date.today().strftime("%A") 178 day = getString("video-of-today", weekday) 179 msg = day.get("message") 180 181 if day: 182 msg += " En passande video är " + day.get("url") 183 else: 184 msg += " Jag har ännu ingen passande video för denna dagen." 185 186 return msg
Check what day it is and provide a url to a suitable video together with a greeting.
189def marvinVideoOfToday(row): 190 """ 191 Show the video of today. 192 """ 193 msg = None 194 if any(r in row for r in ["idag", "dagens"]): 195 if any(r in row for r in ["video", "youtube", "tube"]): 196 msg = videoOfToday() 197 198 return msg
Show the video of today.
201def marvinWhoIs(row): 202 """ 203 Who is Marvin. 204 """ 205 msg = None 206 if all(r in row for r in ["vem", "är"]): 207 msg = getString("whois") 208 209 return msg
Who is Marvin.
212def marvinHelp(row): 213 """ 214 Provide a menu. 215 """ 216 msg = None 217 if any(r in row for r in ["hjälp", "help", "menu", "meny"]): 218 msg = getString("menu") 219 220 return msg
Provide a menu.
223def marvinSayHi(row): 224 """ 225 Say hi with a nice message. 226 """ 227 msg = None 228 if any(r in row for r in [ 229 "snälla", "hej", "tjena", "morsning", "morrn", "mår", "hallå", 230 "halloj", "läget", "snäll", "duktig", "träna", "träning", 231 "utbildning", "tack", "tacka", "tackar", "tacksam" 232 ]): 233 smile = getString("smile") 234 hello = getString("hello") 235 friendly = getString("friendly") 236 msg = f"{smile} {hello} {friendly}" 237 238 return msg
Say hi with a nice message.
241def marvinLunch(row): 242 """ 243 Help decide where to eat. 244 """ 245 lunchOptions = { 246 'stan centrum karlskrona kna': 'karlskrona', 247 'ängelholm angelholm engelholm': 'angelholm', 248 'hässleholm hassleholm': 'hassleholm', 249 'malmö malmo malmoe': 'malmo', 250 'göteborg goteborg gbg': 'goteborg' 251 } 252 253 data = getString("lunch") 254 255 if any(r in row for r in ["lunch", "mat", "äta", "luncha"]): 256 places = data.get("location").get("bth") 257 for keys, value in lunchOptions.items(): 258 if any(r in row for r in keys.split(" ")): 259 places = data.get("location").get(value) 260 261 lunchStr = getString("lunch", "message") 262 return lunchStr.format(places[random.randint(0, len(places) - 1)]) 263 264 return None
Help decide where to eat.
267def marvinSun(row): 268 """ 269 Check when the sun goes up and down. 270 """ 271 msg = None 272 if any(r in row for r in ["sol", "solen", "solnedgång", "soluppgång", "sun"]): 273 try: 274 url = getString("sun", "url") 275 r = requests.get(url, timeout=5) 276 sundata = r.json() 277 # Formats the time from the response to HH:mm instead of hh:mm:ss 278 sunrise = sundata["results"]["sunrise"].split()[0][:-3] 279 sunset = sundata["results"]["sunset"].split()[0][:-3] 280 # The api uses AM/PM notation, this converts the sunset to 12 hour time 281 sunsetHour = int(sunset.split(":")[0]) + 12 282 sunset = str(sunsetHour) + sunset[-3:] 283 msg = getString("sun", "msg").format(sunrise, sunset) 284 return msg 285 286 except Exception as e: 287 LOG.error("Failed to get sun times: %s", e) 288 return getString("sun", "error") 289 290 return msg
Check when the sun goes up and down.
293def marvinWeather(row): 294 """ 295 Check what the weather prognosis looks like. 296 """ 297 msg = "" 298 if any(r in row for r in ["väder", "vädret", "prognos", "prognosen", "smhi"]): 299 forecast = "" 300 observation = "" 301 302 try: 303 station_req = requests.get(getString("smhi", "station_url"), timeout=5) 304 weather_code:int = int(station_req.json().get("value")[0].get("value")) 305 306 weather_codes_req = requests.get(getString("smhi", "weather_codes_url"), timeout=5) 307 weather_codes_arr: list = weather_codes_req.json().get("entry") 308 309 current_weather_req = requests.get(getString("smhi", "current_weather_url"), timeout=5) 310 current_w_data: list = current_weather_req.json().get("timeSeries")[0].get("parameters") 311 312 for curr_w in current_w_data: 313 if curr_w.get("name") == "t": 314 forecast = curr_w.get("values")[0] 315 316 for code in weather_codes_arr: 317 if code.get("key") == weather_code: 318 observation = code.get("value") 319 320 msg = f"Karlskrona just nu: {forecast} °C. {observation}." 321 322 except Exception as e: 323 LOG.error("Failed to get weather: %s", e) 324 msg: str = getString("smhi", "failed") 325 326 return msg
Check what the weather prognosis looks like.
329def marvinStrip(row): 330 """ 331 Get a comic strip. 332 """ 333 msg = None 334 if any(r in row for r in ["strip", "comic", "nöje", "paus"]): 335 msg = commitStrip(randomize=any(r in row for r in ["rand", "random", "slump", "lucky"])) 336 return msg
Get a comic strip.
339def commitStrip(randomize=False): 340 """ 341 Latest or random comic strip from CommitStrip. 342 """ 343 msg = getString("commitstrip", "message") 344 345 if randomize: 346 first = getString("commitstrip", "first") 347 last = getString("commitstrip", "last") 348 rand = random.randint(first, last) 349 url = getString("commitstrip", "urlPage") + str(rand) 350 else: 351 url = getString("commitstrip", "url") 352 353 return msg.format(url=url)
Latest or random comic strip from CommitStrip.
356def marvinTimeToBBQ(row): 357 """ 358 Calcuate the time to next barbecue and print a appropriate msg 359 """ 360 msg = None 361 if any(r in row for r in ["grilla", "grill", "grillcon", "bbq"]): 362 url = getString("barbecue", "url") 363 nextDate = nextBBQ() 364 today = datetime.date.today() 365 daysRemaining = (nextDate - today).days 366 367 if daysRemaining == 0: 368 msg = getString("barbecue", "today") 369 elif daysRemaining == 1: 370 msg = getString("barbecue", "tomorrow") 371 elif 1 < daysRemaining < 14: 372 msg = getString("barbecue", "week") % nextDate 373 elif 14 < daysRemaining < 200: 374 msg = getString("barbecue", "base") % nextDate 375 else: 376 msg = getString("barbecue", "eternity") % nextDate 377 378 msg = url + ". " + msg 379 return msg
Calcuate the time to next barbecue and print a appropriate msg
381def nextBBQ(): 382 """ 383 Calculate the next grillcon date after today 384 """ 385 386 MAY = 5 387 SEPTEMBER = 9 388 389 after = datetime.date.today() 390 spring = thirdFridayIn(after.year, MAY) 391 if after <= spring: 392 return spring 393 394 autumn = thirdFridayIn(after.year, SEPTEMBER) 395 if after <= autumn: 396 return autumn 397 398 return thirdFridayIn(after.year + 1, MAY)
Calculate the next grillcon date after today
401def thirdFridayIn(y, m): 402 """ 403 Get the third Friday in a given month and year 404 """ 405 THIRD = 2 406 FRIDAY = -1 407 408 # Start the weeks on saturday to prevent fridays from previous month 409 cal = calendar.Calendar(firstweekday=calendar.SATURDAY) 410 411 # Return the friday in the third week 412 return cal.monthdatescalendar(y, m)[THIRD][FRIDAY]
Get the third Friday in a given month and year
415def marvinNameday(row): 416 """ 417 Check current nameday 418 """ 419 msg = None 420 if any(r in row for r in ["nameday", "namnsdag"]): 421 try: 422 now = datetime.datetime.now() 423 raw_url = "https://api.dryg.net/dagar/v2.1/{year}/{month}/{day}" 424 url = raw_url.format(year=now.year, month=now.month, day=now.day) 425 r = requests.get(url, timeout=5) 426 nameday_data = r.json() 427 names = nameday_data["dagar"][0]["namnsdag"] 428 parsed_names = formatNames(names) 429 if names: 430 msg = getString("nameday", "somebody").format(parsed_names) 431 else: 432 msg = getString("nameday", "nobody") 433 except Exception as e: 434 LOG.error("Failed to get nameday: %s", e) 435 msg = getString("nameday", "error") 436 return msg
Check current nameday
438def formatNames(names): 439 """ 440 Parses namedata from nameday API 441 """ 442 if len(names) > 1: 443 return " och ".join([", ".join(names[:-1])] + names[-1:]) 444 return "".join(names)
Parses namedata from nameday API
446def marvinUptime(row): 447 """ 448 Display info about uptime tournament 449 """ 450 msg = None 451 if "uptime" in row: 452 msg = getString("uptime", "info") 453 return msg
Display info about uptime tournament
455def marvinStream(row): 456 """ 457 Display info about stream 458 """ 459 msg = None 460 if any(r in row for r in ["stream", "streama", "ström", "strömma"]): 461 msg = getString("stream", "info") 462 return msg
Display info about stream
464def marvinPrinciple(row): 465 """ 466 Display one selected software principle, or provide one as random 467 """ 468 msg = None 469 if any(r in row for r in ["principle", "princip", "principer"]): 470 principles = getString("principle") 471 principleKeys = list(principles.keys()) 472 matchedKeys = [k for k in row if k in principleKeys] 473 if matchedKeys: 474 msg = principles[matchedKeys.pop()] 475 else: 476 msg = principles[random.choice(principleKeys)] 477 return msg
Display one selected software principle, or provide one as random
479def getJoke(): 480 """ 481 Retrieves joke from api.chucknorris.io/jokes/random?category=dev 482 """ 483 try: 484 url = getString("joke", "url") 485 r = requests.get(url, timeout=5) 486 joke_data = r.json() 487 return joke_data["value"] 488 except Exception as e: 489 LOG.error("Failed to get joke: %s", e) 490 return getString("joke", "error")
Retrieves joke from api.chucknorris.io/jokes/random?category=dev
492def marvinJoke(row): 493 """ 494 Display a random Chuck Norris joke 495 """ 496 msg = None 497 if any(r in row for r in ["joke", "skämt", "chuck norris", "chuck", "norris"]): 498 msg = getJoke() 499 return msg
Display a random Chuck Norris joke
501def getCommit(): 502 """ 503 Retrieves random commit message from whatthecommit.com/index.html 504 """ 505 try: 506 url = getString("commit", "url") 507 r = requests.get(url, timeout=5) 508 res = r.text.strip() 509 msg = f"Använd detta meddelandet: '{res}'" 510 return msg 511 except Exception as e: 512 LOG.error("Failed to get commit message: %s", e) 513 return getString("commit", "error")
Retrieves random commit message from whatthecommit.com/index.html
515def marvinCommit(row): 516 """ 517 Display a random commit message 518 """ 519 msg = None 520 if any(r in row for r in ["commit", "-m"]): 521 msg = getCommit() 522 return msg
Display a random commit message