Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
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()