Compare commits
	
		
			7 Commits
		
	
	
		
			0ea54a5ee2
			...
			f898f35ce6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f898f35ce6 | |||
| 4289f95800 | |||
| 572ecddceb | |||
| 3aadde4b71 | |||
| c2d26f404e | |||
| ecaabbce89 | |||
| 051e656a82 | 
							
								
								
									
										222
									
								
								ircbot/bot.py
									
									
									
									
									
								
							
							
						
						
									
										222
									
								
								ircbot/bot.py
									
									
									
									
									
								
							| @ -1,46 +1,36 @@ | |||||||
| """Provide the base IRC client bot which other code can latch onto.""" | """Provide the base IRC client bot which other code can latch onto.""" | ||||||
| 
 |  | ||||||
| import bisect | import bisect | ||||||
| import collections | import collections | ||||||
| import copy | import copy | ||||||
| import importlib | import importlib | ||||||
| import logging | import logging | ||||||
| import re | import re | ||||||
| from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler |  | ||||||
| import socket | import socket | ||||||
| import ssl | import ssl | ||||||
| import sys | import sys | ||||||
| import threading | import threading | ||||||
| import time | import time | ||||||
|  | from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer | ||||||
| 
 | 
 | ||||||
| from django.conf import settings |  | ||||||
| 
 |  | ||||||
| import irc.buffer |  | ||||||
| import irc.client | import irc.client | ||||||
|  | import irc.modes | ||||||
|  | from irc.bot import Channel | ||||||
| from irc.connection import Factory | from irc.connection import Factory | ||||||
| from irc.dict import IRCDict | from irc.dict import IRCDict | ||||||
| import irc.modes | from jaraco.stream import buffer | ||||||
| 
 | 
 | ||||||
| import ircbot.lib as ircbotlib | import ircbot.lib as ircbotlib | ||||||
|  | from dr_botzo import __version__ | ||||||
| from ircbot.models import Alias, IrcChannel, IrcPlugin, IrcServer | from ircbot.models import Alias, IrcChannel, IrcPlugin, IrcServer | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| log = logging.getLogger('ircbot.bot') | log = logging.getLogger('ircbot.bot') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class IrcBotXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): |  | ||||||
|     """Override the basic request handler to change the logging.""" |  | ||||||
| 
 |  | ||||||
|     def log_message(self, format, *args): |  | ||||||
|         """Use a logger rather than stderr.""" |  | ||||||
|         log.debug("XML-RPC - %s - %s", self.client_address[0], format % args) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class PrioritizedRegexHandler(collections.namedtuple('Base', ('priority', 'regex', 'callback'))): | class PrioritizedRegexHandler(collections.namedtuple('Base', ('priority', 'regex', 'callback'))): | ||||||
|     """Regex handler that still uses the normal handler priority stuff.""" |     """Regex handler that still uses the normal handler priority stuff.""" | ||||||
| 
 | 
 | ||||||
|     def __lt__(self, other): |     def __lt__(self, other): | ||||||
|         """When sorting prioritized handlers, only use the priority""" |         """When sorting prioritized handlers, only use the priority.""" | ||||||
|         return self.priority < other.priority |         return self.priority < other.priority | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -52,7 +42,7 @@ class LenientServerConnection(irc.client.ServerConnection): | |||||||
|     method on a Reactor object. |     method on a Reactor object. | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     buffer_class = irc.buffer.LenientDecodingLineBuffer |     buffer_class = buffer.LenientDecodingLineBuffer | ||||||
| 
 | 
 | ||||||
|     server_config = None |     server_config = None | ||||||
| 
 | 
 | ||||||
| @ -65,6 +55,9 @@ class LenientServerConnection(irc.client.ServerConnection): | |||||||
| class DrReactor(irc.client.Reactor): | class DrReactor(irc.client.Reactor): | ||||||
|     """Customize the basic IRC library's Reactor with more features.""" |     """Customize the basic IRC library's Reactor with more features.""" | ||||||
| 
 | 
 | ||||||
|  |     # used by Reactor.server() to initialize | ||||||
|  |     connection_class = LenientServerConnection | ||||||
|  | 
 | ||||||
|     def __do_nothing(*args, **kwargs): |     def __do_nothing(*args, **kwargs): | ||||||
|         pass |         pass | ||||||
| 
 | 
 | ||||||
