<commit_before>#---------------------------------------
#	Import Libraries
#---------------------------------------
import os
import codecs
import json
import time
import threading

#---------------------------------------
#	[Required]	Script Information
#---------------------------------------
ScriptName = "Rank Change Announcer"
Website = "https://www.github.com/hyperneon"
Creator = "GameTangent"
Version = "1.4.0"
Description = "Announce in chat when a user changes ranks"

#---------------------------------------
#	Set Variables
#---------------------------------------
SettingsFile = os.path.join(os.path.dirname(__file__), "RCASettings.json")

#---------------------------------------
# Classes
#---------------------------------------
class Settings(object):
    """ Load in saved settings file if available else set default values. """
    def __init__(self, settingsfile=None):
        try:
            with codecs.open(settingsfile, encoding="utf-8-sig", mode="r") as f:
                self.__dict__ = json.load(f, encoding="utf-8")
        except:
                self.rank_up_message = "KAPOW Congrats to {0} for LEVELING UP to {1} KAPOW"
                self.rank_down_message = "FailFish {0} is slacking and leveled down to {1} FailFish"
                self.announcer_timer = 30
                self.rank_system = "Points"
                self.use_streamlabs_currency = False
                self.announce_rank_ups = True
                self.announce_rank_downs = False
                self.announce_lurkers = False

    def reload(self, jsondata):
        """ Reload settings from Chatbot user interface by given json data. """
        self.__dict__ = json.loads(jsondata, encoding="utf-8")
        return

    def save(self, settingsfile):
        """ Save settings contained within to .json and .js settings files. """
        try:
            with codecs.open(settingsfile, encoding="utf-8-sig", mode="w+") as f:
                json.dump(self.__dict__, f, encoding="utf-8")
            with codecs.open(settingsfile.replace("json", "js"), encoding="utf-8-sig", mode="w+") as f:
                f.write("var settings = {0};".format(json.dumps(self.__dict__, encoding='utf-8')))
        except:
            Parent.Log(ScriptName, "Failed to save settings to file.")
        return

#---------------------------------------
#	Functions
#---------------------------------------
def ProcessAndSendAlerts(new_ranks, last_ranks):
    """ Processes the ranks in a thread """
    rank_changes = CalculateRankChanges(new_ranks, last_ranks)
        
    # Iterate over each rank_change and send chat messages if enabled
    for name, rank_details in rank_changes.items():
        if rank_details['level_up']:
            if ScriptSettings.announce_rank_ups:
                Parent.SendTwitchMessage(ScriptSettings.rank_up_message.format(name, rank_details['rank']))
        else:
            if ScriptSettings.announce_rank_downs:
                Parent.SendTwitchMessage(ScriptSettings.rank_down_message.format(name, rank_details['rank']))
    return

def GetRankList():
    """
        GetRankList is a function that retrieves the full list of viewers and then looks up their
        ranks and points. It returns a dictionary with the following structure:
        {user_name: {'rank': rank, 'points': points}}
        If ScriptSettings.announce_lurkers is false it will only return active users
    """
    # If announce_lurkers is true then get the full Viewer list
    if ScriptSettings.announce_lurkers:
        viewers = Parent.GetViewerList()
    else:
        viewers = Parent.GetActiveUsers()
        
    ranks = BuildRankHash(viewers)
    points = Parent.GetPointsAll(viewers)
    names = Parent.GetDisplayNames(viewers)
    
    rank_list = {}   
    for id,name in names.items():
        try:
            rank_list[name] = {'rank': ranks[id], 'points': points[id]}
        except:
            Parent.Log(ScriptName, "Failed to get Rank or Points for User: " + name + "  Please check if the user exists in the Users tab")
            continue
    
    return rank_list
    
def BuildRankHash(viewers):
    """
        Since the introduction of the StreamLabs Chatbot, GetRanksAll no longer works if the bot is set
        to use Streamlabs Extension Currency. As a workaround, we can build the PythonDictionary ourselves one by one
        at the cost of performance. We only need to do this if use_streamlabs_currency == true.
    """
    if ScriptSettings.use_streamlabs_currency:<commit_msg>Use GetDisplayName for every id rather than GetDisplayNames with a list of ids<commit_after>#---------------------------------------
