Commits

Mikhail Korobov committed 4bc4c6c

yandex_maps.api теперь можно использовать без django. yandex_maps.utils теперь deprecated. Кроме того, добавлена поддержка таймаутов для python 2.5+ и тесты.

Comments (0)

Files changed (6)

 #setup files
 build/
 dist/
-MANIFEST
+MANIFEST
+
+#my files
+my_tests.py

yandex_maps/api.py

+# coding: utf-8
+
+# Yandex maps API wrapper. Can be used without Django.
+
+import xml.dom.minidom
+import urllib
+from yandex_maps import http
+
+STATIC_MAPS_URL = 'http://static-maps.yandex.ru/1.x/?'
+GEOCODE_URL = 'http://geocode-maps.yandex.ru/1.x/?'
+
+def get_map_url(API_key, longtitude, latitude, zoom, width, height):
+    ''' returns URL of static yandex map '''
+    params = [
+       'll=%0.7f,%0.7f' % (longtitude, latitude,),
+       'size=%d,%d' % (width, height,),
+       'z=%d' % zoom,
+       'l=map',
+       'pt=%0.7f,%0.7f' % (longtitude, latitude,),
+       'key=%s' % API_key
+    ]
+    return STATIC_MAPS_URL + '&'.join(params)
+
+def geocode(API_key, address, timeout=2):
+    ''' returns (longtitude, latitude,) tuple for given address '''
+    if isinstance(address, unicode):
+        address = address.encode('utf8')
+    params = urllib.urlencode({'geocode': address, 'key': API_key})
+    url = GEOCODE_URL + params
+    try:
+        status_code, response = http.request('GET', url, timeout=timeout)
+    except IOError:
+        return None, None
+    return _get_coords(response)
+
+def _get_coords(response):
+    try:
+        dom = xml.dom.minidom.parseString(response)
+        pos_elem = dom.getElementsByTagName('pos')[0]
+        pos_data = pos_elem.childNodes[0].data
+        return pos_data.split()
+    except IndexError:
+        return None, None

yandex_maps/http.py

+#coding: utf-8
+from __future__ import with_statement
+from contextlib import closing
+import httplib
+
+# urllib2 doesn't support timeouts for python 2.5
+
+def request(method, url, data=None, headers={}, timeout=None):
+    host_port = url.split('/')[2]
+    timeout_set = False
+    try:
+        connection = httplib.HTTPConnection(host_port, timeout = timeout)
+        timeout_set = True
+    except TypeError:
+        connection = httplib.HTTPConnection(host_port)
+
+    with closing(connection):
+        if not timeout_set:
+            connection.connect()
+            connection.sock.settimeout(timeout)
+            timeout_set = True
+
+        connection.request(method, url, data, headers)
+        response = connection.getresponse()
+        return (response.status, response.read())

yandex_maps/models.py

 from django.conf import settings
 from django.utils.encoding import smart_str
 
-from yandex_maps import utils
+from yandex_maps import api
 
 YANDEX_KEY = getattr(settings, 'YANDEX_MAPS_API_KEY', None)
 
         h = int(height) if height else settings.YANDEX_MAPS_H
         detail_level = int(detail_level) or self.get_detail_level()
         if YANDEX_KEY is not None:
-            return utils.get_map_url(YANDEX_KEY, self.longtitude, self.latitude, detail_level, w, h)
+            return api.get_map_url(YANDEX_KEY, self.longtitude, self.latitude, detail_level, w, h)
         else:
             return ''
 
     def fill_geocode_data(self):
         if YANDEX_KEY is not None:
-            self.longtitude, self.latitude = utils.geocode(settings.YANDEX_MAPS_API_KEY, smart_str(self.address))
+            self.longtitude, self.latitude = api.geocode(settings.YANDEX_MAPS_API_KEY, smart_str(self.address))
 
     def save(self, *args, **kwargs):
         if self.pk or (self.longtitude is None) or (self.latitude is None): # don't fill geocode data if it is known already

yandex_maps/tests.py

 #coding: utf-8
 from unittest import TestCase
-from yandex_maps.utils import _parse_response
+from yandex_maps.api import _get_coords, get_map_url
 
 RESPONSE = u"""<?xml version="1.0" encoding="utf-8"?>
 <ymaps xmlns="http://maps.yandex.ru/ymaps/1.x" xmlns:x="http://www.yandex.ru/xscript">
 </ymaps>
 '''.encode('utf8')
 
+TEST_API_KEY = 'vasia'
+COORDS = [u'60.603826', u'56.854581']
+MAP_URL = 'http://static-maps.yandex.ru/1.x/?ll=60.6038260,56.8545810&size=200,300&z=5&l=map&pt=60.6038260,56.8545810&key=vasia'
+
 class GeocodeParsingTest(TestCase):
-
     def test_parsing(self):
-        self.assertEqual(_parse_response(RESPONSE), [u'60.603826', u'56.854581'])
+        self.assertEqual(_get_coords(RESPONSE), COORDS)
 
     def test_unknown(self):
-        self.assertEqual(_parse_response(UNKNOWN_ADDRESS), (None, None,))
+        self.assertEqual(_get_coords(UNKNOWN_ADDRESS), (None, None,))
+
+
+class MapUrlTest(TestCase):
+    def test_map_url(self):
+        url = get_map_url(TEST_API_KEY, float(COORDS[0]), float(COORDS[1]), 5, 200, 300)
+        self.assertEqual(url, MAP_URL)

yandex_maps/utils.py

-#coding: utf-8
-import xml.dom.minidom
-import urllib2
-from django.utils.http import urlencode
+from yandex_maps.api import geocode, get_map_url
 
-def get_map_url(API_key, longtitude, latitude, zoom, width, height):
-    url = u"http://static-maps.yandex.ru/1.x/?ll=%0.7f,%0.7f&size=%d,%d&z=%d&l=map&pt=%0.7f,%0.7f&key=%s" % \
-          (longtitude, latitude, width, height, zoom, longtitude, latitude, API_key)
-    return url
-
-def geocode(API_key, address):
-    url = u'http://geocode-maps.yandex.ru/1.x/?'
-    params = urlencode({'geocode':address,'key':API_key})
-    try:
-        response = urllib2.urlopen(url+params).read()
-    except IOError:
-        return (None, None,)
-    return _parse_response(response)
-
-def _parse_response(response):
-    try:
-        dom = xml.dom.minidom.parseString(response)
-        pos_elem = dom.getElementsByTagName('pos')[0]
-        pos_data = pos_elem.childNodes[0].data
-        return pos_data.split()
-    except IndexError:
-        return None, None
+import warnings
+msg = 'yandex_maps.utils is deprecated. Import from yandex_maps.api instead.'
+warnings.warn(msg, DeprecationWarning, stacklevel=2)