| Conditions | 16 |
| Total Lines | 74 |
| Code Lines | 59 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like sopel.modules.ip.ip() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # coding=utf-8 |
||
| 106 | @commands('iplookup', 'ip') |
||
| 107 | @example('.ip 8.8.8.8', |
||
| 108 | r'\[IP\/Host Lookup\] Hostname: \S*dns\S*\.google\S* \| Location: United States \| ISP: AS15169 Google LLC', |
||
| 109 | re=True, |
||
| 110 | ignore='Downloading GeoIP database, please wait...', |
||
| 111 | online=True) |
||
| 112 | def ip(bot, trigger): |
||
| 113 | """IP Lookup tool""" |
||
| 114 | # Check if there is input at all |
||
| 115 | if not trigger.group(2): |
||
| 116 | return bot.reply("No search term.") |
||
| 117 | # Check whether the input is an IP or hostmask or a nickname |
||
| 118 | decide = ['.', ':'] |
||
| 119 | if any(x in trigger.group(2) for x in decide): |
||
| 120 | # It's an IP/hostname! |
||
| 121 | query = trigger.group(2).strip() |
||
| 122 | else: |
||
| 123 | # Need to get the host for the username |
||
| 124 | username = trigger.group(2).strip() |
||
| 125 | user_in_botdb = bot.users.get(username) |
||
| 126 | if user_in_botdb is not None: |
||
| 127 | query = user_in_botdb.host |
||
| 128 | |||
| 129 | # Sanity check - sometimes user information isn't populated yet |
||
| 130 | if query is None: |
||
| 131 | return bot.say("I don't know that user's host.") |
||
| 132 | else: |
||
| 133 | return bot.say("I\'m not aware of this user.") |
||
| 134 | |||
| 135 | db_path = _find_geoip_db(bot) |
||
| 136 | if db_path is False: |
||
| 137 | LOGGER.error('Can\'t find (or download) usable GeoIP database.') |
||
| 138 | bot.say('Sorry, I don\'t have a GeoIP database to use for this lookup.') |
||
| 139 | return False |
||
| 140 | |||
| 141 | if ':' in query: |
||
| 142 | try: |
||
| 143 | socket.inet_pton(socket.AF_INET6, query) |
||
| 144 | except (OSError, socket.error): # Python 2/3 compatibility |
||
| 145 | return bot.say("[IP/Host Lookup] Unable to resolve IP/Hostname") |
||
| 146 | elif '.' in query: |
||
| 147 | try: |
||
| 148 | socket.inet_pton(socket.AF_INET, query) |
||
| 149 | except (socket.error, socket.herror): |
||
| 150 | try: |
||
| 151 | query = socket.getaddrinfo(query, None)[0][4][0] |
||
| 152 | except socket.gaierror: |
||
| 153 | return bot.say("[IP/Host Lookup] Unable to resolve IP/Hostname") |
||
| 154 | else: |
||
| 155 | return bot.say("[IP/Host Lookup] Unable to resolve IP/Hostname") |
||
| 156 | |||
| 157 | city = geoip2.database.Reader(os.path.join(db_path, 'GeoLite2-City.mmdb')) |
||
| 158 | asn = geoip2.database.Reader(os.path.join(db_path, 'GeoLite2-ASN.mmdb')) |
||
| 159 | host = socket.getfqdn(query) |
||
| 160 | try: |
||
| 161 | city_response = city.city(query) |
||
| 162 | asn_response = asn.asn(query) |
||
| 163 | except geoip2.errors.AddressNotFoundError: |
||
| 164 | return bot.say("[IP/Host Lookup] The address is not in the database.") |
||
| 165 | |||
| 166 | response = "[IP/Host Lookup] Hostname: %s" % host |
||
| 167 | try: |
||
| 168 | response += " | Location: %s" % city_response.country.name |
||
| 169 | except AttributeError: |
||
| 170 | response += ' | Location: Unknown' |
||
| 171 | |||
| 172 | region = city_response.subdivisions.most_specific.name |
||
| 173 | response += " | Region: %s" % region if region else "" |
||
| 174 | city = city_response.city.name |
||
| 175 | response += " | City: %s" % city if city else "" |
||
| 176 | isp = "AS" + str(asn_response.autonomous_system_number) + \ |
||
| 177 | " " + asn_response.autonomous_system_organization |
||
| 178 | response += " | ISP: %s" % isp if isp else "" |
||
| 179 | bot.say(response) |
||
| 180 | |||
| 185 |