| @ -73,18 +66,10 @@ class DrReactor(irc.client.Reactor): | |||||||
|         super(DrReactor, self).__init__(on_connect=on_connect, on_disconnect=on_disconnect) |         super(DrReactor, self).__init__(on_connect=on_connect, on_disconnect=on_disconnect) | ||||||
|         self.regex_handlers = {} |         self.regex_handlers = {} | ||||||
| 
 | 
 | ||||||
|     def server(self): |  | ||||||
|         """Creates and returns a ServerConnection object.""" |  | ||||||
|         c = LenientServerConnection(self) |  | ||||||
|         with self.mutex: |  | ||||||
|             self.connections.append(c) |  | ||||||
|         return c |  | ||||||
| 
 |  | ||||||
|     def add_global_regex_handler(self, events, regex, handler, priority=0): |     def add_global_regex_handler(self, events, regex, handler, priority=0): | ||||||
|         """Adds a global handler function for a specific event type and regex. |         """Add a global handler function for a specific event type and regex. | ||||||
| 
 | 
 | ||||||
|         Arguments: |         Arguments: | ||||||
| 
 |  | ||||||
|             events --- Event type(s) (a list of strings). |             events --- Event type(s) (a list of strings). | ||||||
| 
 | 
 | ||||||
|             handler -- Callback function taking connection and event |             handler -- Callback function taking connection and event | ||||||
| @ -114,10 +99,9 @@ class DrReactor(irc.client.Reactor): | |||||||
|                 bisect.insort(event_regex_handlers, handler) |                 bisect.insort(event_regex_handlers, handler) | ||||||
| 
 | 
 | ||||||
|     def remove_global_regex_handler(self, events, handler): |     def remove_global_regex_handler(self, events, handler): | ||||||
|         """Removes a global regex handler function. |         """Remove a global regex handler function. | ||||||
| 
 | 
 | ||||||
|         Arguments: |         Arguments: | ||||||
| 
 |  | ||||||
|             events -- Event type(s) (a list of strings). |             events -- Event type(s) (a list of strings). | ||||||
|             handler -- Callback function. |             handler -- Callback function. | ||||||
| 
 | 
 | ||||||
| @ -228,8 +212,7 @@ class DrReactor(irc.client.Reactor): | |||||||
|                     if result == "NO MORE": |                     if result == "NO MORE": | ||||||
|                         return |                         return | ||||||
|         except Exception as ex: |         except Exception as ex: | ||||||
|             log.error("caught exception!") |             log.exception("caught exception!") | ||||||
|             log.exception(ex) |  | ||||||
|             connection.privmsg(event.target, str(ex)) |             connection.privmsg(event.target, str(ex)) | ||||||
| 
 | 
 | ||||||
|     def try_recursion(self, connection, event): |     def try_recursion(self, connection, event): | ||||||
| @ -416,7 +399,7 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
| 
 | 
 | ||||||
|         # load XML-RPC server |         # load XML-RPC server | ||||||
|         self.xmlrpc = SimpleXMLRPCServer((self.server_config.xmlrpc_host, self.server_config.xmlrpc_port), |         self.xmlrpc = SimpleXMLRPCServer((self.server_config.xmlrpc_host, self.server_config.xmlrpc_port), | ||||||
|                                          requestHandler=IrcBotXMLRPCRequestHandler, allow_none=True) |                                          requestHandler=SimpleXMLRPCRequestHandler, allow_none=True) | ||||||
|         self.xmlrpc.register_introspection_functions() |         self.xmlrpc.register_introspection_functions() | ||||||
| 
 | 
 | ||||||
|         t = threading.Thread(target=self._xmlrpc_listen, args=()) |         t = threading.Thread(target=self._xmlrpc_listen, args=()) | ||||||
| @ -429,8 +412,7 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
| 
 | 
 | ||||||
|     def _connected_checker(self): |     def _connected_checker(self): | ||||||
|         if not self.connection.is_connected(): |         if not self.connection.is_connected(): | ||||||
|             self.connection.execute_delayed(self.reconnection_interval, |             self.reactor.scheduler.execute_after(self.reconnection_interval, self._connected_checker) | ||||||
|                                             self._connected_checker) |  | ||||||
|             self.jump_server() |             self.jump_server() | ||||||
| 
 | 
 | ||||||
