Skip to content

Commit bc68707

Browse files
committed
[TO DROP] Commits from sopel-irc#2231
1 parent c37f62b commit bc68707

File tree

25 files changed

+1064
-433
lines changed

25 files changed

+1064
-433
lines changed

docs/source/api.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ sopel.tools
1010
.. automodule:: sopel.tools
1111
:members:
1212
:exclude-members: iteritems, iterkeys, itervalues, raw_input
13-
:private-members: Identifier._lower, Identifier._lower_swapped
13+
14+
15+
sopel.tools.identifiers
16+
-----------------------
17+
18+
.. automodule:: sopel.tools.identifiers
19+
:members:
20+
1421

1522
sopel.tools.web
1623
---------------

docs/source/plugin/bot.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ second argument::
2323

2424
bot.say('The bot is now talking!', '#private-channel')
2525

26-
Instead of a string, you can use an instance of :class:`sopel.tools.Identifier`.
26+
Instead of a string, you can use an instance of
27+
:class:`~sopel.tools.identifiers.Identifier`.
2728

2829
If you want to reply to a user in a private message, you can use the trigger's
2930
:attr:`~sopel.trigger.Trigger.nick` attribute as destination::
@@ -261,8 +262,8 @@ which provides the following information:
261262
if not trigger.sender.is_nick():
262263
# this trigger is from a channel
263264

264-
See :meth:`Identifier.is_nick() <sopel.tools.Identifier.is_nick>` for
265-
more information.
265+
See :meth:`Identifier.is_nick() <sopel.tools.identifiers.Identifier.is_nick>`
266+
for more information.
266267

267268
Getting users in a channel
268269
--------------------------

sopel/bot.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from sopel import db, irc, logger, plugin, plugins, tools
2323
from sopel.irc import modes
2424
from sopel.plugins import jobs as plugin_jobs, rules as plugin_rules
25-
from sopel.tools import deprecated, Identifier, jobs as tools_jobs
25+
from sopel.tools import deprecated, jobs as tools_jobs
2626
from sopel.trigger import PreTrigger, Trigger
2727

2828

@@ -81,23 +81,28 @@ def __init__(self, config, daemon=False):
8181
self.modeparser = modes.ModeParser()
8282
"""A mode parser used to parse ``MODE`` messages and modestrings."""
8383

84-
self.channels = tools.SopelIdentifierMemory()
84+
self.channels = tools.SopelIdentifierMemory(
85+
identifier_factory=self.make_identifier,
86+
)
8587
"""A map of the channels that Sopel is in.
8688
87-
The keys are :class:`sopel.tools.Identifier`\\s of the channel names,
88-
and map to :class:`sopel.tools.target.Channel` objects which contain
89-
the users in the channel and their permissions.
89+
The keys are :class:`~sopel.tools.identifiers.Identifier`\\s of the
90+
channel names, and map to :class:`~sopel.tools.target.Channel` objects
91+
which contain the users in the channel and their permissions.
9092
"""
9193

92-
self.users = tools.SopelIdentifierMemory()
94+
self.users = tools.SopelIdentifierMemory(
95+
identifier_factory=self.make_identifier,
96+
)
9397
"""A map of the users that Sopel is aware of.
9498
95-
The keys are :class:`sopel.tools.Identifier`\\s of the nicknames, and
96-
map to :class:`sopel.tools.target.User` instances. In order for Sopel
97-
to be aware of a user, it must share at least one mutual channel.
99+
The keys are :class:`~sopel.tools.identifiers.Identifier`\\s of the
100+
nicknames, and map to :class:`~sopel.tools.target.User` instances. In
101+
order for Sopel to be aware of a user, it must share at least one
102+
mutual channel.
98103
"""
99104

100-
self.db = db.SopelDB(config)
105+
self.db = db.SopelDB(config, identifier_factory=self.make_identifier)
101106
"""The bot's database, as a :class:`sopel.db.SopelDB` instance."""
102107

103108
self.memory = tools.SopelMemory()
@@ -212,9 +217,10 @@ def has_channel_privilege(self, channel, privilege) -> bool:
212217
>>> bot.has_channel_privilege('#chan', plugin.VOICE)
213218
True
214219
215-
The ``channel`` argument can be either a :class:`str` or a
216-
:class:`sopel.tools.Identifier`, as long as Sopel joined said channel.
217-
If the channel is unknown, a :exc:`ValueError` will be raised.
220+
The ``channel`` argument can be either a :class:`str` or an
221+
:class:`~sopel.tools.identifiers.Identifier`, as long as Sopel joined
222+
said channel. If the channel is unknown, a :exc:`ValueError` will be
223+
raised.
218224
"""
219225
if channel not in self.channels:
220226
raise ValueError('Unknown channel %s' % channel)
@@ -987,7 +993,7 @@ def _nick_blocked(self, nick: str) -> bool:
987993
if not bad_nick:
988994
continue
989995
if (re.match(bad_nick + '$', nick, re.IGNORECASE) or
990-
Identifier(bad_nick) == nick):
996+
self.make_identifier(bad_nick) == nick):
991997
return True
992998
return False
993999

sopel/config/core_section.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ def homedir(self):
880880
:default: ``Sopel: https://sopel.chat/``
881881
"""
882882