#	Import Libraries
#---------------------------------------
import os
import codecs
import json
import time
import threading

#---------------------------------------
#	[Required]	Script Information
#---------------------------------------
ScriptName = "Rank Change Announcer"
Website = "https://www.github.com/hyperneon"
Creator = "GameTangent"
Version = "1.4.1"
Description = "Announce in chat when a user changes ranks"

#---------------------------------------
#	Set Variables
#---------------------------------------
SettingsFile = os.path.join(os.path.dirname(__file__), "RCASettings.json")

#---------------------------------------
# Classes
#---------------------------------------
class Settings(object):
    """ Load in saved settings file if available else set default values. """
    def __init__(self, settingsfile=None):
        try:
            with codecs.open(settingsfile, encoding="utf-8-sig", mode="r") as f:
                self.__dict__ = json.load(f, encoding="utf-8")
        except:
                self.rank_up_message = "KAPOW Congrats to {0} for LEVELING UP to {1} KAPOW"
                self.rank_down_message = "FailFish {0} is slacking and leveled down to {1} FailFish"
                self.announcer_timer = 30
                self.rank_system = "Points"
                self.use_streamlabs_currency = False
                self.announce_rank_ups = True
                self.announce_rank_downs = False
                self.announce_lurkers = False

    def reload(self, jsondata):
        """ Reload settings from Chatbot user interface by given json data. """
        self.__dict__ = json.loads(jsondata, encoding="utf-8")
        return

    def save(self, settingsfile):
        """ Save settings contained within to .json and .js settings files. """
        try:
            with codecs.open(settingsfile, encoding="utf-8-sig", mode="w+") as f:
                json.dump(self.__dict__, f, encoding="utf-8")
            with codecs.open(settingsfile.replace("json", "js"), encoding="utf-8-sig", mode="w+") as f:
                f.write("var settings = {0};".format(json.dumps(self.__dict__, encoding='utf-8')))
        except:
            Parent.Log(ScriptName, "Failed to save settings to file.")
        return

#---------------------------------------
#	Functions
#---------------------------------------
def ProcessAndSendAlerts(new_ranks, last_ranks):
    """ Processes the ranks in a thread """
    rank_changes = CalculateRankChanges(new_ranks, last_ranks)
        
    # Iterate over each rank_change and send chat messages if enabled
    for name, rank_details in rank_changes.items():
        if rank_details['level_up']:
            if ScriptSettings.announce_rank_ups:
                Parent.SendTwitchMessage(ScriptSettings.rank_up_message.format(name, rank_details['rank']))
        else:
            if ScriptSettings.announce_rank_downs:
                Parent.SendTwitchMessage(ScriptSettings.rank_down_message.format(name, rank_details['rank']))
    return

def GetRankList():
    """
        GetRankList is a function that retrieves the full list of viewers and then looks up their
        ranks and points. It returns a dictionary with the following structure:
        {user_name: {'rank': rank, 'points': points}}
        If ScriptSettings.announce_lurkers is false it will only return active users
    """
    # If announce_lurkers is true then get the full Viewer list
    if ScriptSettings.announce_lurkers:
        viewers = Parent.GetViewerList()
    else:
        viewers = Parent.GetActiveUsers()
        
    ranks = BuildRankHash(viewers)
    points = Parent.GetPointsAll(viewers)
    
    rank_list = {}   
    for id in viewers:
        try:
            rank_list[Parent.GetDisplayName(id)] = {'rank': ranks[id], 'points': points[id]}
        except:
            Parent.Log(ScriptName, "Failed to get Rank or Points for User: " + name + "  Please check if the user exists in the Users tab")
            continue
    
    return rank_list
    
def BuildRankHash(viewers):
    """
        Since the introduction of the StreamLabs Chatbot, GetRanksAll no longer works if the bot is set
        to use Streamlabs Extension Currency. As a workaround, we can build the PythonDictionary ourselves one by one
        at the cost of performance. We only need to do this if use_streamlabs_currency == true.
    """
    if ScriptSettings.use_streamlabs_currency:
{'fraction_non_alphanumeric': 0.1724898049156839, 'fraction_numerical': 0.0037473823432161357, 'mean_word_length': 2.0116163292399603, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5700627', 'n_tokens_mistral': 2424, 'n_tokens_neox': 2385, 'n_words': 719}