|     def _connect(self): |     def _connect(self): | ||||||
| @ -448,8 +430,7 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
| 
 | 
 | ||||||
|     def _on_disconnect(self, c, e): |     def _on_disconnect(self, c, e): | ||||||
|         self.channels = IRCDict() |         self.channels = IRCDict() | ||||||
|         self.connection.execute_delayed(self.reconnection_interval, |         self.reactor.scheduler.execute_after(self.reconnection_interval, self._connected_checker) | ||||||
|                                         self._connected_checker) |  | ||||||
| 
 | 
 | ||||||
|     def _on_join(self, c, e): |     def _on_join(self, c, e): | ||||||
|         ch = e.target |         ch = e.target | ||||||
| @ -558,7 +539,7 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
| 
 | 
 | ||||||
|         for chan in IrcChannel.objects.filter(autojoin=True, server=connection.server_config): |         for chan in IrcChannel.objects.filter(autojoin=True, server=connection.server_config): | ||||||
|             log.info("autojoining %s", chan.name) |             log.info("autojoining %s", chan.name) | ||||||
|             self.connection.join(chan) |             self.connection.join(chan.name) | ||||||
| 
 | 
 | ||||||
|         for plugin in IrcPlugin.objects.filter(autoload=True): |         for plugin in IrcPlugin.objects.filter(autoload=True): | ||||||
|             log.info("autoloading %s", plugin.path) |             log.info("autoloading %s", plugin.path) | ||||||
| @ -592,12 +573,11 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
|         self.connection.disconnect(msg) |         self.connection.disconnect(msg) | ||||||
| 
 | 
 | ||||||
|     def get_version(self): |     def get_version(self): | ||||||
|         """Returns the bot version. |         """Return the bot version. | ||||||
| 
 | 
 | ||||||
|         Used when answering a CTCP VERSION request. |         Used when answering a CTCP VERSION request. | ||||||
|         """ |         """ | ||||||
|         return "Python irc.bot ({version})".format( |         return f"dr.botzo {__version__}" | ||||||
|             version=irc.client.VERSION_STRING) |  | ||||||
| 
 | 
 | ||||||
|     def jump_server(self, msg="Changing servers"): |     def jump_server(self, msg="Changing servers"): | ||||||
|         """Connect to a new server, potentially disconnecting from the current one.""" |         """Connect to a new server, potentially disconnecting from the current one.""" | ||||||
| @ -607,7 +587,7 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
|         self._connect() |         self._connect() | ||||||
| 
 | 
 | ||||||
|     def on_ctcp(self, c, e): |     def on_ctcp(self, c, e): | ||||||
|         """Default handler for ctcp events. |         """Handle for ctcp events. | ||||||
| 
 | 
 | ||||||
|         Replies to VERSION and PING requests and relays DCC requests |         Replies to VERSION and PING requests and relays DCC requests | ||||||
|         to the on_dccchat method. |         to the on_dccchat method. | ||||||
| @ -997,165 +977,3 @@ class IRCBot(irc.client.SimpleIRCClient): | |||||||
|             del sys.modules[path] |             del sys.modules[path] | ||||||
| 
 | 
 | ||||||
|         self.die(msg="Shutting down...") |         self.die(msg="Shutting down...") | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Channel(object): |  | ||||||
|     """A class for keeping information about an IRC channel.""" |  | ||||||
| 
 |  | ||||||
|     def __init__(self): |  | ||||||
|         """Initialize channel object.""" |  | ||||||
|         self.userdict = IRCDict() |  | ||||||
|         self.operdict = IRCDict() |  | ||||||
|         self.voiceddict = IRCDict() |  | ||||||
|         self.ownerdict = IRCDict() |  | ||||||
|         self.halfopdict = IRCDict() |  | ||||||
|         self.modes = {} |  | ||||||
| 
 |  | ||||||
|     def users(self): |  | ||||||
|         """Returns an unsorted list of the channel's users.""" |  | ||||||
|         return list(self.userdict.keys()) |  | ||||||
| 
 |  | ||||||
|     def opers(self): |  | ||||||
|         """Returns an unsorted list of the channel's operators.""" |  | ||||||
|         return list(self.operdict.keys()) |  | ||||||
| 
 |  | ||||||
