def __init__(self, speakerbot=None): self.db = SpeakerDB() self.theme_songs = {} self.speakerbot = speakerbot self.config = config["twitter"] self.twitter = Twython( self.config["app_key"], self.config["app_secret"], self.config["oauth_token"], self.config["oauth_token_secret"])
class SpeakerTwitter(object): def __init__(self, speakerbot=None): self.db = SpeakerDB() self.theme_songs = {} self.speakerbot = speakerbot self.config = config["twitter"] self.twitter = Twython( self.config["app_key"], self.config["app_secret"], self.config["oauth_token"], self.config["oauth_token_secret"]) def publish_from_queue(self): forbidden_words = ["nohodo", "vk", "vertical knowledge", "d ", "rape", "raping", "rapeing", "rapin"] try: tweet_record = self.db.execute("select id, tweet_text from publish_queue limit 1").next() except StopIteration: tweet_record = False if tweet_record: tweet_text = unicode(tweet_record["tweet_text"]) tweet_id = tweet_record["id"] tweet_this = True for word in forbidden_words: if word in tweet_text.lower(): tweet_this = False if tweet_this: try: self.twitter.update_status(status=tweet_text) except TwythonError as e: print str(e) print "---------" print tweet_text pass self.db.execute("delete from publish_queue where id=?", [tweet_id])
class Speakonomy: __metaclass__ = Singleton def __init__(self, speakerbot=None, disabled=False): self.db = SpeakerDB() self.speakerbot = speakerbot self.disabled = disabled self.free_play_timeout = None def check_affordability(self, sound_name=None, cost=None, free=False): if not self.is_active() or free: return True if not cost: cost = self.db.execute("SELECT cost FROM sounds WHERE name=?", [ sound_name, ]).fetchone()['cost'] balance = self.get_speakerbuck_balance() if cost <= balance: return True return False def deposit_funds(self, amount=1): self.db.execute("UPDATE bank_account set balance=balance+?", [ amount, ]) self.db.execute("UPDATE bank_account set balance=0 WHERE balance<0") def get_free_play_timeout(self, force_check=False): if self.free_play_timeout and not force_check: return self.free_play_timeout expiration_timestamp = self.db.execute( "SELECT free_play_timeout FROM bank_account").fetchone( )['free_play_timeout'] self.free_play_timeout = dt.datetime.fromtimestamp( expiration_timestamp) return self.free_play_timeout def get_last_withdrawal_time(self, include_sbpm=False): last_withdrawal_time = self.db.execute( "SELECT last_withdrawal_time FROM bank_account").fetchone( )['last_withdrawal_time'] last_withdrawal_time = dt.datetime.fromtimestamp(last_withdrawal_time) if not include_sbpm: return last_withdrawal_time today_time = dt.datetime.combine(dt.date.today(), dt.time(8, 00)) if last_withdrawal_time < today_time: last_withdrawal_time = today_time minutes_since_last_withdrawal = ( dt.datetime.now() - last_withdrawal_time).total_seconds() / 60 spbm = int((minutes_since_last_withdrawal + 9) / 10) return last_withdrawal_time, spbm def get_speakerbuck_balance(self): balance = self.db.execute( "SELECT balance FROM bank_account").fetchone() if balance: return balance['balance'] return 0 def is_active(self, force_check=False): if config.get("force_speakonomy", False): return True if self.disabled: return False if dt.datetime.today().weekday() in [5, 6]: return False current_hour = dt.datetime.now().hour if current_hour < 8 or current_hour > 18: return False if dt.datetime.now() < self.get_free_play_timeout( force_check=force_check): return False return True def regulate_costs(self): self.db.execute( "UPDATE sounds set cost=FLOOR(0.95*cost+0.05*base_cost) WHERE cost > base_cost" ) self.db.execute( "UPDATE sounds set cost=base_cost WHERE cost < base_cost") def sell_sound(self, sound_name, **kwargs): if self.is_active() and not kwargs.get('free'): cost = int( self.db.execute("SELECT cost FROM sounds WHERE name=?", [ sound_name, ]).fetchone()['cost']) self.withdraw_funds(cost) self.db.execute("UPDATE sounds set cost=cost*2 where name=?", [ sound_name, ]) self.speakerbot.sounds[sound_name].cost = cost * 2 def sell_saying(self, speech_text, **kwargs): if self.is_active(): speech_cost = len(re.sub(r'[^a-z0-9]', '', speech_text, flags=re.I)) * 2 self.withdraw_funds(speech_cost) def set_free_play_timeout(self, expiration_datetime=None, hours=0, minutes=0): if not expiration_datetime: expiration_datetime = dt.datetime.now() + dt.timedelta( hours=hours, minutes=minutes) expiration_timestamp = expiration_datetime.strftime("%s") self.db.execute("UPDATE bank_account SET free_play_timeout=?", [ expiration_timestamp, ]) self.free_play_timeout = dt.datetime.fromtimestamp( float(expiration_timestamp)) def get_sound_base_cost(self, sound_path): try: sound_size = os.stat(sound_path).st_size sound_cost = int(sound_size / 1024 * 0.0854455 - 0.0953288 + 0.5) if sound_cost < 1: sound_cost = 1 except: sound_cost = 0 return sound_cost def set_sound_base_costs(self, sound_dir="sounds"): assert self.speakerbot != None if not self.speakerbot.sounds: self.speakerbot.load_sounds() for sound_name in self.speakerbot.sounds: sound_path = '{}/{}'.format(sound_dir, self.speakerbot.sounds[sound_name][0]) sound_cost = self.get_sound_base_cost(sound_path) self.db.execute( "UPDATE sounds SET base_cost={} where name='{}'".format( sound_cost, sound_name)) def withdraw_funds(self, amount): if self.is_active(True): self.deposit_funds(amount=-1 * amount) withdrawal_time = dt.datetime.now().strftime("%s") self.db.execute( "UPDATE bank_account SET last_withdrawal_time={}".format( withdrawal_time))
def __init__(self, speakerbot=None, disabled=False): self.db = SpeakerDB() self.speakerbot = speakerbot self.disabled = disabled self.free_play_timeout = None
def __init__(self, speakerbot=None): self.db = SpeakerDB() self.theme_songs = {} self.speakerbot = speakerbot self.last_theme_cache_time = dt.datetime.min
class SpeakerbotDJ: def __init__(self, speakerbot=None): self.db = SpeakerDB() self.theme_songs = {} self.speakerbot = speakerbot self.last_theme_cache_time = dt.datetime.min def extract_email_field(self, s, field): field_match = re.search(r'^\s*{}:\s+(.*?)\s*$'.format(re.escape(field)), s, flags=re.I|re.M) if not field_match: return None return field_match.group(1) def cache_theme_songs(self): sb.load_sounds() results = self.db.execute("SELECT name, theme_song, last_theme_play_time FROM person").fetchall() for result in results: play_ok = True if result['last_theme_play_time']: last_theme_play_time = dt.datetime.fromtimestamp(result['last_theme_play_time']) minutes_since_last_theme = (dt.datetime.now() - last_theme_play_time).total_seconds() / 60 if minutes_since_last_theme < 15: play_ok = False self.theme_songs[minimize_string(result['name'])] = (result['name'], result['theme_song'], play_ok) self.last_theme_cache_time = dt.datetime.now() def check_for_entrance(self): # Needs cleanup... mail = imaplib.IMAP4(config['email']['host']) mail.login(config['email']['user'], config['email']['pass']) mail.select() (retcode, messages) = mail.search(None, '(UNSEEN)') if retcode != 'OK': print 'Unknown error' return if len(messages[0]) == 0: return for message_number in messages[0].split(' '): (ret, data) = mail.fetch(message_number, '(RFC822)') email_body = str(email.message_from_string(data[0][1])) user = self.extract_email_field(email_body, 'User') door = self.extract_email_field(email_body, 'Door') if not door: door = self.extract_email_field(email_body, 'Elevator') # date = self.extract_email_field(email_body, 'Date') # time = self.extract_email_field(email_body, 'Time') # entry_time = dt.datetime.strptime(date+' '+time, '%m/%d/%y %I:%M:%S %p EDT') if not user: print "No user" continue user = minimize_string(user) door = minimize_string(door) #lookup theme song based on user if not self.theme_songs.get(user): print "Unrecognized user:"******"USER: [{}] DOOR: [{}]".format(user, door) real_name, theme_song, play_ok = self.theme_songs[user] if not theme_song or not play_ok: print "No theme song or play_ok" continue if door in ['mezstairdevhall','nstair2labdrb1n1mezz','nhall2labdrb2n2mezz']: print 'queue now' elif door in ['sstairdrb2n1serv']: print 'queue in 45 seconds' sleep(45) elif door in ['1stflelevbutton']: print 'queue in 60 seconds' sleep(60) else: print 'Unknown door:', door continue # Hackaround to avoid economy sb._play(theme_song) theme_play_time = dt.datetime.now().strftime("%s") self.db.execute("UPDATE person SET last_theme_play_time=? WHERE name=?", [theme_play_time, real_name]) self.cache_theme_songs() mail.close()
import datetime import json from random import choice, randrange import requests from pyquery import PyQuery as pq from config import config from speakonomy import Speakonomy from macros import Macro from util.words import parse_and_fill_mad_lib, term_map from speaker_db import SpeakerDB from dynamic_class import plugin from mitch import quotes as mitch_quotes db = SpeakerDB() def get_mashape_api(url): api_key = config["mashape_api_key"] headers = {"X-Mashape-Authorization": api_key} return requests.get(url, headers=headers) @plugin def suspense(sb): speakonomy = Speakonomy() if speakonomy.is_active(): if not speakonomy.check_affordability(cost=20): return "Not enough speakerbucks for drumroll"
class Speakonomy: __metaclass__ = Singleton def __init__(self, speakerbot=None, disabled=False): self.db = SpeakerDB() self.speakerbot = speakerbot self.disabled = disabled self.free_play_timeout = None def check_affordability(self, sound_name=None, cost=None, free=False): if not self.is_active() or free: return True if not cost: cost = self.db.execute("SELECT cost FROM sounds WHERE name=?", [sound_name,]).fetchone()['cost'] balance = self.get_speakerbuck_balance() if cost <= balance: return True return False def deposit_funds(self, amount=1): self.db.execute("UPDATE bank_account set balance=balance+?", [amount,]) self.db.execute("UPDATE bank_account set balance=0 WHERE balance<0") def get_free_play_timeout(self, force_check=False): if self.free_play_timeout and not force_check: return self.free_play_timeout expiration_timestamp = self.db.execute("SELECT free_play_timeout FROM bank_account").fetchone()['free_play_timeout'] self.free_play_timeout = dt.datetime.fromtimestamp(expiration_timestamp) return self.free_play_timeout def get_last_withdrawal_time(self, include_sbpm=False): last_withdrawal_time = self.db.execute("SELECT last_withdrawal_time FROM bank_account").fetchone()['last_withdrawal_time'] last_withdrawal_time = dt.datetime.fromtimestamp(last_withdrawal_time) if not include_sbpm: return last_withdrawal_time today_time = dt.datetime.combine(dt.date.today(), dt.time(8, 00)) if last_withdrawal_time < today_time: last_withdrawal_time = today_time minutes_since_last_withdrawal = (dt.datetime.now() - last_withdrawal_time).total_seconds() / 60 spbm = int((minutes_since_last_withdrawal + 9) / 10) return last_withdrawal_time, spbm def get_speakerbuck_balance(self): balance = self.db.execute("SELECT balance FROM bank_account").fetchone() if balance: return balance['balance'] return 0 def is_active(self, force_check=False): if config.get("force_speakonomy", False): return True if self.disabled: return False if dt.datetime.today().weekday() in [5,6]: return False current_hour = dt.datetime.now().hour if current_hour < 8 or current_hour > 18: return False if dt.datetime.now() < self.get_free_play_timeout(force_check=force_check): return False return True def regulate_costs(self): self.db.execute("UPDATE sounds set cost=FLOOR(0.95*cost+0.05*base_cost) WHERE cost > base_cost") self.db.execute("UPDATE sounds set cost=base_cost WHERE cost < base_cost") def sell_sound(self, sound_name, **kwargs): if self.is_active() and not kwargs.get('free'): cost = int(self.db.execute("SELECT cost FROM sounds WHERE name=?", [sound_name,]).fetchone()['cost']) self.withdraw_funds(cost) self.db.execute("UPDATE sounds set cost=cost*2 where name=?", [sound_name,]) self.speakerbot.sounds[sound_name].cost = cost * 2 def sell_saying(self, speech_text, **kwargs): if self.is_active(): speech_cost = len(re.sub(r'[^a-z0-9]', '', speech_text, flags=re.I)) * 2 self.withdraw_funds(speech_cost) def set_free_play_timeout(self, expiration_datetime=None, hours=0, minutes=0): if not expiration_datetime: expiration_datetime = dt.datetime.now() + dt.timedelta(hours=hours, minutes=minutes) expiration_timestamp = expiration_datetime.strftime("%s") self.db.execute("UPDATE bank_account SET free_play_timeout=?", [expiration_timestamp,]) self.free_play_timeout = dt.datetime.fromtimestamp(float(expiration_timestamp)) def get_sound_base_cost(self, sound_path): try: sound_size = os.stat(sound_path).st_size sound_cost = int(sound_size/1024 * 0.0854455 - 0.0953288 + 0.5) if sound_cost < 1: sound_cost = 1 except: sound_cost = 0 return sound_cost def set_sound_base_costs(self, sound_dir="sounds"): assert self.speakerbot != None if not self.speakerbot.sounds: self.speakerbot.load_sounds() for sound_name in self.speakerbot.sounds: sound_path = '{}/{}'.format(sound_dir, self.speakerbot.sounds[sound_name][0]) sound_cost = self.get_sound_base_cost(sound_path) self.db.execute("UPDATE sounds SET base_cost={} where name='{}'".format(sound_cost, sound_name)) def withdraw_funds(self, amount): if self.is_active(True): self.deposit_funds(amount=-1*amount) withdrawal_time = dt.datetime.now().strftime("%s") self.db.execute("UPDATE bank_account SET last_withdrawal_time={}".format(withdrawal_time))
def __init__(self): self._db = SpeakerDB() self._voice = config['ibm_speech']['voice'] self._voice_prefix = '<voice-transformation type="Custom" glottal_tension="-10%" breathiness="-10%" pitch="10%" pitch_range="15%" rate="-99%" strength="5%">'
def __init__(self, speakerbot=None, disabled=False): self.db = SpeakerDB() self.speakerbot = speakerbot self.disabled = disabled
class SpeakerbotDJ: def __init__(self, speakerbot=None): self.db = SpeakerDB() self.theme_songs = {} self.speakerbot = speakerbot self.last_theme_cache_time = dt.datetime.min def extract_email_field(self, s, field): field_match = re.search(r'>\s*{}:\s+(.*?)\s*<'.format(re.escape(field)), s, flags=re.I|re.M) if not field_match: return None return field_match.group(1) def cache_theme_songs(self): sb.load_sounds() results = self.db.execute("SELECT name, theme_song, last_theme_play_time FROM person").fetchall() for result in results: play_ok = True if result['last_theme_play_time']: last_theme_play_time = dt.datetime.fromtimestamp(result['last_theme_play_time']) minutes_since_last_theme = (dt.datetime.now() - last_theme_play_time).total_seconds() / 60 if minutes_since_last_theme < 15: play_ok = False self.theme_songs[minimize_string(result['name'])] = (result['name'], result['theme_song'], play_ok) self.last_theme_cache_time = dt.datetime.now() def check_for_entrance(self): # Needs cleanup... mail = imaplib.IMAP4(config['email']['host']) mail.login(config['email']['user'], config['email']['pass']) mail.select() (retcode, messages) = mail.search(None, '(UNSEEN)') if retcode != 'OK': print 'Unknown error' return if len(messages[0]) == 0: return for message_number in messages[0].split(' '): (ret, data) = mail.fetch(message_number, '(RFC822)') email_body = str(email.message_from_string(data[0][1])) user = self.extract_email_field(email_body, 'User') door = self.extract_email_field(email_body, 'Door') if not door: door = self.extract_email_field(email_body, 'Elevator') # date = self.extract_email_field(email_body, 'Date') # time = self.extract_email_field(email_body, 'Time') # entry_time = dt.datetime.strptime(date+' '+time, '%m/%d/%y %I:%M:%S %p EDT') if not user: print "No user" continue user = minimize_string(user) door = minimize_string(door) #lookup theme song based on user if not self.theme_songs.get(user): print "Unrecognized user:"******"USER: [{}] DOOR: [{}]".format(user, door) real_name, theme_song, play_ok = self.theme_songs[user] if not theme_song or not play_ok: print "No theme song or play_ok" continue if door in ['mezstairdevhall','nstair2labdrb1n1mezz','nhall2labdrb2n2mezz']: print 'queue now' elif door in ['sstairdrb2n1serv']: print 'queue in 45 seconds' sleep(45) elif door in ['1stflelevbutton']: print 'queue in 60 seconds' sleep(60) else: print 'Unknown door:', door continue # Hackaround to avoid economy sb._play(theme_song) theme_play_time = dt.datetime.now().strftime("%s") self.db.execute("UPDATE person SET last_theme_play_time=? WHERE name=?", [theme_play_time, real_name]) self.cache_theme_songs() mail.close()
def __init__(self): self._db = SpeakerDB() self.client = self.get_client()
class ATTTextToSpeech(object): CLIENT_ID = config['att_speech']['client_id'] CLIENT_SECRET = config['att_speech']['client_secret'] CLIENT_SCOPE = ['TTS'] TOKEN_FIELD_NAME = 'att_speech_token' TOKEN_URL = 'https://api.att.com/oauth/v4/token' TTS_URL = 'https://api.att.com/speech/v3/textToSpeech' TTS_VOICE = config['att_speech']['voice_name'] TTS_TEMPO = config['att_speech']['tempo'] TTS_HEADERS = { 'Content-Type': 'text/plain', 'Accept': 'audio/x-wav', 'X-Arg': 'VoiceName={},Tempo={}'.format(TTS_VOICE, TTS_TEMPO) } def __init__(self): self._db = SpeakerDB() self.client = self.get_client() def get_client(self): token = self._db.get_field_value('att_speech_token') if token: token = json.loads(token) else: oauth = OAuth2Session(client=BackendApplicationClient(client_id=self.CLIENT_ID)) token = oauth.fetch_token(token_url=self.TOKEN_URL, client_id=self.CLIENT_ID, client_secret=self.CLIENT_SECRET, scope=self.CLIENT_SCOPE) self.save_token(token) return OAuth2Session(self.CLIENT_ID, token=token, auto_refresh_url=self.TOKEN_URL, token_updater=self.save_token) def save_token(self, token): self._db.set_field_value(self.TOKEN_FIELD_NAME, json.dumps(token)) def say(self, text): phrases = [text] filenames = [] if len(text) > 100: phrases = split_text(text, 100) for phrase in phrases: hsh = sha256() hsh.update(phrase.lower() + self.TTS_VOICE + self.TTS_TEMPO) filename = 'speech/%s.wav' % hsh.hexdigest() self.create_sound_file(filename, phrase) filenames.append(filename) for filename in filenames: SoundPlayer(config['wav_player']).play_sound(filename) def create_sound_file(self, filename, text): if os.path.isfile(filename) and os.path.getsize(filename): return response = self.client.post(self.TTS_URL, headers=self.TTS_HEADERS, data=text) with open(filename, 'wb') as f: f.write(response.content)