# Path: invoker.py
# class ReplyObject:
#     """ Class for returning information from a command to the core program.
# 
#     Parameters used for creating this class defines the behaviour of the main
#     program when it comes across the reply object.
# 
#     Attributes:
#         text: str, the content of the reply.
#         samePlace: bool, if the response will always be in pm or where the command
#         was said.
#         ignoreEscaping: bool, default every reply is escaped to not allow
#         arbitrary commands to be executed through replies. Some commands require
#         to be able to use PS commands, which is when this should be overwritten.
#         ignoreBroadcastPermission: bool, ignore the global broadcast permission
#         for the reply if this is true.
#         gameCommand: bool, unused, pending removal.
#         canPmReply: bool, override the default request for users without broadcast
#         permission to pm the command and instead return the result of the action.
#         isException: bool, if a command throws an exception this will be true.
#     """
#     def __init__(self, res = '', reply = False, escape = False, broadcast = False, game = False, pmreply = False, ignoreml = False):
#         self.text = str(res)
#         self.samePlace = reply
#         self.ignoreEscaping = escape
#         self.ignoreBroadcastPermission = broadcast
#         self.ignoreMultiline = ignoreml
#         self.gameCommand = game
#         self.canPmReply = pmreply
#         self.isException = isinstance(res, Exception)
# 
#     def __eq__(self, other):
#         try:
#             return (self.text == other.text
#                 and self.samePlace == other.samePlace
#                 and self.ignoreEscaping == other.ignoreEscaping
#                 and self.ignoreBroadcastPermission == other.ignoreBroadcastPermission
#                 and self.ignoreMultiline == other.ignoreMultiline
#                 and self.gameCommand == other.gameCommand
#                 and self.canPmReply == other.canPmReply
#                 and self.isException == other.isException
#             )
#         except:
#             # This only happens if the other object isn't a matching object
#             return False
# 
#     def response(self, text):
#         self.text = text
#         return self
#     def extra(self, text):
#         self.text += text
#         return self
# 
# class Command:
#     """ Wrapper class that every command should use when being created.
# 
#     The default run method should never be called, and any instance of the
#     class should override this method on creation of the instance.
# 
#     Commands should also implement any private methods they may need for completion
# 
#     Attributes:
#         cmdTriggers: List, list of every trigger that should be used to invoke
#         this method.
#         altHtml: Bool, true if the command has alternate output if HTML is supported.
#     """
#     def __init__(self, triggers, nonAbsRun = None, html = False):
#         self.cmdTriggers = triggers
#         self.altHtml = html
#         self.hasBroadcastAlt = False
#         # This will hide the default run method if it is given on object creation
#         self.run = nonAbsRun if nonAbsRun else self.run
#     def run(self, robot, cmd, room, params, user):
#         """Abstract method for executing a command after it has been found. Each command
#         has to reimplement this function to work.
# 
#         Args:
#             robot: PokemonShowdownBot, the instance of PokemonShowdownBot that called this function.
#             cmd: string, the command that was send.
#             room: Room, the room object that the command was sent from.
#             params: string, additional paramters that the command may need.
#             user: User, the user object of the user who sent the command.
#         Returns:
#             ReplyObject.
#         Raises:
#             NotImplementedError if not implemented, otherwise unknown. """
#         raise NotImplementedError('Command#run method not implemented')
# 
# Path: plugins/games.py
# class GenericGame:
#     def __init__(self, ws, room):
#         self.ws = ws
#         self.room = room
#     def isThisGame(self, game):
#         return type(self) == game


import requests
from invoker import ReplyObject, Command
from plugins.games import GenericGame

    def pasteLog(self, room, apiKey):
        if apiKey == '0': return 'No paste for the workshop could be generated'
        with open('logs/{room}-workshop-{host}.txt'.format(room = room, host = self.host), 'r') as log:
            r = requests.post('https://pastebin.com/api/api_post.php',
                            data = {
                                'api_dev_key': apiKey,
                                'api_option':'paste',
                                'api_paste_code': log.read(),
                                'api_paste_private': 0,
                                'api_paste_expire_date':'N'
                                })
            if 'Bad API request' in r.text:
                return 'Something went wrong ({error})'.format(error = r.text)
            return r.text
    def hasHostingRights(self, user):
        return self.host == user.id or user.hasRank('@')


def timestampWorkshopHandler(self, room, timestamp, user, *text):
    user = room.getUser(self.toId(user))
    if type(room.activity) == Workshop:
        room.activity.logSession(room.title, user.rank + user.name, '|'.join(text))

def workshopHandler(self, room, user, *text):
    timestampWorkshopHandler(self, room, 0, user, *text) # timestamp doesn't matter here

def workshopCommands(bot, cmd, msg, user, room):
    reply = ReplyObject('', True)
    if msg.startswith('new'):

