class Youtube: APIKEY = dotenv_parser.get_value('.env', 'YOUTUBE_KEY') def __init__(self, timespan=20): self.timespan = timespan self.latest_video = {} self.channels = [ 'UCtI0Hodo5o5dUb67FeUjDeA', ] def _filter(self, text: str) -> bool: if 'Flight Test' in text: return True return False def _go_trough_all_videos(self, channel): out = [] last_time = datetime.datetime.utcnow() - datetime.timedelta( minutes=self.timespan) if channel in self.latest_video: last_time = self.latest_video[channel] data = None try: data = requests.get('https://www.youtube.com/feeds/videos.xml?', {'channel_id': channel}) except: pass if data is None: return None for entry in reversed(xmltodict.parse(data.content)['feed']['entry']): if datetime.datetime.strptime( entry['published'], "%Y-%m-%dT%H:%M:%S%z").replace(tzinfo=None) > last_time: last_time = datetime.datetime.strptime( entry['published'], "%Y-%m-%dT%H:%M:%S%z").replace(tzinfo=None) if self._filter( entry['media:group']['media:title'] ): #print(json.dumps(entry,indent=2,sort_keys=False)) out.append(entry['link']['@href']) self.latest_video[channel] = last_time return out def update(self): out = [] for channel in self.channels: resp = self._go_trough_all_videos(channel) if resp is None: return None out += resp return out
def main(): #daily_update() Database().setup_database() # Initialize logging args = str(sys.argv) if '--testing' in args or '-t' in args: logger = StarshipLogger(level=logging.DEBUG, broadcast=True) try: branch = dotenv_parser.get_value('.env', 'BRANCH') logger.info( 'Starting Starship Flight Updates Bot (TESTING) on branch ' + branch) except ValueError: logger.info('Starting Starship Flight Updates Bot (TESTING)') else: logger = StarshipLogger(level=logging.INFO) logger.info('Starting Starship Flight Updates Bot (PROD)') # ------------------ twit = twitter.Twitter(0, logger) twit.add_twitter_account('BocaChicaGal') twit.add_twitter_account('SpaceX') regular_update(twit, logger) active.start(twit, logger) calcDailyTime = datetime.datetime.combine( datetime.datetime.utcnow().date(), Database().daily_message_time) - datetime.timedelta(minutes=5) schedule.every().day.at(calcDailyTime.strftime('%H:%M')).do( daily_update, logger) logger.info('>Daily-Update Time: ' + calcDailyTime.strftime('%H:%M')) schedule.every(15).to(25).minutes.do(regular_update, twit, logger) logger.debug('>starting main-main loop') while 1: schedule.run_pending() time.sleep(1)
class Weather: APIKEY = dotenv_parser.get_value('.env', 'WEATHER_KEY') _last_current_weather = {'time': datetime.datetime.min, 'data': {}} def __init__(self): pass def today_forecast(self): try: r = requests.get( 'http://api.openweathermap.org/data/2.5/onecall', { 'lat': 25.997083229714256, 'lon': -97.15597286864448, 'exclude': 'current,minutely,hourly,alerts', 'units': 'metric', 'appid': Weather.APIKEY }).json()['daily'][0] return { 'temp': r['temp']['day'], 'feels_like': r['feels_like']['day'], 'pressure': r['pressure'], 'humidity': r['humidity'], 'wind_speed': round(r['wind_speed'] * 3.6, 2), 'wind_deg': r['wind_deg'], 'weather': r['weather'][0] } except Exception as e: if e is not requests.ConnectionError: message.ErrMessage().sendErrMessage( 'Error Weather-today-forecast!\n\nException:\n' + str(e)) return {} def current_weather(self, sincelastmins=20): try: if self._last_current_weather['time'] < datetime.datetime.utcnow( ) - datetime.timedelta(minutes=sincelastmins): r = requests.get( 'http://api.openweathermap.org/data/2.5/onecall', { 'lat': 25.997083229714256, 'lon': -97.15597286864448, 'exclude': 'daily,minutely,hourly,alerts', 'units': 'metric', 'appid': self.APIKEY }).json()['current'] self._last_current_weather['time'] = datetime.datetime.utcnow() self._last_current_weather['data'] = { 'temp': r['temp'], 'feels_like': r['feels_like'], 'pressure': r['pressure'], 'humidity': r['humidity'], 'wind_speed': round(r['wind_speed'] * 3.6, 2), 'wind_deg': r['wind_deg'], 'weather': r['weather'][0] } return self._last_current_weather['data'] except Exception as e: if e is not requests.ConnectionError: message.ErrMessage().sendErrMessage( 'Error Weather-current-weather!\n\nException:\n' + str(e)) return {} def wind_text(self, w: dict, wind_limit=30): wind_speed = w['wind_speed'] if wind_speed > wind_limit: #windspeed > 20mph return ('Too windy (' + str(w['wind_speed']) + ' km/h, max:' + str(wind_limit) + ' km/h)', False) elif wind_speed > wind_limit / 2: return ('Windy (' + str(w['wind_speed']) + ' km/h)', True) elif wind_speed > 0: return ('Low wind (' + str(w['wind_speed']) + ' km/h)', True) else: return ('No wind (' + str(w['wind_speed']) + ' km/h)', True) def weather_text(self, w: dict): weather_id = str(w['weather']['id'])[0] out = w['weather']['main'] + ' (' + w['weather']['description'] + ')' if weather_id in ['8']: #more id's can be added later return (out, True) else: return (out, False) def weather_change(self, w=None, currently_active=None): #try: if self._last_current_weather['data'] == {}: if self.current_weather() == {}: return last = self._last_current_weather['data'] if w is None: w = self.current_weather() status_message = status.Status().active_change(currently_active) if self.weather_text(w)[1] != self.weather_text(last)[1]: if self.weather_text(w)[1]: message.send_message( '<a href="https://openweathermap.org/city/4720060"><b>Weather has changed:</b></a>\n<i>' + self.weather_text(w)[0] + '</i>' + status_message) else: message.send_message( '<a href="https://openweathermap.org/city/4720060"><b>Weather has changed:</b></a>\n<i>' + self.weather_text(w)[0] + '</i>' + status_message) elif self.wind_text(w)[1] != self.wind_text(last)[1]: if self.wind_text(w)[1]: message.send_message( '<a href="https://openweathermap.org/city/4720060"><b>Wind has changed:</b></a>\n<i>' + self.wind_text(w)[0] + '</i>' + status_message) else: message.send_message( '<a href="https://openweathermap.org/city/4720060"><b>Wind has changed:</b></a>\n<i>' + self.wind_text(w)[0] + '</i>' + status_message) elif self.weather_text(w)[1] != self.weather_text( last)[1] and self.wind_text(w)[1] != self.wind_text(last)[1]: out = '<a href="https://openweathermap.org/city/4720060"><b>Weather and wind have changed:</b></a><i>\nWeather: ' out += ('✅' if self.weather_text(w)[1] else '❌') out += ' ' + self.weather_text(w)[0] + '\nWind: ' out += ('✅' if self.wind_text(w)[1] else '❌') out += ' ' + self.wind_text(w)[0] + '</i>' message.send_message(out + status_message)
import requests, time, datetime from data_sources import dotenv_parser bot_token = dotenv_parser.get_value( '.env', 'TELEBOT_TOKEN') #https://api.telegram.org/botXXX/getUpdates channel_id = dotenv_parser.get_value('.env', 'TELEBOT_CHANNEL') err_channel_id = dotenv_parser.get_value('.env', 'TELEBOT_ERR_CHANNEL') def send_err_message(message, chatid=err_channel_id): try: return requests.post( 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + str(chatid), { 'text': '⚠️' + message, 'disable_web_page_preview': True }).json() except: pass def send_message(chatid, message, disable_link_preview=False): #print('<'+message) resp = '' try: resp = requests.post( 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + str(chatid) + '&parse_mode=HTML', { 'text': message, 'disable_web_page_preview': disable_link_preview }).json() except:
from typing import Text import requests from data_sources import dotenv_parser webhook_url = dotenv_parser.get_value('.env','DISCORD_URL') error_webhook_url = dotenv_parser.get_value('.env','DISCORD_ERROR') def handle_link(text:str , disable_link_preview:bool): #rekursive if '<a' not in text: return text beforelink = text.split('<a',1)[0] afterlink = text.split('</a>',1)[-1] unformatted = text.split('<a',1)[1].split('</a>',1)[0] link = '' if "'" in unformatted: link = unformatted.split("'")[1] else: link = unformatted.split('"')[1] linktext = unformatted.split('>',1)[-1] preview = '' if not disable_link_preview: preview = '\n'+link else: link = '<'+link+'>' return handle_link(beforelink+'['+linktext+']('+link+')'+afterlink+preview,disable_link_preview) def send_discord_message(text:str, disable_link_preview = False, color = 7707321, webhook = webhook_url): text = text.replace('<b>','**').replace('</b>','**') #bold text = text.replace('<u>','__').replace('</u>','__') #underline text = text.replace('<i>','_').replace('</i>','_') #italic text = text.replace('<s>','~~').replace('</s>','~~') #strike