883-
nick = ValidatedAttribute('nick', Identifier, default=Identifier('Sopel'))
883+
nick = ValidatedAttribute('nick', default='Sopel')
884884
"""The nickname for the bot.
885885
886886
:default: ``Sopel``

sopel/coretasks.py

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
from sopel import config, plugin
3535
from sopel.irc import isupport, utils
36-
from sopel.tools import events, Identifier, jobs, SopelMemory, target
36+
from sopel.tools import events, jobs, SopelMemory, target
3737

3838

3939
LOGGER = logging.getLogger(__name__)
@@ -143,7 +143,7 @@ def auth_after_register(bot):
143143

144144
# nickserv-based auth method needs to check for current nick
145145
if auth_method == 'nickserv':
146-
if bot.nick != bot.settings.core.nick:
146+
if bot.nick != bot.make_identifier(bot.settings.core.nick):
147147
LOGGER.warning("Sending nickserv GHOST command.")
148148
bot.say(
149149
'GHOST %s %s' % (bot.settings.core.nick, auth_password),
@@ -347,6 +347,7 @@ def handle_isupport(bot, trigger):
347347
botmode_support = 'BOT' in bot.isupport
348348
namesx_support = 'NAMESX' in bot.isupport
349349
uhnames_support = 'UHNAMES' in bot.isupport
350+
casemapping_support = 'CASEMAPPING' in bot.isupport
350351

351352
# parse ISUPPORT message from server
352353
parameters = {}
@@ -367,6 +368,11 @@ def handle_isupport(bot, trigger):
367368
if 'PREFIX' in bot.isupport:
368369
bot.modeparser.privileges = set(bot.isupport.PREFIX.keys())
369370

371+
# was CASEMAPPING support status updated?
372+
if not casemapping_support and 'CASEMAPPING' in bot.isupport:
373+
# Re-create the bot's nick with the proper identifier+casemapping
374+
bot.rebuild_nick()
375+
370376
# was BOT mode support status updated?
371377
if not botmode_support and 'BOT' in bot.isupport:
372378
# yes it was! set our mode unless the config overrides it
@@ -482,9 +488,12 @@ def handle_names(bot, trigger):
482488
channels = re.search(r'(#\S*)', trigger.raw)
483489
if not channels:
484490
return
485-
channel = Identifier(channels.group(1))
491+
channel = bot.make_identifier(channels.group(1))
486492
if channel not in bot.channels:
487-
bot.channels[channel] = target.Channel(channel)
493+
bot.channels[channel] = target.Channel(
494+
channel,
495+
identifier_factory=bot.make_identifier,
496+
)
488497

489498
# This could probably be made flexible in the future, but I don't think
490499
# it'd be worth it.
@@ -515,7 +524,7 @@ def handle_names(bot, trigger):
515524
if prefix in name:
516525
priv = priv | value
517526

518-
nick = Identifier(name.lstrip(''.join(mapping.keys())))
527+
nick = bot.make_identifier(name.lstrip(''.join(mapping.keys())))
519528
user = bot.users.get(nick)
520529
if user is None:
521530
# The username/hostname will be included in a NAMES reply only if
@@ -559,7 +568,7 @@ def _parse_modes(bot, args, clear=False):
559568
modes at https://modern.ircdocs.horse/#channel-mode
560569
561570
"""
562-
channel_name = Identifier(args[0])
571+
channel_name = bot.make_identifier(args[0])
563572
if channel_name.is_nick():
564573
# We don't do anything with user modes
565574
LOGGER.debug("Ignoring user modes: %r", args)
@@ -622,7 +631,7 @@ def _parse_modes(bot, args, clear=False):
622631
# modeinfo.privileges contains only the valid parsed privileges
623632
for privilege, is_added, param in modeinfo.privileges:
624633
# User privs modes, always have a param
625-
nick = Identifier(param)
634+
nick = bot.make_identifier(param)
626635
priv = channel.privileges.get(nick, 0)
627636
value = MODE_PREFIX_PRIVILEGES[privilege]
628637
if is_added:
@@ -659,7 +668,7 @@ def _parse_modes(bot, args, clear=False):
659668
def track_nicks(bot, trigger):
660669
"""Track nickname changes and maintain our chanops list accordingly."""
661670
old = trigger.nick
662-
new = Identifier(trigger)
671+
new = bot.make_identifier(trigger)
663672

