Add internal_ip segment

Closes #857
This commit is contained in:
ZyX 2014-08-24 01:20:25 +04:00
parent d76df9f168
commit 173c4d6e76
5 changed files with 119 additions and 3 deletions

View File

@ -16,6 +16,7 @@
"weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0", "attr": [] },
"uptime": { "fg": "gray8", "bg": "gray0", "attr": [] },
"external_ip": { "fg": "gray8", "bg": "gray0", "attr": [] },
"internal_ip": { "fg": "gray8", "bg": "gray0", "attr": [] },
"network_load": { "fg": "gray8", "bg": "gray0", "attr": [] },
"network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] },
"system_load": { "fg": "gray8", "bg": "gray0", "attr": [] },

View File

@ -263,6 +263,74 @@ Divider highlight group used: ``background:divider``.
''')
try:
import netifaces
except ImportError:
def internal_ip(pl, interface='detect', ipv=4):
return None
else:
_interface_starts = {
'eth': 10, # Regular ethernet adapters : eth1
'enp': 10, # Regular ethernet adapters, Gentoo : enp2s0
'ath': 9, # Atheros WiFi adapters : ath0
'wlan': 9, # Other WiFi adapters : wlan1
'wlp': 9, # Other WiFi adapters, Gentoo : wlp5s0
'teredo': 1, # miredo interface : teredo
'lo': -10, # Loopback interface : lo
}
_interface_start_re = re.compile(r'^([a-z]+?)(\d|$)')
def _interface_key(interface):
match = _interface_start_re.match(interface)
if match:
try:
base = _interface_starts[match.group(1)] * 100
except KeyError:
base = 500
if match.group(2):
return base - int(match.group(2))
else:
return base
else:
return 0
def internal_ip(pl, interface='detect', ipv=4):
if interface == 'detect':
try:
interface = next(iter(sorted(netifaces.interfaces(), key=_interface_key, reverse=True)))
except StopIteration:
pl.info('No network interfaces found')
return None
addrs = netifaces.ifaddresses(interface)
try:
return addrs[netifaces.AF_INET6 if ipv == 6 else netifaces.AF_INET][0]['addr']
except (KeyError, IndexError):
return None
internal_ip = with_docstring(internal_ip,
'''Return internal IP address
Requires ``netifaces`` package to work properly.
:param str interface:
Interface on which IP will be checked. Use ``detect`` to automatically
detect interface. In this case interfaces with lower numbers will be
preferred over interfaces with similar names. Order of preference based on
names:
#. ``eth`` and ``enp`` followed by number or the end of string.
#. ``ath``, ``wlan`` and ``wlp`` followed by number or the end of string.
#. ``teredo`` followed by number or the end of string.
#. Any other interface that is not ``lo*``.
#. ``lo`` followed by number or the end of string.
:param int ipv:
4 or 6 for ipv4 and ipv6 respectively, depending on which IP address you
need exactly.
''')
# Weather condition code descriptions available at
# http://developer.yahoo.com/weather/#codes
weather_conditions_codes = (

View File

@ -1,6 +1,6 @@
#!/bin/sh
pip install .
pip install psutil
pip install psutil netifaces
if python -c 'import sys; sys.exit(1 * (sys.version_info[0] != 2))' ; then
# Python 2
if python -c 'import platform, sys; sys.exit(1 - (platform.python_implementation() == "CPython"))' ; then

View File

@ -9,10 +9,11 @@ class Pl(object):
self.errors = []
self.warns = []
self.debugs = []
self.infos = []
self.prefix = None
self.use_daemon_threads = True
for meth in ('error', 'warn', 'debug', 'exception'):
for meth in ('error', 'warn', 'debug', 'exception', 'info'):
exec ((
'def {0}(self, msg, *args, **kwargs):\n'
' self.{0}s.append((kwargs.get("prefix") or self.prefix, msg, args, kwargs))\n'

View File

@ -9,7 +9,7 @@ import sys
import os
from functools import partial
from tests.lib import Args, urllib_read, replace_attr, new_module, replace_module_module, replace_env, Pl
from tests import TestCase
from tests import TestCase, SkipTest
vim = None
@ -587,6 +587,52 @@ class TestCommon(TestCase):
}
])
def test_internal_ip(self):
try:
import netifaces
except ImportError:
raise SkipTest()
pl = Pl()
addr = {
'enp2s0': {
netifaces.AF_INET: [{'addr': '192.168.100.200'}],
netifaces.AF_INET6: [{'addr': 'feff::5446:5eff:fe5a:7777%enp2s0'}]
},
'lo': {
netifaces.AF_INET: [{'addr': '127.0.0.1'}],
netifaces.AF_INET6: [{'addr': '::1'}]
},
'teredo': {
netifaces.AF_INET6: [{'addr': 'feff::5446:5eff:fe5a:7777'}]
},
}
interfaces = ['lo', 'enp2s0', 'teredo']
with replace_module_module(
common, 'netifaces',
interfaces=(lambda: interfaces),
ifaddresses=(lambda interface: addr[interface]),
AF_INET=netifaces.AF_INET,
AF_INET6=netifaces.AF_INET6,
):
self.assertEqual(common.internal_ip(pl=pl), '192.168.100.200')
self.assertEqual(common.internal_ip(pl=pl, interface='detect'), '192.168.100.200')
self.assertEqual(common.internal_ip(pl=pl, interface='lo'), '127.0.0.1')
self.assertEqual(common.internal_ip(pl=pl, interface='teredo'), None)
self.assertEqual(common.internal_ip(pl=pl, ipv=4), '192.168.100.200')
self.assertEqual(common.internal_ip(pl=pl, interface='detect', ipv=4), '192.168.100.200')
self.assertEqual(common.internal_ip(pl=pl, interface='lo', ipv=4), '127.0.0.1')
self.assertEqual(common.internal_ip(pl=pl, interface='teredo', ipv=4), None)
self.assertEqual(common.internal_ip(pl=pl, ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0')
self.assertEqual(common.internal_ip(pl=pl, interface='detect', ipv=6), 'feff::5446:5eff:fe5a:7777%enp2s0')
self.assertEqual(common.internal_ip(pl=pl, interface='lo', ipv=6), '::1')
self.assertEqual(common.internal_ip(pl=pl, interface='teredo', ipv=6), 'feff::5446:5eff:fe5a:7777')
interfaces[1:2] = ()
self.assertEqual(common.internal_ip(pl=pl, ipv=6), 'feff::5446:5eff:fe5a:7777')
interfaces[1:2] = ()
self.assertEqual(common.internal_ip(pl=pl, ipv=6), '::1')
interfaces[:] = ()
self.assertEqual(common.internal_ip(pl=pl, ipv=6), None)
class TestVim(TestCase):
def test_mode(self):