def init(username, password, try_cookies=True): global _clients global _rooms global _room_data global _last_messages for site in _clients.keys(): client = Client(site) logged_in = False if try_cookies: if GlobalVars.cookies is None: datahandling._remove_pickle("cookies.p") GlobalVars.cookies = {} else: cookies = GlobalVars.cookies try: if site in cookies and cookies[site] is not None: client.login_with_cookie(cookies[site]) logged_in = True log('debug', 'Logged in using cached cookies') except LoginError as e: exc_type, exc_obj, exc_tb = sys.exc_info() log('debug', 'Login error {}: {}'.format(exc_type.__name__, exc_obj)) log('debug', 'Falling back to credential-based login') del cookies[site] datahandling.dump_cookies() if not logged_in: for retry in range(3): try: GlobalVars.cookies[site] = client.login(username, password) break except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() log('debug', 'Login error {}: {}'.format(exc_type.__name__, exc_obj)) else: raise Exception("Failed to log into " + site + ", max retries exceeded") _clients[site] = client if os.path.exists("rooms_custom.yml"): parse_room_config("rooms_custom.yml") else: parse_room_config("rooms.yml") if not GlobalVars.standby_mode: join_command_rooms() if os.path.isfile("messageData.p"): try: _last_messages = pickle.load(open("messageData.p", "rb")) except EOFError: pass threading.Thread(name="pickle ---rick--- runner", target=pickle_last_messages, daemon=True).start() threading.Thread(name="message sender", target=send_messages, daemon=True).start() if try_cookies: datahandling.dump_cookies()
def init(username, password): global _clients global _rooms global _room_data global _last_messages for site in _clients.keys(): client = Client(site) for _ in range(10): try: client.login(username, password) break except: pass else: raise Exception("Failed to log into " + site) _clients[site] = client if os.path.exists("rooms_custom.yml"): parse_room_config("rooms_custom.yml") else: parse_room_config("rooms.yml") if not GlobalVars.standby_mode: for site, roomid in _command_rooms: room = _clients[site].get_room(roomid) deletion_watcher = (site, roomid) in _watcher_rooms room.join() room.watch_socket(on_msg) _rooms[(site, roomid)] = RoomData(room, -1, deletion_watcher) if os.path.isfile("messageData.p"): try: _last_messages = pickle.load(open("messageData.p", "rb")) except EOFError: pass threading.Thread(name="pickle ---rick--- runner", target=pickle_last_messages, daemon=True).start() threading.Thread(name="message sender", target=send_messages, daemon=True).start()
def init(username, password): global _clients global _rooms global _room_data global _last_messages for site in _clients.keys(): client = Client(site) for _ in range(10): try: client.login(username, password) break except: pass else: raise Exception("Failed to log into " + site) _clients[site] = client if os.path.exists("rooms_custom.yml"): parse_room_config("rooms_custom.yml") else: parse_room_config("rooms.yml") if not GlobalVars.standby_mode: join_command_rooms() if os.path.isfile("messageData.p"): try: _last_messages = pickle.load(open("messageData.p", "rb")) except EOFError: pass threading.Thread(name="pickle ---rick--- runner", target=pickle_last_messages, daemon=True).start() threading.Thread(name="message sender", target=send_messages, daemon=True).start()
def init(username, password): global _clients global _rooms global _room_data global _last_messages for site in _clients.keys(): client = Client(site) for retry in range(10): try: client.login(username, password) break except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() log('debug', 'Login error {}: {}'.format(exc_type.__name__, exc_obj)) else: raise Exception("Failed to log into " + site + ", max retries exceeded") _clients[site] = client if os.path.exists("rooms_custom.yml"): parse_room_config("rooms_custom.yml") else: parse_room_config("rooms.yml") if not GlobalVars.standby_mode: join_command_rooms() if os.path.isfile("messageData.p"): try: _last_messages = pickle.load(open("messageData.p", "rb")) except EOFError: pass threading.Thread(name="pickle ---rick--- runner", target=pickle_last_messages, daemon=True).start() threading.Thread(name="message sender", target=send_messages, daemon=True).start()
class GlobalVars: false_positives = [] whitelisted_users = [] blacklisted_users = [] ignored_posts = [] auto_ignored_posts = [] startup_utc = datetime.utcnow().strftime("%H:%M:%S") latest_questions = [] api_backoff_time = 0 charcoal_room_id = "11540" meta_tavern_room_id = "89" socvr_room_id = "41570" blockedTime = { "all": 0, charcoal_room_id: 0, meta_tavern_room_id: 0, socvr_room_id: 0 } metasmoke_last_ping_time = datetime.now() experimental_reasons = [] # Don't widely report these non_socvr_reasons = [] # Don't report to SOCVR non_tavern_reasons = [ # Don't report in the Tavern "all-caps body", "all-caps answer", "repeating characters in body", "repeating characters in title", "repeating characters in answer", "few unique characters in body", "few unique characters in answer", "title has only one unique char", "phone number detected in title", "offensive body detected", "no whitespace in body", "no whitespace in answer", ] non_tavern_sites = ["stackoverflow.com"] parser = HTMLParser.HTMLParser() wrap = Client("stackexchange.com") wrapm = Client("meta.stackexchange.com") wrapso = Client("stackoverflow.com") privileged_users = { charcoal_room_id: [ "117490", # Normal Human "66258", # Andy "31768", # ManishEarth "103081", # hichris123 "73046", # Undo "88521", # ProgramFOX "59776", # Doorknob "31465", # Seth "88577", # Santa Claus "34124", # Andrew Leach "54229", # apnorton "20459", # S.L. Barth "32436", # tchrist "30477", # Brock Adams "58529", # ferrybig "145208", # Robert Longson "178825", # Ms Yvette "171800", # JAL "64978", # PeterJ "125141", # Jeffrey Bosboom "54902", # bummi "135450", # M.A.R. "145604", # Quill "60548", # rene "121401", # michaelpri "116218", # JamesENL "82927", # Braiam "11606", # bwDraco "19761", # Ilmari Karonen "108271", # Andrew T. "171054", # Magisch "190011", # Petter Friberg "165661", # Tunaki "145086", # Wai Ha Lee "137665", # ByteCommander "147884", # wythagoras "186395", # Åna "181293", # Ashish Ahuja "163686", # Gothdo "145827", # angussidney "244748", # Supreme Leader SnokeDetector (angussidney's sock) "121520", # ArtOfCode "244382", # Lt. A. Code (ArtOfCode's sock to test things with) "137388", # QPaysTaxes "212311", # Ryan Bemrose "172397", # Kyll "224538", # FrankerZ "61202", # OldSkool "56166", # Jan Dvorak "133966", # DavidPostill "22839", # djsmiley2k "97389", # Kaz Wolfe "144962", # DJMcMayhem "139423", # NobodyNada "62118", # tripleee "130558", # Registered User "128113", # arda "164318", # Glorfindel "175347", # Floern "180274", # Alexander O'Mara "158742", # Rob "207356", # 4castle "133031", # Mithrandir "169713", # Mego "126657", # Cerbrus "10145", # Thomas Ward "161943", # J F "195967", # CaffeineAddiction "5363", # Stijn "248139", # FelixSFD "156721", # D-side "167070", # quartata "172450", # Hovercraft Full Of Eels "56200", # Eric Leschinski "211021", # Henders "255290" # Gypsy Spellweaver ], meta_tavern_room_id: [ "315433", # Normal Human "244519", # CRABOLO "244382", # TGMCians "194047", # Jan Dvorak "158100", # rene "178438", # Manishearth "237685", # hichris123 "215468", # Undo "229438", # ProgramFOX "180276", # Doorknob "161974", # Lynn Crumbling "186281", # Andy "266094", # Unihedro "245167", # Infinite Recursion "230261", # Jason C "213575", # Braiam "241919", # Andrew T. "203389", # backwards-Seth "202832", # Mooseman "160017", # bwDraco "201151", # bummi "188558", # Frank "229166", # Santa Claus "159034", # Kevin Brown "203972", # PeterJ "188673", # Alexis King "258672", # AstroCB "227577", # Sam "255735", # cybermonkey "279182", # Ixrec "271104", # James "220428", # Qantas 94 Heavy "153355", # tchrist "238426", # Ed Cottrell "166899", # Second Rikudo "287999", # ASCIIThenANSI "208518", # JNat "284141", # michaelpri "260312", # vaultah "244062", # SouravGhosh "152859", # Shadow Wizard "201314", # apnorton "280934", # M.A.Ramezani "200235", # durron597 "148310", # Awesome Poodles / Brock Adams "168333", # S.L. Barth "257207", # Unikitty "244282", # DroidDev "163250", # Cupcake "298265", # BoomsPlus "253560", # josilber "244254", # misterManSam "188189", # Robert Longson "174699", # Ilmari Karonen "202362", # chmod 666 telkitty "289717", # Quill "237813", # bjb568 "311345", # Simon Klaver "171881", # rekire "260388", # Pandya "310756", # Ms Yvette "262399", # Jeffrey Bosboom "242209", # JAL "280883", # ByteCommander "302251", # kos "262823", # ArtOfCode "215067", # Ferrybig "308386", # Magisch "285368", # angussidney "158829", # Thomas Ward "294691" # Mithrandir ], socvr_room_id: [ "1849664", # Undo "2581872", # hichris123 "1198729", # Manishearth "3717023", # Normal Human aka 1999 "2619912", # ProgramFOX "578411", # rene "1043380", # gunr2171 "2246344", # Sam "2756409", # TylerH "1768232", # durron597 "359284", # Kevin Brown "258400", # easwee "3622940", # Unihedron "3204551", # Deduplicator "4342498", # NathanOliver "4639281", # Tiny Giant "3093387", # josilber "1652962", # cimmanon "1677912", # Mogsdad "656243", # Lynn Crumbling "3933332", # Rizier123 "2422013", # cybermonkey "3478852", # Nisse Engström "2302862", # Siguza "1324", # Paul Roub "1743880", # Tunaki "1663001", # DavidG "2415822", # JAL "4174897", # Kyll "5299236", # Kevin Guan "4050842", # Thaillie "1816093", # Drew "874188", # Triplee "880772", # approxiblue "1835379", # Cerbrus "3956566", # JamesENL "2357233", # Ms Yvette "3155639", # AlexanderOMara "462627", # Praveen Kumar "4490559", # intboolstring "1364007", # Wai Ha Lee "1699210", # bummi "563532", # Rob "5389107", # Magisch "4099593", # bhargav-rao "1542723", # Ferrybig "2025923", # Tushar "5292302", # Petter Friberg "792066", # Braiam "5666987", # Ian "3160466", # ArtOfCode "4688119", # Ashish Ahuja "3476191", # Nobody Nada "2227743", # Eric D "821878", # Ryan Bemrose "1413395", # Panta Rei "4875631", # FrankerZ "2958086", # Compass "499214", # JanDvorak "5647260", # Andrew L. "559745", # Floern "5743988", # 4castle "4622463", # angussidney "603346", # Thomas Ward "3002139", # Baum mit Augen "1863564", # QPaysTaxes "4687348", # FelixSFD "4751173", # Glorfindel "2233391", # henders "4805174" # kayess ] } code_privileged_users = None smokeDetector_user_id = { charcoal_room_id: "120914", meta_tavern_room_id: "266345", socvr_room_id: "3735529" } censored_committer_names = {"3f4ed0f38df010ce300dba362fa63a62": "Undo1"} commit = os.popen('git log --pretty=format:"%h" -n 1').read() commit_author = os.popen('git log --pretty=format:"%an" -n 1').read() if md5(commit_author).hexdigest() in censored_committer_names: commit_author = censored_committer_names[md5( commit_author).hexdigest()] commit_with_author = os.popen('git log --pretty=format:"%h (' + commit_author + ': *%s*)" -n 1').read() on_master = "HEAD detached" not in os.popen("git status").read() charcoal_hq = None tavern_on_the_meta = None socvr = None s = "" s_reverted = "" specialrooms = [] apiquota = -1 bodyfetcher = None se_sites = [] users_chatting = { meta_tavern_room_id: [], charcoal_room_id: [], socvr_room_id: [] } why_data = [] why_data_allspam = [] notifications = [] listen_to_these_if_edited = [] multiple_reporters = [] api_calls_per_site = {} standby_message = "" standby_mode = False api_request_lock = threading.Lock() num_posts_scanned = 0 post_scan_time = 0 posts_scan_stats_lock = threading.Lock() config = ConfigParser.RawConfigParser() if os.path.isfile('config'): config.read('config') else: config.read('config.ci') latest_smokedetector_messages = { meta_tavern_room_id: [], charcoal_room_id: [], socvr_room_id: [] } # environ_or_none defined in helpers.py bot_name = environ_or_none("SMOKEDETECTOR_NAME") or "SmokeDetector" bot_repository = environ_or_none( "SMOKEDETECTOR_REPO") or "//github.com/Charcoal-SE/SmokeDetector" chatmessage_prefix = "[{}]({})".format(bot_name, bot_repository) site_id_dict = {} post_site_id_to_question = {} location = config.get("Config", "location") metasmoke_ws = None try: metasmoke_host = config.get("Config", "metasmoke_host") except ConfigParser.NoOptionError: metasmoke_host = None log( 'info', "metasmoke host not found. Set it as metasmoke_host in the config file." "See https://github.com/Charcoal-SE/metasmoke.") try: metasmoke_key = config.get("Config", "metasmoke_key") except ConfigParser.NoOptionError: metasmoke_key = "" log( 'info', "No metasmoke key found, which is okay if both are running on the same host" ) try: metasmoke_ws_host = config.get("Config", "metasmoke_ws_host") except ConfigParser.NoOptionError: metasmoke_ws_host = "" log( 'info', "No metasmoke websocket host found, which is okay if you're anti-websocket" ) try: github_username = config.get("Config", "github_username") github_password = config.get("Config", "github_password") except ConfigParser.NoOptionError: github_username = None github_password = None
def init(username, password, try_cookies=True): global _clients global _rooms global _room_data global _last_messages for site in _clients.keys(): client = Client(site) logged_in = False if try_cookies: if GlobalVars.cookies is None: datahandling._remove_pickle("cookies.p") GlobalVars.cookies = {} else: cookies = GlobalVars.cookies try: if site in cookies and cookies[site] is not None: client.login_with_cookie(cookies[site]) logged_in = True log( 'debug', 'chat.{}: Logged in using cached cookies'.format( site)) except LoginError as e: exc_type, exc_obj, exc_tb = sys.exc_info() log( 'debug', 'chat.{}: Login error {}: {}'.format( site, exc_type.__name__, exc_obj)) log( 'debug', 'chat.{}: Falling back to credential-based login'. format(site)) del cookies[site] datahandling.dump_cookies() if not logged_in: for retry in range(3): try: GlobalVars.cookies[site] = client.login(username, password) break except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() log( 'debug', 'chat.{}: Login error {}: {}'.format( site, exc_type.__name__, exc_obj)) else: raise Exception("Failed to log into " + site + ", max retries exceeded") _clients[site] = client if os.path.exists("rooms_custom.yml"): parse_room_config("rooms_custom.yml") else: parse_room_config("rooms.yml") if not GlobalVars.standby_mode: join_command_rooms() if os.path.isfile("messageData.p"): with open("messageData.p", "rb") as messages_file: try: _last_messages = pickle.load(messages_file) except EOFError: pass threading.Thread(name="pickle ---rick--- runner", target=pickle_last_messages, daemon=True).start() threading.Thread(name="message sender", target=send_messages, daemon=True).start() if try_cookies: datahandling.dump_cookies()
def init(username, password, try_cookies=True): global _clients global _rooms global _room_data global _last_messages for site in _clients.keys(): client = Client(site) logged_in = False if try_cookies: if GlobalVars.cookies is None: datahandling.remove_pickle("cookies.p") GlobalVars.cookies = {} else: cookies = GlobalVars.cookies try: if site in cookies and cookies[site] is not None: try: # This implements a quick login to only chat using the existing cookies. It doesn't # require accessing main SE sites, so should be available when SE is in read-only mode. # Ideally, we'll update ChatExchange with something similar. client._br.session.cookies.update(cookies[site]) # client.get_me() will raise an exception if the cookies don't work. me = client.get_me() if me.id > 0: client.logged_in = True logged_in = True log( 'debug', 'chat.{}: Logged in to chat only using cached cookies' .format(site)) except Exception: # This is a fallback using the ChatExchange functionality we've been using for a long time. log( 'debug', 'chat.{}: chat-only login failed. Falling back to normal cookies' .format(site)) client.login_with_cookie(cookies[site]) logged_in = True log( 'debug', 'chat.{}: Logged in using cached cookies'. format(site)) except LoginError as e: exc_type, exc_obj, exc_tb = sys.exc_info() log( 'debug', 'chat.{}: Login error {}: {}'.format( site, exc_type.__name__, exc_obj)) log( 'debug', 'chat.{}: Falling back to credential-based login'. format(site)) # Instead of deleting the cookies, start with a clean slate of a new client. client = Client(site) if not logged_in: for retry in range(3): try: GlobalVars.cookies[site] = client.login(username, password) break except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() log( 'debug', 'chat.{}: Login error {}: {}'.format( site, exc_type.__name__, exc_obj)) if exc_type.__name__ == 'LoginError' and str( exc_obj) == 'fkey input not found': # ChatExchange didn't find the `fkey` <input> in the SE login page. Under most operating # conditions, this means that we've either lost connectivity to SE entirely or SE # is in read-only mode and isn't accepting login attempts. Under those conditions, # there's nothing which we or SD can do other than wait for SE to resolve the issue. # So, instead of spinning the CPU hard in order to retry at the maximum rate, we delay a bit. # The situations where the problem is on our end rather than on SE's end tend sleep_time = 30 * (retry + 1) log( 'warning', 'Login to SE appears unavailable. Can be caused by: SD config issue,' + ' bad network connection, or Stack Exchange is down/read-only.' + ' Sleeping for {} seconds.'.format(sleep_time)) time.sleep(sleep_time) else: raise Exception("Failed to log into " + site + ", max retries exceeded") _clients[site] = client if os.path.exists("rooms_custom.yml"): parse_room_config("rooms_custom.yml") else: parse_room_config("rooms.yml") if not GlobalVars.standby_mode: join_command_rooms() if datahandling.has_pickle("messageData.p"): try: _last_messages = datahandling.load_pickle("messageData.p") except EOFError: pass threading.Thread(name="pickle ---rick--- runner", target=pickle_last_messages, daemon=True).start() threading.Thread(name="message sender", target=send_messages, daemon=True).start() if try_cookies: datahandling.dump_cookies()