|     def voiced(self): |  | ||||||
|         """Returns an unsorted list of the persons that have voice mode set in the channel.""" |  | ||||||
|         return list(self.voiceddict.keys()) |  | ||||||
| 
 |  | ||||||
|     def owners(self): |  | ||||||
|         """Returns an unsorted list of the channel's owners.""" |  | ||||||
|         return list(self.ownerdict.keys()) |  | ||||||
| 
 |  | ||||||
|     def halfops(self): |  | ||||||
|         """Returns an unsorted list of the channel's half-operators.""" |  | ||||||
|         return list(self.halfopdict.keys()) |  | ||||||
| 
 |  | ||||||
|     def has_user(self, nick): |  | ||||||
|         """Check whether the channel has a user.""" |  | ||||||
|         return nick in self.userdict |  | ||||||
| 
 |  | ||||||
|     def is_oper(self, nick): |  | ||||||
|         """Check whether a user has operator status in the channel.""" |  | ||||||
|         return nick in self.operdict |  | ||||||
| 
 |  | ||||||
|     def is_voiced(self, nick): |  | ||||||
|         """Check whether a user has voice mode set in the channel.""" |  | ||||||
|         return nick in self.voiceddict |  | ||||||
| 
 |  | ||||||
|     def is_owner(self, nick): |  | ||||||
|         """Check whether a user has owner status in the channel.""" |  | ||||||
|         return nick in self.ownerdict |  | ||||||
| 
 |  | ||||||
|     def is_halfop(self, nick): |  | ||||||
|         """Check whether a user has half-operator status in the channel.""" |  | ||||||
|         return nick in self.halfopdict |  | ||||||
| 
 |  | ||||||
|     def add_user(self, nick): |  | ||||||
|         """Add user.""" |  | ||||||
|         self.userdict[nick] = 1 |  | ||||||
| 
 |  | ||||||
|     def remove_user(self, nick): |  | ||||||
|         """Remove user.""" |  | ||||||
|         for d in self.userdict, self.operdict, self.voiceddict: |  | ||||||
|             if nick in d: |  | ||||||
|                 del d[nick] |  | ||||||
| 
 |  | ||||||
|     def change_nick(self, before, after): |  | ||||||
|         """Handle a nick change.""" |  | ||||||
|         self.userdict[after] = self.userdict.pop(before) |  | ||||||
|         if before in self.operdict: |  | ||||||
|             self.operdict[after] = self.operdict.pop(before) |  | ||||||
|         if before in self.voiceddict: |  | ||||||
|             self.voiceddict[after] = self.voiceddict.pop(before) |  | ||||||
| 
 |  | ||||||
|     def set_userdetails(self, nick, details): |  | ||||||
|         """Set user details.""" |  | ||||||
|         if nick in self.userdict: |  | ||||||
|             self.userdict[nick] = details |  | ||||||
| 
 |  | ||||||
|     def set_mode(self, mode, value=None): |  | ||||||
|         """Set mode on the channel. |  | ||||||
| 
 |  | ||||||
|         Arguments: |  | ||||||
| 
 |  | ||||||
|             mode -- The mode (a single-character string). |  | ||||||
| 
 |  | ||||||
|             value -- Value |  | ||||||
|         """ |  | ||||||
|         if mode == "o": |  | ||||||
|             self.operdict[value] = 1 |  | ||||||
|         elif mode == "v": |  | ||||||
|             self.voiceddict[value] = 1 |  | ||||||
|         elif mode == "q": |  | ||||||
|             self.ownerdict[value] = 1 |  | ||||||
|         elif mode == "h": |  | ||||||
|             self.halfopdict[value] = 1 |  | ||||||
|         else: |  | ||||||
|             self.modes[mode] = value |  | ||||||
| 
 |  | ||||||