# Path: invoker.py
# class ReplyObject:
#     """ Class for returning information from a command to the core program.
# 
#     Parameters used for creating this class defines the behaviour of the main
#     program when it comes across the reply object.
# 
#     Attributes:
#         text: str, the content of the reply.
#         samePlace: bool, if the response will always be in pm or where the command
#         was said.
#         ignoreEscaping: bool, default every reply is escaped to not allow
#         arbitrary commands to be executed through replies. Some commands require
#         to be able to use PS commands, which is when this should be overwritten.
#         ignoreBroadcastPermission: bool, ignore the global broadcast permission
#         for the reply if this is true.
#         gameCommand: bool, unused, pending removal.
#         canPmReply: bool, override the default request for users without broadcast
#         permission to pm the command and instead return the result of the action.
#         isException: bool, if a command throws an exception this will be true.
#     """
#     def __init__(self, res = '', reply = False, escape = False, broadcast = False, game = False, pmreply = False, ignoreml = False):
#         self.text = str(res)
#         self.samePlace = reply
#         self.ignoreEscaping = escape
#         self.ignoreBroadcastPermission = broadcast
#         self.ignoreMultiline = ignoreml
#         self.gameCommand = game
#         self.canPmReply = pmreply
#         self.isException = isinstance(res, Exception)
# 
#     def __eq__(self, other):
#         try:
#             return (self.text == other.text
#                 and self.samePlace == other.samePlace
#                 and self.ignoreEscaping == other.ignoreEscaping
#                 and self.ignoreBroadcastPermission == other.ignoreBroadcastPermission
#                 and self.ignoreMultiline == other.ignoreMultiline
#                 and self.gameCommand == other.gameCommand
#                 and self.canPmReply == other.canPmReply
#                 and self.isException == other.isException
#             )
#         except:
#             # This only happens if the other object isn't a matching object
#             return False
# 
#     def response(self, text):
#         self.text = text
#         return self
#     def extra(self, text):
#         self.text += text
#         return self
# 
# class Command:
#     """ Wrapper class that every command should use when being created.
# 
#     The default run method should never be called, and any instance of the
#     class should override this method on creation of the instance.
# 
#     Commands should also implement any private methods they may need for completion
# 
#     Attributes:
#         cmdTriggers: List, list of every trigger that should be used to invoke
#         this method.
#         altHtml: Bool, true if the command has alternate output if HTML is supported.
#     """
#     def __init__(self, triggers, nonAbsRun = None, html = False):
#         self.cmdTriggers = triggers
#         self.altHtml = html
#         self.hasBroadcastAlt = False
#         # This will hide the default run method if it is given on object creation
#         self.run = nonAbsRun if nonAbsRun else self.run
#     def run(self, robot, cmd, room, params, user):
#         """Abstract method for executing a command after it has been found. Each command
#         has to reimplement this function to work.
# 
#         Args:
#             robot: PokemonShowdownBot, the instance of PokemonShowdownBot that called this function.
#             cmd: string, the command that was send.
#             room: Room, the room object that the command was sent from.
#             params: string, additional paramters that the command may need.
#             user: User, the user object of the user who sent the command.
#         Returns:
#             ReplyObject.
#         Raises:
#             NotImplementedError if not implemented, otherwise unknown. """
#         raise NotImplementedError('Command#run method not implemented')
# 
# Path: plugins/games.py
# class GenericGame:
#     def __init__(self, ws, room):
#         self.ws = ws
#         self.room = room
#     def isThisGame(self, game):
#         return type(self) == game


# Path: plugins/workshop.py
import requests
from invoker import ReplyObject, Command
from plugins.games import GenericGame


    def pasteLog(self, room, apiKey):
        if apiKey == '0': return 'No paste for the workshop could be generated'
        with open('logs/{room}-workshop-{host}.txt'.format(room = room, host = self.host), 'r') as log:
            r = requests.post('https://pastebin.com/api/api_post.php',
                            data = {
                                'api_dev_key': apiKey,
                                'api_option':'paste',
                                'api_paste_code': log.read(),
                                'api_paste_private': 0,
                                'api_paste_expire_date':'N'
                                })
            if 'Bad API request' in r.text:
                return 'Something went wrong ({error})'.format(error = r.text)
            return r.text
    def hasHostingRights(self, user):
        return self.host == user.id or user.hasRank('@')


def timestampWorkshopHandler(self, room, timestamp, user, *text):
    user = room.getUser(self.toId(user))
    if type(room.activity) == Workshop:
        room.activity.logSession(room.title, user.rank + user.name, '|'.join(text))

def workshopHandler(self, room, user, *text):
    timestampWorkshopHandler(self, room, 0, user, *text) # timestamp doesn't matter here

def workshopCommands(bot, cmd, msg, user, room):
    reply = ReplyObject('', True)
    if msg.startswith('new'):

        if not user.hasRank('@'): return reply.response("You don't have permission to start workshops (Requires @)")