Added a MinecraftServer.lookup method, converts a string to host/port (including SRV lookup)

This closes #12
This commit is contained in:
Nathan Adams
2014-09-26 01:05:47 +02:00
parent 18af499c62
commit 7bcbbc7409
9 changed files with 101 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
from mcstatus.pinger import ServerPinger
from mcstatus.protocol.connection import TCPSocketConnection, UDPSocketConnection
from mcstatus.querier import ServerQuerier
import dns.resolver
class MinecraftServer:
@@ -8,6 +9,29 @@ class MinecraftServer:
self.host = host
self.port = port
@staticmethod
def lookup(address):
host = address
port = None
if ":" in address:
parts = address.split(":")
if len(parts) > 2:
raise ValueError("Invalid address '%s'" % address)
host = parts[0]
port = int(parts[1])
if port is None:
port = 25565
try:
answers = dns.resolver.query("_minecraft._tcp." + host, "SRV")
if len(answers):
answer = answers[0]
host = str(answer.target).rstrip(".")
port = int(answer.port)
except Exception:
pass
return MinecraftServer(host, port)
def ping(self, retries=3, **kwargs):
attempt = 0
connection = TCPSocketConnection((self.host, self.port))

View File

@@ -81,4 +81,42 @@ class TestMinecraftServer(TestCase):
with patch("mcstatus.server.ServerQuerier") as querier:
querier.side_effect = [Exception, Exception, Exception]
self.assertRaises(Exception, self.server.query)
self.assertEqual(querier.call_count, 3)
self.assertEqual(querier.call_count, 3)
def test_by_address_no_srv(self):
with patch("dns.resolver.query") as query:
query.return_value = []
self.server = MinecraftServer.lookup("example.org")
query.assert_called_once_with("_minecraft._tcp.example.org", "SRV")
self.assertEqual(self.server.host, "example.org")
self.assertEqual(self.server.port, 25565)
def test_by_address_invalid_srv(self):
with patch("dns.resolver.query") as query:
query.side_effect = [Exception]
self.server = MinecraftServer.lookup("example.org")
query.assert_called_once_with("_minecraft._tcp.example.org", "SRV")
self.assertEqual(self.server.host, "example.org")
self.assertEqual(self.server.port, 25565)
def test_by_address_with_srv(self):
with patch("dns.resolver.query") as query:
answer = Mock()
answer.target = "different.example.org."
answer.port = 12345
query.return_value = [answer]
self.server = MinecraftServer.lookup("example.org")
query.assert_called_once_with("_minecraft._tcp.example.org", "SRV")
self.assertEqual(self.server.host, "different.example.org")
self.assertEqual(self.server.port, 12345)
def test_by_address_with_port(self):
self.server = MinecraftServer.lookup("example.org:12345")
self.assertEqual(self.server.host, "example.org")
self.assertEqual(self.server.port, 12345)
def test_by_address_with_multiple_ports(self):
self.assertRaises(ValueError, MinecraftServer.lookup, "example.org:12345:6789")
def test_by_address_with_invalid_port(self):
self.assertRaises(ValueError, MinecraftServer.lookup, "example.org:port")