|     def clear_mode(self, mode, value=None): |  | ||||||
|         """Clear mode on the channel. |  | ||||||
| 
 |  | ||||||
|         Arguments: |  | ||||||
| 
 |  | ||||||
|             mode -- The mode (a single-character string). |  | ||||||
| 
 |  | ||||||
|             value -- Value |  | ||||||
|         """ |  | ||||||
|         try: |  | ||||||
|             if mode == "o": |  | ||||||
|                 del self.operdict[value] |  | ||||||
|             elif mode == "v": |  | ||||||
|                 del self.voiceddict[value] |  | ||||||
|             elif mode == "q": |  | ||||||
|                 del self.ownerdict[value] |  | ||||||
|             elif mode == "h": |  | ||||||
|                 del self.halfopdict[value] |  | ||||||
|             else: |  | ||||||
|                 del self.modes[mode] |  | ||||||
|         except KeyError: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|     def has_mode(self, mode): |  | ||||||
|         """Return if mode is in channel modes.""" |  | ||||||
|         return mode in self.modes |  | ||||||
| 
 |  | ||||||
|     def is_moderated(self): |  | ||||||
|         """Return if the channel is +m.""" |  | ||||||
|         return self.has_mode("m") |  | ||||||
| 
 |  | ||||||
|     def is_secret(self): |  | ||||||
|         """Return if the channel is +s.""" |  | ||||||
|         return self.has_mode("s") |  | ||||||
| 
 |  | ||||||
|     def is_protected(self): |  | ||||||
|         """Return if the channel is +p.""" |  | ||||||
|         return self.has_mode("p") |  | ||||||
| 
 |  | ||||||
|     def has_topic_lock(self): |  | ||||||
|         """Return if the channel is +t.""" |  | ||||||
|         return self.has_mode("t") |  | ||||||
| 
 |  | ||||||
|     def is_invite_only(self): |  | ||||||
|         """Return if the channel is +i.""" |  | ||||||
|         return self.has_mode("i") |  | ||||||
| 
 |  | ||||||
|     def has_allow_external_messages(self): |  | ||||||
|         """Return if the channel is +n.""" |  | ||||||
|         return self.has_mode("n") |  | ||||||
| 
 |  | ||||||
|     def has_limit(self): |  | ||||||
|         """Return if the channel is +l.""" |  | ||||||
|         return self.has_mode("l") |  | ||||||
| 
 |  | ||||||
|     def limit(self): |  | ||||||
|         """Return the channel limit count.""" |  | ||||||
|         if self.has_limit(): |  | ||||||
|             return self.modes["l"] |  | ||||||
|         else: |  | ||||||
|             return None |  | ||||||
| 
 |  | ||||||
