Package: miniirc-extras
miniirc_extrasAn extension of miniirc (GitHub,GitLab) that adds more features.Note that miniirc_extras is still in beta and there can and will be breaking
API changes before v1.0.0, and miniirc_extras may not work with older versions
of miniirc.Some features here may be merged into miniirc eventually.Loading featuresAfter importing miniirc_extras, features can be loaded withirc.require('feature_name'), and once loaded can be accessed withirc.feature_name.Featureschans: Channel mode tracking, must be loaded while miniirc is disconnected.ensure_connection:https://github.com/luk3yx/miniirc/issues/15mp:(WIP)Multiprocessing handlers for miniirc.testfeature: Debuggingusers: User tracking, must be loaded while miniirc is disconnected._json(Proof-of-concept): Parse JSON messages.irc.usersirc.usersadds rudimentary user tracking to miniirc.UserobjectsUser objects store the current user's information and user-defined data, and
can be accessed withirc.users[Hostmask]orirc.users['nick'].The following items are available inUserobjects:VariableDescriptionnickThe user's current nickname.identThe user's current ident.hostThe user's current hostname.realnameThe user'srealname.hostmaskAHostmaskobject containing the user's hostmask.raw_hostmaskA string containingnick!user@host.channelsA set containingChannelobjects for channels the user is currently in.accountA string containing the user's current NickServ account, orNoneif the user isn't logged in.avatar_urlThe avatar URL of the user. Currently only IRCCloud avatars work.You can also set and get items with strings as keys and JSON-compatible objects
as values.Userobjects have the following helper functions:FunctionDescriptionmsg(*text)Send aPRIVMSGto the user.me(*text)Send aCTCP ACTION(/me) to the user.notice(*text)Send aNOTICEto the user.kick(channel, reason='')Kicks the user fromchannel(a string orChannelobject).irc.chansirc.chansadds channel mode tracking on top ofirc.users. You can get
channels withirc.chans['#channel-name']ChannelobjectsChannelobjects have the following attributes:VariableDescriptionnameThe name of the channel.modesAModeListobject containing a list of modes.topicThe channel topic.usersAsetcontainingUserobjects for members of this channel.ModeListobjectsModeList objects store a list of modes, and have the following functions:FunctionDescriptiongetbool(mode)ReturnsTrueifmode(a single-character string) is set on the corresponding channel.Use this for+i,+t, etcgetstr(mode, default=None)Return the parametermodewas set with, otherwisedefault.Use this for+k,+l, etcgetset(mode)Return afrozensetcontaining all the entries stored inmode. If you plan to use this for modes such as+b, you may want to runMODE #channel +bwhen the bot/client joins the channel to populate the list.Use this for+b,+e,+o,+v, etchasstr(mode)ReturnsTrueifmodeis set with a single parameter, otherwiseFalse.hasset(mode)Equivalent tolen(getset(mode)) > 0.You can accessModeListobjects likedicts, however this will require
extra type checking code if you plan to use mypy or another type checker.irc.mpMultiprocessing handlers. You can create multiprocessing handlers withirc.mp.Handlerandirc.mp.CmdHandler. These handlers are called with the
limitedRestrictedIRCobject (a subclass ofAbstractIRC) instead of the
normalIRCobject.The following functions/variables work withRestrictedIRC:active_caps,channels,connect_modes,ctcp,debug,ident,ip,ircv3_caps,isupport,me,msg,nick,notice,persist,ping_interval,port,quit_message,quote,realname,ssl,verify_sslTrying to modify these variables will result in anAttributeErroror the set
operation silently failing.Misc classesAbstractIRCTheminiirc_extras.AbstractIRCclass provides an easy way to type checkIRCobjects without stub files.Hostmaskminiirc_extras adds the abstract-ish classminiirc_extras.Hostmask:fromminiirc_extrasimportHostmaskisinstance('test',Hostmask)# Falseisinstance(('nick',123,'host'),Hostmask)# Falseisinstance(('nick','user','host'),Hostmask)# TrueHostmask('nick','user','host')# ('nick', 'user', 'host')Hostmask(123456,'user','host')# TypeErrorCreating new featuresThis API will probably change in the future.You can create your own features withminiirc_extras.Feature:@miniirc_extras.Feature('feature_name')classMyFeature:deftest_func(self):print('test_func called with',self._irc)def__call__(self):print('MyFeature called with',self._irc)def__init__(self,irc):self._irc=ircOnce registered, you canrequireand use it:irc.require('feature_name')irc.feature_name()# MyFeature called with <miniirc.IRC object>irc.feature_name.test_func()# test_func called with <miniirc.IRC object>Miscellaneous functionsSome miscellaneous functions and classes are located inminiirc_extras.utils.FunctionDescriptionDummyIRC(...)A subclass ofminiirc.IRCthat cannot connect to servers.DummyIRC.__init__has no required parameters.dict_to_tags(tags)Converts a dict containing strings and booleans into an IRCv3 tags string. Example:dict_to_tags({'tag1': True, 'tag2': 'tag-data'})→b'@tag1;tag2=tag-data 'get_raw_socket(irc)Attempts to get the raw socket from an AbstractIRC object. This is not recommended, and under no circumstances should you attempt to receive data using this socket.Only use this if there is no alternative.Raises a miniirc_extras.error if no socket can be found.tags_to_dict(tag_list, separator = ';')Converts a tags list (tag1;tag2=tag-data) joined byseparatorinto adictcontaining strings and booleans.ircv3_message_parser(msg, *, colon=True)The same asminiirc.ircv3_message_parser, but also acceptsbytesandbytearrays. Thecolonkeyword argument works in the same way as thecolonkeyword argument onminiirc.Handler.hostmask_to_str(hostmask)Converts aHostmaskobject into anick!user@hoststring.ircv2_message_unparser(cmd, hostmask, tags, args, *, colon=True, encoding='utf-8')Converts miniirc-style message data into an IRCv2 message encoded withencoding(orNoneto return astr). WhencolonisFalse,args[-1]will have a colon prepended to it.ircv3_message_unparser(cmd, hostmask, tags, args, *, colon=True, encoding='utf-8')The same asircv2_message_unparser, but tags are added.namedtuple(...)Alias forcollections.namedtupleon Python 3.7+, otherwise a wrapper that addsdefaultsandmodulekeyword arguments.VersionInfo(major=0, minor=0, micro=0, releaselevel='final', serial=0)Anamedtuplesimilar totype(sys.version_info).Note thatdict_to_tagsandtags_to_dictare available in miniirc as
internal functions, however they can and will change.miniirc_extras.utils.irc_from_urlAllows you to createIRCobjects from URLs, for exampleirc_from_url('irc://nick@ssl-server.example/#channel1,#channel2')will create
anIRCobject with the nicknamenick. Any keyword arguments passed toirc_from_urlare sent toIRC().miniirc_extras.utils.HandlerGroupAllows you to create a group of handlers and apply them in bulk toIRCobjects.MethodDescriptionHandler(...)Adds aHandlerto the group, uses the same syntax asirc.Handler.CmdHandler(...)Adds aCmdHandlerto the group, uses the same syntax asirc.CmdHandler.add_to(irc_or_group)Adds all the handlers in this group to an IRC object or another handler group.copy()Returns another handler group with the same handlers as this one.miniirc_extras.utils.numericsAnEnumof most of the IRC numerics inRFC 1459,RFC 2812, andmodern.ircdocs.horse. Seeminiirc_extras/_numerics.pyfor a list of
numerics and their names.Example:importminiircfromminiirc_extras.utilsimportnumerics@miniirc.Handler(numerics.RPL_WELCOME,colon=False)defhandler(irc,hostmask,args):print('Connected to IRC!')Another example:>>>fromminiirc_extras.utilsimportnumerics>>>numerics.RPL_ISUPPORT<numerics.RPL_ISUPPORT:0​0​5>>>>numerics['RPL_MOTD']<numerics.RPL_MOTD:372>>>>numerics(465)<numerics.ERR_YOUREBANNEDCREEP:465>>>>numerics('422')<numerics.ERR_NOMOTD:422>>>>str(numerics.RPL_YOURHOST)'002'miniirc_extras.aioircAn asyncio-oriented version ofminiirc.IRC. Example:importasyncio,timefromminiirc_extrasimportaioircirc=aioirc.AsyncIRC(ip,6697,nickname,'#botwar',auto_connect=False)@irc.Handler('PRIVMSG',colon=False)defhandle_privmsg(irc,hostmask,args):ifargs[0]=='#botwar'andargs[1]=='>thread_test':irc.msg(args[0],'[Thread] Waiting 1 second...')time.sleep(1)irc.msg(args[0],'[Thread] Done!')@irc.Handler('PRIVMSG',colon=False)asyncdefhandle_privmsg(irc,hostmask,args):ifargs[0]=='#botwar'andargs[1]=='>coro_test':awaitirc.msg(args[0],'[Coroutine] Waiting 1 second...')awaitasyncio.sleep(1)awaitirc.msg(args[0],'[Coroutine] Done!')if__name__=='__main__':irc.connect()asyncio.get_event_loop().run_forever()This probably doesn't need to be used unless asyncio-based libraries need to be
used.miniirc_extras.formattingText formatting. Inspired byircmessage.colours/colorsenumThecolours(orcolors) enum contains colours and their corresponding code.
Do not use these to format text, instead use the belowstyleandcolorizefunctions.StylerobjectsStyler objects are callables that apply IRC formatting to strings.miniirc_extras.formatting.Styler(fg=None,bg=None,*,bold:bool=False,italics:bool=False,underline:bool=False,reverse_colour:bool=False,strikethrough:bool=False,spoiler:bool=False,monospace:bool=False,reset:bool=True)Note thatStyleraccepts bothreverse_colourandreverse_color.fgandbgcan be strings or values from the aforementionedEnum.The parameters passed to__init__are available as attributes on the object,
for examplestyler.bold.SettingresettoFalseis not recommended, as when enabled it only resets
any changed formatting.For cleaner code, you can also useminiirc_extras.formatting.style(text, fg=None, ...).Example:fromminiirc_extrasimportformattingstyler=formatting.Styler('red',bold=True,monospace=True)msg=styler('Test message')print(styler.fg)# <colours.red: 04>print(styler.fg)# Noneprint(styler.bold)# Trueprint(repr(msg))# '\x11\x02\x0304Test message\x0399\x02\x11'msg2=formatting.style('Test message','red',bold=True,monospace=True)assertmsg==msg2# No errorprint(repr(formatting.unstyle(msg)))# 'Test message'"Lightweight" stylersThere are a number of predefinedStylers that are more efficient (if you are
only adding one style):bold=Styler(bold=True)italics=Styler(italics=True)italic=italicsunderline=Styler(underline=True)reverse_colour=Styler(reverse_colour=True)reverse_color=reverse_colourstrikethrough=Styler(strikethrough=True)monospace=Styler(monospace=True)spoiler=Styler(spoiler=True)Lightweight stylers are subclassed fromStylerand will run slightly faster,
provided you are only changing one style.You can also useminiirc_extras.formatting.colorize(text, fg)(orminiirc_extras.formatting.colourise(text, fg)) if you are only changing the
foreground colour/color for a similarly small speed improvement.Note thatformatting.style(text, 'red', bold=True)is recommended overformatting.bold(formatting.colorize(text, 'red')), as it is more readable
and probably faster.Deprecated functions.These functions still work for now but will probably be removed from
miniirc_extras v1.0.0:miniirc_extras.DummyIRCNow calledminiirc_extras.utils.DummyIRC.miniirc_extras.VersionInfoNow calledminiirc_extras.utils.VersionInfo.Other planned breaking changesTo coincide with miniirc v2.0.0, all functions that take acolonkeyword
argument here will default toFalse(instead ofTrue). This may change
in miniirc_extras v1.0.0 instead.If Python 3.5 is obsolete by the time miniirc_extras v1.0.0 is released,
support may be dropped.