зеркало из https://github.com/mozilla/bedrock.git
Bug 1133146: Add geolocation capabilities.
Add functions for country lookup and MaxMind DB handling.
This commit is contained in:
Родитель
0e5e664caa
Коммит
cb4a45710e
|
@ -27,6 +27,7 @@ Desktop.ini
|
|||
venv
|
||||
.vagrant
|
||||
*.db
|
||||
*.mmdb
|
||||
james.ini
|
||||
/media/js/test/test-results.xml
|
||||
bedrock/externalfiles/files_cache
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
try:
|
||||
import maxminddb
|
||||
except ImportError:
|
||||
maxminddb = None
|
||||
|
||||
|
||||
if maxminddb is not None:
|
||||
try:
|
||||
geo = maxminddb.open_database(settings.MAXMIND_DB_PATH)
|
||||
except (IOError, maxminddb.InvalidDatabaseError):
|
||||
geo = None
|
||||
else:
|
||||
geo = None
|
||||
|
||||
|
||||
def get_country_from_ip(ip_addr):
|
||||
"""Return country info for the given IP Address."""
|
||||
if geo is not None:
|
||||
try:
|
||||
data = geo.get(ip_addr)
|
||||
except ValueError:
|
||||
data = None
|
||||
|
||||
if data:
|
||||
country = data.get('country', data.get('registered_country'))
|
||||
if country:
|
||||
return country['iso_code'].upper()
|
||||
|
||||
return settings.MAXMIND_DEFAULT_COUNTRY.upper()
|
||||
|
||||
|
||||
def get_country_from_request(request):
|
||||
"""Return country info for the given request data."""
|
||||
client_ip = request.META.get('HTTP_X_CLUSTER_CLIENT_IP',
|
||||
request.META.get('REMOTE_ADDR'))
|
||||
return get_country_from_ip(client_ip)
|
|
@ -4,10 +4,13 @@
|
|||
|
||||
import os
|
||||
from subprocess import call
|
||||
from django.test.utils import override_settings
|
||||
from mock import patch
|
||||
|
||||
import chkcrontab_lib as chkcrontab
|
||||
from funfactory.settings_base import path
|
||||
|
||||
from bedrock.base import geo
|
||||
from bedrock.mozorg.tests import TestCase
|
||||
|
||||
|
||||
|
@ -42,3 +45,72 @@ class TestCrontabFiles(TestCase):
|
|||
cronlog = chkcrontab.LogCounter()
|
||||
return_value = chkcrontab.check_crontab(filename, cronlog)
|
||||
self.assertEqual(return_value, 0, 'Problem with ' + filename)
|
||||
|
||||
|
||||
@patch('bedrock.base.geo.geo')
|
||||
class TestGeo(TestCase):
|
||||
# real output from a real maxmind db
|
||||
good_geo_data = {
|
||||
u'continent': {
|
||||
u'code': u'NA',
|
||||
u'geoname_id': 6255149L,
|
||||
u'names': {u'de': u'Nordamerika',
|
||||
u'en': u'North America',
|
||||
u'es': u'Norteam\xe9rica',
|
||||
u'fr': u'Am\xe9rique du Nord',
|
||||
u'ja': u'\u5317\u30a2\u30e1\u30ea\u30ab',
|
||||
u'pt-BR': u'Am\xe9rica do Norte',
|
||||
u'ru': u'\u0421\u0435\u0432\u0435\u0440\u043d\u0430\u044f '
|
||||
u'\u0410\u043c\u0435\u0440\u0438\u043a\u0430',
|
||||
u'zh-CN': u'\u5317\u7f8e\u6d32'}
|
||||
},
|
||||
u'country': {
|
||||
u'geoname_id': 6252001L,
|
||||
u'iso_code': u'US',
|
||||
u'names': {u'de': u'USA',
|
||||
u'en': u'United States',
|
||||
u'es': u'Estados Unidos',
|
||||
u'fr': u'\xc9tats-Unis',
|
||||
u'ja': u'\u30a2\u30e1\u30ea\u30ab\u5408\u8846\u56fd',
|
||||
u'pt-BR': u'Estados Unidos',
|
||||
u'ru': u'\u0421\u0428\u0410',
|
||||
u'zh-CN': u'\u7f8e\u56fd'}
|
||||
},
|
||||
u'location': {u'latitude': 38.0, u'longitude': -97.0},
|
||||
u'registered_country': {
|
||||
u'geoname_id': 6252001L,
|
||||
u'iso_code': u'US',
|
||||
u'names': {u'de': u'USA',
|
||||
u'en': u'United States',
|
||||
u'es': u'Estados Unidos',
|
||||
u'fr': u'\xc9tats-Unis',
|
||||
u'ja': u'\u30a2\u30e1\u30ea\u30ab\u5408\u8846\u56fd',
|
||||
u'pt-BR': u'Estados Unidos',
|
||||
u'ru': u'\u0421\u0428\u0410',
|
||||
u'zh-CN': u'\u7f8e\u56fd'}
|
||||
}
|
||||
}
|
||||
|
||||
def test_get_country_by_ip(self, geo_mock):
|
||||
geo_mock.get.return_value = self.good_geo_data
|
||||
self.assertEqual(geo.get_country_from_ip('1.1.1.1'), 'US')
|
||||
geo_mock.get.assert_called_with('1.1.1.1')
|
||||
|
||||
@override_settings(MAXMIND_DEFAULT_COUNTRY='XX')
|
||||
def test_get_country_by_ip_default(self, geo_mock):
|
||||
"""Geo failure should return default country."""
|
||||
geo_mock.get.return_value = None
|
||||
self.assertEqual(geo.get_country_from_ip('1.1.1.1'), 'XX')
|
||||
geo_mock.get.assert_called_with('1.1.1.1')
|
||||
|
||||
geo_mock.reset_mock()
|
||||
geo_mock.get.side_effect = ValueError
|
||||
self.assertEqual(geo.get_country_from_ip('1.1.1.1'), 'XX')
|
||||
geo_mock.get.assert_called_with('1.1.1.1')
|
||||
|
||||
@override_settings(MAXMIND_DEFAULT_COUNTRY='XX')
|
||||
def test_get_country_by_ip_bad_data(self, geo_mock):
|
||||
"""Bad data from geo should return default country."""
|
||||
geo_mock.get.return_value = {'fred': 'flintstone'}
|
||||
self.assertEqual(geo.get_country_from_ip('1.1.1.1'), 'XX')
|
||||
geo_mock.get.assert_called_with('1.1.1.1')
|
||||
|
|
|
@ -2336,3 +2336,6 @@ FIREFOX_OS_FEEDS = (
|
|||
FIREFOX_OS_FEED_LOCALES = [feed[0] for feed in FIREFOX_OS_FEEDS]
|
||||
|
||||
TABLEAU_DB_URL = None
|
||||
|
||||
MAXMIND_DB_PATH = os.getenv('MAXMIND_DB_PATH', path('GeoIP2-Country.mmdb'))
|
||||
MAXMIND_DEFAULT_COUNTRY = os.getenv('MAXMIND_DEFAULT_COUNTRY', 'US')
|
||||
|
|
|
@ -6,3 +6,5 @@ MySQL-python==1.2.3c1
|
|||
Jinja2==2.5.5
|
||||
# sha256: KjyjT2OwYu6OBZyiRgrBgEDsliLwox4UM4Pw25RM6zY
|
||||
lxml==2.3.3
|
||||
# sha256: z7Y2FZPiv53Fe_051X6y8U4-RhzuMzrC_-2w-HP3l80
|
||||
maxminddb==1.1.1
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2008 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,17 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: ipaddr
|
||||
Version: 2.1.11
|
||||
Summary: UNKNOWN
|
||||
Home-page: http://code.google.com/p/ipaddr-py/
|
||||
Author: Google
|
||||
Author-email: ipaddr-py-dev@googlegroups.com
|
||||
License: Apache License, Version 2.0
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: Apache Software License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Topic :: Internet
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Classifier: Topic :: System :: Networking
|
|
@ -0,0 +1,8 @@
|
|||
ipaddr.py is a library for working with IP addresses, both IPv4 and IPv6.
|
||||
It was developed by Google for internal use, and is now open source.
|
||||
|
||||
Project home page: http://code.google.com/p/ipaddr-py/
|
||||
|
||||
Please send contributions to ipaddr-py-dev@googlegroups.com. Code should
|
||||
include unit tests and follow the Google Python style guide:
|
||||
http://code.google.com/p/soc/wiki/PythonStyleGuide
|
|
@ -0,0 +1,295 @@
|
|||
#summary notes from releases
|
||||
|
||||
= Release Notes =
|
||||
|
||||
Here are the visible changes for each release.
|
||||
|
||||
== 2.1.11 ==
|
||||
|
||||
(2014-01-31)
|
||||
|
||||
* hostmask parsing bug fixed by pmarks (a nearly complete rewrite of the mask parsing code)
|
||||
* i97, incorrectly parses some v6 addresses.
|
||||
* docstring typos.
|
||||
* i95, refer to the nets in the exception raised by collapse_address_list
|
||||
* add license to boilerplate to test-2to3.sh
|
||||
|
||||
== 2.1.10 ==
|
||||
|
||||
(2012-01-20)
|
||||
|
||||
Friday night, LAUNCH LAUNCH LAUNCH!
|
||||
|
||||
* i84, fix iterhosts for /31's or /127's
|
||||
* private method arg cleanup.
|
||||
* i83, docstring issue.
|
||||
* i87, new ipv4/ipv6 parser. patch from pmarks
|
||||
* i90, fix copyright.
|
||||
* bytes fix. patch from pmarks.
|
||||
|
||||
== 2.1.9 ==
|
||||
|
||||
(2011-02-22)
|
||||
|
||||
The last outstanding issues.
|
||||
|
||||
* fix warnings from python3.2
|
||||
* fix bug in _is_shorthand_ip resulting in bad teredo addresses.
|
||||
|
||||
== 2.1.8 ==
|
||||
|
||||
(2011-02-09)
|
||||
|
||||
This release fixes regressions.
|
||||
|
||||
* Address and networks now again compare true, if the address matches.
|
||||
* ipaddr works again on Python 2.4 and 2.5.
|
||||
|
||||
== 2.1.7 ==
|
||||
|
||||
(2011-01-13)
|
||||
|
||||
* turn teredo and sixtofour into properties as opposed to normal methods.
|
||||
|
||||
== 2.1.6 ==
|
||||
|
||||
(2011-01-13)
|
||||
|
||||
* typo fixes.
|
||||
* fix for ipaddr_test referring to an old version of ipaddr.
|
||||
* add test cases for r176 and r196.
|
||||
* fix for recognizing IPv6 addresses with embedded IPv4 address not being recognized.
|
||||
* additional unit tests for network comparisons and sorting.
|
||||
* force hash() to long to ensure consistency
|
||||
* turn v4_int_to_packed and v6_int_to_packed into public functions to aid converting between integers and network objects.
|
||||
* add support for pulling teredo and 6to4 embedded addresses out of an IPv6 address.
|
||||
|
||||
== 2.1.5 ==
|
||||
|
||||
(2010-09-11)
|
||||
|
||||
* containment test should always return false on mixed-type tests.
|
||||
|
||||
== 2.1.4 ==
|
||||
|
||||
(2010-08-15)
|
||||
|
||||
* fix for issue66, more invalid IPv6 addresses will be rejected
|
||||
|
||||
== 2.1.3 ==
|
||||
|
||||
(2010-06-12)
|
||||
|
||||
* fix for issue61, incorrect network containment (thanks bw.default)
|
||||
|
||||
== 2.1.2 ==
|
||||
|
||||
(2010-05-31)
|
||||
|
||||
* Happy Memorial day.
|
||||
* arithmetic for v4 and v6 address objects and ints (issue 57).
|
||||
* fix address_exclude issue where excluding an address from itself puked.
|
||||
* make sure addresses and networks don't compare.
|
||||
* doc-string fixes (issue60)
|
||||
* and masked() method to _BaseNet to return a network object with the host bits masked out (issue58)
|
||||
* fix v6 subnet representation (email to ipaddr-py-dev)
|
||||
|
||||
|
||||
== 2.1.1 ==
|
||||
|
||||
(2010-03-02)
|
||||
|
||||
* bug with list comprehension in {{{ IPv4Network._is_valid_netmask() }}}
|
||||
* kill the last remaining instances of the old exceptions in the docstrings(thanks Scott Kitterman)
|
||||
|
||||
== 2.1.0 ==
|
||||
|
||||
(2010-02-13)
|
||||
|
||||
Easier change this time :)
|
||||
|
||||
* networks and addresses are unsortable by default (see https://groups.google.com/group/ipaddr-py-dev/browse_thread/thread/8fbc5166be71adbc for discussion).
|
||||
* exception text cleanup.
|
||||
* fixing inconsistent behavior of v4/v6 address/network comparisons.
|
||||
* add IPv4Network().is_unspecified (thanks rep.dot.net)
|
||||
* fix for decoding mapped addresses (thanks rlaager)
|
||||
* docstring updates (thanks Scott Kitterman)
|
||||
* fix errant ref to non-existent variable(s) (thanks Harry Bock)
|
||||
* fix exceptions (most exceptions are subclassed from ValueError now, so this can easily be caught)
|
||||
* iterator for looping through subnets (thanks Marco Giutsi)
|
||||
|
||||
That's mostly it. there were quite a few other minor changes, but this should cover the major bits. Usage.wiki will be updated in the coming days.
|
||||
|
||||
== 2.0.0 ==
|
||||
|
||||
First and foremost, this is a backwards incompatible change. Code written for ipaddr-1.x will likely not work stock with ipaddr-2.0. For users of the 1.x branch, I'll continue to provide support, but new-feature development has ceased. But it's not so bad, take a look.All in all, I think this new version of ipaddr is much more intuitive and easy to use.
|
||||
|
||||
The best way to get a feel for this code is to download it and try and out, but I've tried to list some of the more important changes below to help you out.
|
||||
|
||||
The major changes.
|
||||
|
||||
# IPvXAddress and IPvXNetwork classes.
|
||||
|
||||
* Individual addresses are now (IPv4|IPv6)Address objects. Network attributes that are actually addresses (eg, broadcast, network, hostmask) are now (IPv4|IPv6)Address objects. That means no more IPv4/IPv6 classes handling only networks.
|
||||
{{{
|
||||
In [3]: ipaddr.IPv4Network("1.1.1.0/24")
|
||||
Out[3]: IPv4Network('1.1.1.0/24')
|
||||
|
||||
In [4]: ipaddr.IPv4Network("1.1.1.0/24").network
|
||||
Out[4]: IPv4Address('1.1.1.0')
|
||||
|
||||
In [5]: ipaddr.IPv4Network("1.1.1.0/24").broadcast
|
||||
Out[5]: IPv4Address('1.1.1.255')
|
||||
}}}
|
||||
|
||||
* no more ext methods. To reference the stringified version of any attribute, you call str() on (similar for the numeric value with int()).
|
||||
{{{
|
||||
In [6]: str(ipaddr.IPv4Network("1.1.1.0/24").broadcast)
|
||||
Out[6]: '1.1.1.255'
|
||||
|
||||
In [7]: int(ipaddr.IPv4Network("1.1.1.0/24").broadcast)
|
||||
Out[7]: 16843263
|
||||
|
||||
In [8]: int(ipaddr.IPv4Network("1.1.1.0/24").network)
|
||||
Out[8]: 16843008
|
||||
|
||||
In [9]: str(ipaddr.IPv4Network("1.1.1.0/24").network)
|
||||
Out[9]: '1.1.1.0'
|
||||
}}}
|
||||
|
||||
* IP() everything-constructor has been replaced by IPAddress() and IPNetwork() constructors. It seems reasonable to assume that an application programmer will know when they are dealing strictly with ip addresses vs. networks and making this separation de-clutters the code. IPNetwork still assumes a default prefixlength of 32 for IPv4 and 128 for IPv6 if none is supplied (just like IP() used to), so when in doubt, you can always use IPNetwork.
|
||||
{{{
|
||||
In [16]: ipaddr.IPNetwork('1.1.1.1')
|
||||
Out[16]: IPv4Network('1.1.1.1/32')
|
||||
|
||||
In [17]: ipaddr.IPNetwork('1.1.1.1/12')
|
||||
Out[17]: IPv4Network('1.1.1.1/12')
|
||||
|
||||
In [18]: ipaddr.IPNetwork('::1')
|
||||
Out[18]: IPv6Network('::1/128')
|
||||
|
||||
In [19]: ipaddr.IPNetwork('::1/64')
|
||||
Out[19]: IPv6Network('::1/64')
|
||||
}}}
|
||||
|
||||
# Some other (but no less important) bug fixes/improvements:
|
||||
|
||||
* __ contains __ accepts strings/ints as well as (IPv4|IPv6)Address objects.
|
||||
{{{
|
||||
In [9]: ipaddr.IPAddress('1.1.1.1') in ipaddr.IPNetwork('1.1.1.0/24')
|
||||
Out[9]: True
|
||||
|
||||
In [10]: '1.1.1.1' in ipaddr.IPv4Network("1.1.1.0/24")
|
||||
Out[10]: True
|
||||
|
||||
In [11]: '1' in ipaddr.IPv4Network("0.0.0.0/0")
|
||||
Out[11]: True
|
||||
|
||||
In [12]: 1 in ipaddr.IPv4Network("0.0.0.0/0")
|
||||
Out[12]: True
|
||||
}}}
|
||||
* summarize_address_range. You can now get a list of all of the networks between two distinct (IPv4|IPv6)Address'es (results in potentially huge speed boosts for address collapsing)
|
||||
{{{
|
||||
In [14]: ipaddr.summarize_address_range(ipaddr.IPAddress('1.1.0.0'), ipaddr.IPAddress('1.1.255.255'))
|
||||
Out[14]: [IPv4Network('1.1.0.0/16')]
|
||||
|
||||
In [15]: ipaddr.summarize_address_range(ipaddr.IPAddress('1.1.0.0'), ipaddr.IPAddress('1.1.255.254'))
|
||||
Out[15]:
|
||||
[IPv4Network('1.1.0.0/17'),
|
||||
IPv4Network('1.1.128.0/18'),
|
||||
IPv4Network('1.1.192.0/19'),
|
||||
IPv4Network('1.1.224.0/20'),
|
||||
IPv4Network('1.1.240.0/21'),
|
||||
IPv4Network('1.1.248.0/22'),
|
||||
IPv4Network('1.1.252.0/23'),
|
||||
IPv4Network('1.1.254.0/24'),
|
||||
IPv4Network('1.1.255.0/25'),
|
||||
IPv4Network('1.1.255.128/26'),
|
||||
IPv4Network('1.1.255.192/27'),
|
||||
IPv4Network('1.1.255.224/28'),
|
||||
IPv4Network('1.1.255.240/29'),
|
||||
IPv4Network('1.1.255.248/30'),
|
||||
IPv4Network('1.1.255.252/31'),
|
||||
IPv4Network('1.1.255.254/32')]
|
||||
}}}
|
||||
|
||||
* network iterators. the (IPv4|IPv6)Network classes now implement iterators to help quickly access each member of a network in sequence:
|
||||
{{{
|
||||
|
||||
In [24]: for addr in iter(ipaddr.IPNetwork('1.1.1.1/28')): addr
|
||||
....:
|
||||
Out[24]: IPv4Address('1.1.1.0')
|
||||
Out[24]: IPv4Address('1.1.1.1')
|
||||
Out[24]: IPv4Address('1.1.1.2')
|
||||
Out[24]: IPv4Address('1.1.1.3')
|
||||
Out[24]: IPv4Address('1.1.1.4')
|
||||
Out[24]: IPv4Address('1.1.1.5')
|
||||
Out[24]: IPv4Address('1.1.1.6')
|
||||
Out[24]: IPv4Address('1.1.1.7')
|
||||
Out[24]: IPv4Address('1.1.1.8')
|
||||
Out[24]: IPv4Address('1.1.1.9')
|
||||
Out[24]: IPv4Address('1.1.1.10')
|
||||
Out[24]: IPv4Address('1.1.1.11')
|
||||
Out[24]: IPv4Address('1.1.1.12')
|
||||
Out[24]: IPv4Address('1.1.1.13')
|
||||
Out[24]: IPv4Address('1.1.1.14')
|
||||
Out[24]: IPv4Address('1.1.1.15')
|
||||
}}}
|
||||
|
||||
* additionally, an iterhosts() method has been added to allow for iterating over all of the usable addresses on a network (everything except the network and broadcast addresses)
|
||||
{{{
|
||||
In [26]: for addr in ipaddr.IPNetwork('1.1.1.1/28').iterhosts(): addr
|
||||
....:
|
||||
Out[26]: IPv4Address('1.1.1.1')
|
||||
Out[26]: IPv4Address('1.1.1.2')
|
||||
Out[26]: IPv4Address('1.1.1.3')
|
||||
Out[26]: IPv4Address('1.1.1.4')
|
||||
Out[26]: IPv4Address('1.1.1.5')
|
||||
Out[26]: IPv4Address('1.1.1.6')
|
||||
Out[26]: IPv4Address('1.1.1.7')
|
||||
Out[26]: IPv4Address('1.1.1.8')
|
||||
Out[26]: IPv4Address('1.1.1.9')
|
||||
Out[26]: IPv4Address('1.1.1.10')
|
||||
Out[26]: IPv4Address('1.1.1.11')
|
||||
Out[26]: IPv4Address('1.1.1.12')
|
||||
Out[26]: IPv4Address('1.1.1.13')
|
||||
Out[26]: IPv4Address('1.1.1.14')
|
||||
}}}
|
||||
|
||||
Thanks to the python community and everyone who's made feature suggestions or submitted patches. Please continue to send bugs/enhancements/patches to the mailing list.
|
||||
|
||||
== 1.1.1 ==
|
||||
|
||||
This release contains a single important bugfix. All users of 1.1.0 should upgrade.
|
||||
|
||||
* r77 A logical error caused ordering operators to behave incorrectly.
|
||||
|
||||
== 1.1.0 ==
|
||||
|
||||
`ipaddr.py` is now part of the standard library in Python 2.7 and 3.1! This release is compatible with the `ipaddr` from future versions of Python.
|
||||
|
||||
Special thanks to Philipp Hagemeister for making most of the improvements to this release, and to Gregory P. Smith for shepherding this into the Python standard library.
|
||||
|
||||
* r59 Method names are now PEP-8 compliant, instead of Google-style camel case. The old method names remain, but are deprecated; you should use the lowercase names to be compatible with Python 2.7/3.1. (pmoody)
|
||||
* r63 .prefixlen is now a property. (pmoody)
|
||||
* r64 Stronger validation. (Philipp Hagemeister)
|
||||
* r65 1.2.3.4 is not a valid v6 address, so we can simplify the constructor. (Philipp Hagemeister)
|
||||
* r66 Expand rich comparison operations and their tests, with a goal of supporting 2to3. Add a new method .networks_key(). Add a new script to run through 2to3 and make sure tests pass under Python 3 with the converted version. (Philipp Hagemeister)
|
||||
* r68 New method .packed(). (Philipp Hagemeister)
|
||||
* r69 Add `is_multicast`, `is_unspecified`, `is_loopback`, `is_link_local`, `is_site_local`, and `is_private` for IPv6. Make more methods into properties. Improved documentation and tests for `is_*` properties for IPv4 and IPv6. Rename `networks_key()` to `_get_networks_key()`.
|
||||
* r71 Fix off-by-one bug (issue 15). (gpsmith)
|
||||
|
||||
== 1.0.2 ==
|
||||
* r52 Force the return value in testHexRepresentation to uppercase to workaround Python version. (smart)
|
||||
* r51 Fix testHexRepresentation(). Hex representations of longs are uppercase. (smart)
|
||||
* r50 Remove trailing whitespace and update docstrings. (smart)
|
||||
* r44. this makes the spacing and docstrings pep8 compliant. (pmoody)
|
||||
* r43. When processing the IPv4 mapped address 16 bits at a time, the components are stored in the reverse order. Updated the test to use a non-symmetric IPv4 address, which exhibited the bug. (smart)
|
||||
* r40. implment __int__ and __hex__. will need to be updated for py3k (to use __index__) (pmoody)
|
||||
* r38 A cleanup from issue 9 : Make exception messages consistent for IP(''), IPv4(''), IPv6('') (smart)
|
||||
* r37 Fix for issue 9 : ipaddr.IP('') should raise ValueError (mshields)
|
||||
|
||||
== 1.0.1 ==
|
||||
|
||||
* str() now produces lowercase for IPv6 addresses, to match inet_pton(3). (http://codereview.appspot.com/7678)
|
||||
* repr() now produces strings that can be pasted back into the interpreter.
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2008 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from distutils.core import setup
|
||||
|
||||
import ipaddr
|
||||
|
||||
|
||||
setup(name='ipaddr',
|
||||
maintainer='Google',
|
||||
maintainer_email='ipaddr-py-dev@googlegroups.com',
|
||||
version=ipaddr.__version__,
|
||||
url='http://code.google.com/p/ipaddr-py/',
|
||||
license='Apache License, Version 2.0',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Internet',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
'Topic :: System :: Networking'],
|
||||
py_modules=['ipaddr'])
|
|
@ -5,6 +5,7 @@ packages/python-memcached
|
|||
packages/pytz
|
||||
packages/PyYAML/lib
|
||||
packages/futures
|
||||
packages/ipaddr
|
||||
src/basket-client
|
||||
src/bleach
|
||||
src/chkcrontab
|
||||
|
|
Загрузка…
Ссылка в новой задаче