664673
# Give debug message, and PM the owner, if the bot's own nick changes.
665674
if old == bot.nick and new != bot.nick:
@@ -705,7 +714,7 @@ def track_part(bot, trigger):
705714
@plugin.priority('medium')
706715
def track_kick(bot, trigger):
707716
"""Track users kicked from channels."""
708-
nick = Identifier(trigger.args[1])
717+
nick = bot.make_identifier(trigger.args[1])
709718
channel = trigger.sender
710719
_remove_from_channel(bot, nick, channel)
711720
LOGGER.info(
@@ -748,7 +757,9 @@ def _send_who(bot, channel):
748757
# We might be on an old network, but we still care about keeping our
749758
# user list updated
750759
bot.write(['WHO', channel])
751-
bot.channels[Identifier(channel)].last_who = datetime.datetime.utcnow()
760+
761+
channel_id = bot.make_identifier(channel)
762+
bot.channels[channel_id].last_who = datetime.datetime.utcnow()
752763

753764

754765
@plugin.interval(30)
@@ -793,7 +804,10 @@ def track_join(bot, trigger):
793804

794805
# is it a new channel?
795806
if channel not in bot.channels:
796-
bot.channels[channel] = target.Channel(channel)
807+
bot.channels[channel] = target.Channel(
808+
channel,
809+
identifier_factory=bot.make_identifier,
810+
)
797811

798812
# did *we* just join?
799813
if trigger.nick == bot.nick:
@@ -836,7 +850,8 @@ def track_quit(bot, trigger):
836850

837851
LOGGER.info("User quit: %s", trigger.nick)
838852

839-
if trigger.nick == bot.settings.core.nick and trigger.nick != bot.nick:
853+
configured_nick = bot.make_identifier(bot.settings.core.nick)
854+
if trigger.nick == configured_nick and trigger.nick != bot.nick:
840855
# old nick is now available, let's change nick again
841856
bot.change_current_nick(bot.settings.core.nick)
842857
auth_after_register(bot)
@@ -1229,7 +1244,7 @@ def blocks(bot, trigger):
12291244
}
12301245

12311246
masks = set(s for s in bot.config.core.host_blocks if s != '')
1232-
nicks = set(Identifier(nick)
1247+
nicks = set(bot.make_identifier(nick)
12331248
for nick in bot.config.core.nick_blocks
12341249
if nick != '')
12351250
text = trigger.group().split()
@@ -1266,10 +1281,11 @@ def blocks(bot, trigger):
12661281

12671282
elif len(text) == 4 and text[1] == "del":
12681283
if text[2] == "nick":
1269-
if Identifier(text[3]) not in nicks:
1284+
nick = bot.make_identifier(text[3])
1285+
if nick not in nicks:
12701286
bot.reply(STRINGS['no_nick'] % (text[3]))
12711287
return
1272-
nicks.remove(Identifier(text[3]))
1288+
nicks.remove(nick)
12731289
bot.config.core.nick_blocks = [str(n) for n in nicks]
12741290
bot.config.save()
12751291
bot.reply(STRINGS['success_del'] % (text[3]))
@@ -1352,8 +1368,8 @@ def recv_whox(bot, trigger):
13521368

13531369

13541370
def _record_who(bot, channel, user, host, nick, account=None, away=None, modes=None):
1355-
nick = Identifier(nick)
1356-
channel = Identifier(channel)
1371+
nick = bot.make_identifier(nick)
1372+
channel = bot.make_identifier(channel)
13571373
if nick not in bot.users:
13581374
usr = target.User(nick, user, host)
13591375
bot.users[nick] = usr
@@ -1383,7 +1399,11 @@ def _record_who(bot, channel, user, host, nick, account=None, away=None, modes=N
13831399
for c in modes:
13841400
priv = priv | mapping[c]
13851401
if channel not in bot.channels:
1386-
bot.channels[channel] = target.Channel(channel)
1402+
bot.channels[channel] = target.Channel(
1403+
channel,
1404+
identifier_factory=bot.make_identifier,
1405+
)
1406+
13871407
bot.channels[channel].add_user(usr, privs=priv)
13881408

13891409

0 commit comments

Comments
 (0)