|     def has_key(self): |  | ||||||
|         """Return if the channel is +k.""" |  | ||||||
|         return self.has_mode("k") |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| # | # | ||||||
| # This file is autogenerated by pip-compile with Python 3.8 | # This file is autogenerated by pip-compile with Python 3.10 | ||||||
| # by the following command: | # by the following command: | ||||||
| # | # | ||||||
| #    pip-compile --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in | #    pip-compile --output-file=requirements/requirements-dev.txt requirements/requirements-dev.in | ||||||
| @ -22,7 +22,7 @@ click==8.1.3 | |||||||
|     # via |     # via | ||||||
|     #   pip-tools |     #   pip-tools | ||||||
|     #   safety |     #   safety | ||||||
| coverage[toml]==7.1.0 | coverage[toml]==7.2.1 | ||||||
|     # via pytest-cov |     # via pytest-cov | ||||||
| distlib==0.3.6 | distlib==0.3.6 | ||||||
|     # via virtualenv |     # via virtualenv | ||||||
| @ -77,19 +77,15 @@ flake8-mutable==1.2.0 | |||||||
|     # via -r requirements/requirements-dev.in |     # via -r requirements/requirements-dev.in | ||||||
| gitdb==4.0.10 | gitdb==4.0.10 | ||||||
|     # via gitpython |     # via gitpython | ||||||
| gitpython==3.1.30 | gitpython==3.1.31 | ||||||
|     # via bandit |     # via bandit | ||||||
| idna==3.4 | idna==3.4 | ||||||
|     # via requests |     # via requests | ||||||
| importlib-resources==5.10.2 |  | ||||||
|     # via jaraco-text |  | ||||||
| inflect==6.0.2 | inflect==6.0.2 | ||||||
|     # via |     # via jaraco-text | ||||||
|     #   jaraco-itertools |  | ||||||
|     #   jaraco-text |  | ||||||
| iniconfig==2.0.0 | iniconfig==2.0.0 | ||||||
|     # via pytest |     # via pytest | ||||||
| irc==15.0.6 | irc==20.1.0 | ||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| isort==5.12.0 | isort==5.12.0 | ||||||
|     # via flake8-isort |     # via flake8-isort | ||||||
| @ -99,13 +95,11 @@ jaraco-collections==3.8.0 | |||||||
|     # via irc |     # via irc | ||||||
| jaraco-context==4.3.0 | jaraco-context==4.3.0 | ||||||
|     # via jaraco-text |     # via jaraco-text | ||||||
| jaraco-functools==3.5.2 | jaraco-functools==3.6.0 | ||||||
|     # via |     # via | ||||||
|     #   irc |     #   irc | ||||||
|     #   jaraco-text |     #   jaraco-text | ||||||
|     #   tempora |     #   tempora | ||||||
| jaraco-itertools==6.2.1 |  | ||||||
|     # via irc |  | ||||||
| jaraco-logging==3.1.2 | jaraco-logging==3.1.2 | ||||||
|     # via irc |     # via irc | ||||||
| jaraco-stream==3.0.3 | jaraco-stream==3.0.3 | ||||||
| @ -116,12 +110,11 @@ jaraco-text==3.11.1 | |||||||
|     #   jaraco-collections |     #   jaraco-collections | ||||||
| mccabe==0.7.0 | mccabe==0.7.0 | ||||||
|     # via flake8 |     # via flake8 | ||||||
| more-itertools==9.0.0 | more-itertools==9.1.0 | ||||||
|     # via |     # via | ||||||
|     #   irc |     #   irc | ||||||
|     #   jaraco-classes |     #   jaraco-classes | ||||||
|     #   jaraco-functools |     #   jaraco-functools | ||||||
|     #   jaraco-itertools |  | ||||||
|     #   jaraco-text |     #   jaraco-text | ||||||
| packaging==21.3 | packaging==21.3 | ||||||
|     # via |     # via | ||||||
| @ -134,7 +127,7 @@ parsedatetime==2.6 | |||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| pbr==5.11.1 | pbr==5.11.1 | ||||||
|     # via stevedore |     # via stevedore | ||||||
| pip-tools==6.12.2 | pip-tools==6.12.3 | ||||||
|     # via -r requirements/requirements-dev.in |     # via -r requirements/requirements-dev.in | ||||||
| platformdirs==3.0.0 | platformdirs==3.0.0 | ||||||
|     # via virtualenv |     # via virtualenv | ||||||
| @ -197,7 +190,6 @@ safety==2.3.5 | |||||||
|     # via -r requirements/requirements-dev.in |     # via -r requirements/requirements-dev.in | ||||||
| six==1.16.0 | six==1.16.0 | ||||||
|     # via |     # via | ||||||
|     #   irc |  | ||||||
|     #   python-dateutil |     #   python-dateutil | ||||||
|     #   tox |     #   tox | ||||||
| smmap==5.0.0 | smmap==5.0.0 | ||||||
| @ -233,7 +225,7 @@ urllib3==1.26.14 | |||||||
|     # via requests |     # via requests | ||||||
| versioneer==0.28 | versioneer==0.28 | ||||||
|     # via -r requirements/requirements-dev.in |     # via -r requirements/requirements-dev.in | ||||||
| virtualenv==20.19.0 | virtualenv==20.20.0 | ||||||
|     # via tox |     # via tox | ||||||
| wheel==0.38.4 | wheel==0.38.4 | ||||||
|     # via |     # via | ||||||
| @ -241,8 +233,6 @@ wheel==0.38.4 | |||||||
|     #   tox-wheel |     #   tox-wheel | ||||||
| zalgo-text==0.6 | zalgo-text==0.6 | ||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| zipp==3.13.0 |  | ||||||
|     # via importlib-resources |  | ||||||
| 
 | 
 | ||||||
| # The following packages are considered to be unsafe in a requirements file: | # The following packages are considered to be unsafe in a requirements file: | ||||||
| # pip | # pip | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ django-adminplus                # admin.site.register_view | |||||||
| django-bootstrap3               # bootstrap layout | django-bootstrap3               # bootstrap layout | ||||||
| django-extensions               # more commands | django-extensions               # more commands | ||||||
| djangorestframework             # dispatch WS API | djangorestframework             # dispatch WS API | ||||||
| irc==15.0.6                     # core, pinned until I can bother to update --- 17.x has API changes | irc                             # core | ||||||
| parsedatetime                   # relative date stuff in countdown | parsedatetime                   # relative date stuff in countdown | ||||||
| ply                             # dice lex/yacc compiler | ply                             # dice lex/yacc compiler | ||||||
| python-dateutil                 # countdown relative math | python-dateutil                 # countdown relative math | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| # | # | ||||||
| # This file is autogenerated by pip-compile with Python 3.8 | # This file is autogenerated by pip-compile with Python 3.10 | ||||||
| # by the following command: | # by the following command: | ||||||
| # | # | ||||||
| #    pip-compile --output-file=requirements/requirements.txt requirements/requirements.in | #    pip-compile --output-file=requirements/requirements.txt requirements/requirements.in | ||||||
| @ -28,13 +28,9 @@ djangorestframework==3.14.0 | |||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| idna==3.4 | idna==3.4 | ||||||
|     # via requests |     # via requests | ||||||
| importlib-resources==5.10.2 |  | ||||||
|     # via jaraco-text |  | ||||||
| inflect==6.0.2 | inflect==6.0.2 | ||||||
|     # via |     # via jaraco-text | ||||||
|     #   jaraco-itertools | irc==20.1.0 | ||||||
|     #   jaraco-text |  | ||||||
| irc==15.0.6 |  | ||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| jaraco-classes==3.2.3 | jaraco-classes==3.2.3 | ||||||
|     # via jaraco-collections |     # via jaraco-collections | ||||||
| @ -42,13 +38,11 @@ jaraco-collections==3.8.0 | |||||||
|     # via irc |     # via irc | ||||||
| jaraco-context==4.3.0 | jaraco-context==4.3.0 | ||||||
|     # via jaraco-text |     # via jaraco-text | ||||||
| jaraco-functools==3.5.2 | jaraco-functools==3.6.0 | ||||||
|     # via |     # via | ||||||
|     #   irc |     #   irc | ||||||
|     #   jaraco-text |     #   jaraco-text | ||||||
|     #   tempora |     #   tempora | ||||||
| jaraco-itertools==6.2.1 |  | ||||||
|     # via irc |  | ||||||
| jaraco-logging==3.1.2 | jaraco-logging==3.1.2 | ||||||
|     # via irc |     # via irc | ||||||
| jaraco-stream==3.0.3 | jaraco-stream==3.0.3 | ||||||
| @ -57,12 +51,11 @@ jaraco-text==3.11.1 | |||||||
|     # via |     # via | ||||||
|     #   irc |     #   irc | ||||||
|     #   jaraco-collections |     #   jaraco-collections | ||||||
| more-itertools==9.0.0 | more-itertools==9.1.0 | ||||||
|     # via |     # via | ||||||
|     #   irc |     #   irc | ||||||
|     #   jaraco-classes |     #   jaraco-classes | ||||||
|     #   jaraco-functools |     #   jaraco-functools | ||||||
|     #   jaraco-itertools |  | ||||||
|     #   jaraco-text |     #   jaraco-text | ||||||
| parsedatetime==2.6 | parsedatetime==2.6 | ||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| @ -90,9 +83,7 @@ requests==2.28.2 | |||||||
| requests-toolbelt==0.10.1 | requests-toolbelt==0.10.1 | ||||||
|     # via python-gitlab |     # via python-gitlab | ||||||
| six==1.16.0 | six==1.16.0 | ||||||
|     # via |     # via python-dateutil | ||||||
|     #   irc |  | ||||||
|     #   python-dateutil |  | ||||||
| sqlparse==0.4.3 | sqlparse==0.4.3 | ||||||
|     # via django |     # via django | ||||||
| tempora==5.2.1 | tempora==5.2.1 | ||||||
| @ -105,5 +96,3 @@ urllib3==1.26.14 | |||||||
|     # via requests |     # via requests | ||||||
| zalgo-text==0.6 | zalgo-text==0.6 | ||||||
|     # via -r requirements/requirements.in |     # via -r requirements/requirements.in | ||||||
| zipp==3.13.0 |  | ||||||
|     # via importlib-resources |  | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user