Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-django-ipware for openSUSE:Factory checked in at 2021-12-26 13:30:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-django-ipware (Old) and /work/SRC/openSUSE:Factory/.python-django-ipware.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-ipware" Sun Dec 26 13:30:36 2021 rev:2 rq:942586 version:4.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-django-ipware/python-django-ipware.changes 2020-09-15 16:29:46.422682009 +0200 +++ /work/SRC/openSUSE:Factory/.python-django-ipware.new.2520/python-django-ipware.changes 2021-12-26 13:30:56.634977670 +0100 @@ -1,0 +2,14 @@ +Sun Dec 26 10:44:22 UTC 2021 - John Vandenberg <jay...@gmail.com> + +- Update to v4.0.2 + * Added support for Python 3.10 +- from v4.0.1 + * Added test for django 4.0 +- from v4.0.0 + * Added test to cover more proxy scenarios +- from v3.0.3-3.0.7 + * Clean ups +- from v3.0.2 + * Add support for ppc64le + +------------------------------------------------------------------- Old: ---- django-ipware-3.0.1.tar.gz New: ---- django-ipware-4.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-django-ipware.spec ++++++ --- /var/tmp/diff_new_pack.uEHpzO/_old 2021-12-26 13:30:57.050977960 +0100 +++ /var/tmp/diff_new_pack.uEHpzO/_new 2021-12-26 13:30:57.058977965 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-django-ipware # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,13 +19,13 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-django-ipware -Version: 3.0.1 +Version: 4.0.2 Release: 0 Summary: Django utility application that returns client's real IP address License: MIT Group: Development/Languages/Python URL: https://github.com/un33k/django-ipware -Source: https://files.pythonhosted.org/packages/source/d/django-ipware/django-ipware-%{version}.tar.gz +Source: https://github.com/un33k/django-ipware/archive/refs/tags/v%{version}.tar.gz#/django-ipware-%{version}.tar.gz BuildRequires: %{python_module Django} BuildRequires: %{python_module setuptools} BuildRequires: fdupes ++++++ django-ipware-3.0.1.tar.gz -> django-ipware-4.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/.github/workflows/ci.yml new/django-ipware-4.0.2/.github/workflows/ci.yml --- old/django-ipware-3.0.1/.github/workflows/ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/.github/workflows/ci.yml 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,51 @@ +name: (CI) + +on: + push: + branches: + - ci + +jobs: + build: + name: Python ${{ matrix.python-version }}, django ${{ matrix.django-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9, "3.10", pypy3] + django-version: [2.2, 3.0, 3.1, 3.2, 4.0] + exclude: + # excludes list + - python-version: 3.6 + django-version: 4.0 + - python-version: 3.7 + django-version: 4.0 + - python-version: pypy3 + django-version: 4.0 + + steps: + - uses: actions/checkout@v2 + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + pip install coveralls + pip install "django~=${{ matrix.django-version }}.0" + - name: Run flake8 + run: | + pip install flake8 + flake8 --exclude=migrations,tests --ignore=E501,E241,E225,E128 . + - name: Run pycodestyle + run: | + pip install pycodestyle + pycodestyle --exclude=migrations,tests --ignore=E501,E241,E225,E128 . + - name: Run test + run: | + coverage run --source=ipware manage.py test + - name: Coveralls + run: coveralls --service=github + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/.github/workflows/dev.yml new/django-ipware-4.0.2/.github/workflows/dev.yml --- old/django-ipware-3.0.1/.github/workflows/dev.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/.github/workflows/dev.yml 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,54 @@ +name: DEV + +# Run on push only for dev/sandbox +# Otherwise it may trigger concurrently `push & pull_request` on PRs. +on: + push: + branches: + - sandbox + - dev + +jobs: + build: + name: Python ${{ matrix.python-version }}, django ${{ matrix.django-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9, "3.10", pypy3] + django-version: [2.2, 3.0, 3.1, 3.2, 4.0] + exclude: + # excludes list + - python-version: 3.6 + django-version: 4.0 + - python-version: 3.7 + django-version: 4.0 + - python-version: pypy3 + django-version: 4.0 + + steps: + - uses: actions/checkout@v2 + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + pip install coveralls + pip install "django~=${{ matrix.django-version }}.0" + - name: Run flake8 + run: | + pip install flake8 + flake8 --exclude=migrations,tests --ignore=E501,E241,E225,E128 . + - name: Run pycodestyle + run: | + pip install pycodestyle + pycodestyle --exclude=migrations,tests --ignore=E501,E241,E225,E128 . + - name: Run test + run: | + coverage run --source=ipware manage.py test + - name: Coveralls + run: coveralls --service=github + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/.github/workflows/main.yml new/django-ipware-4.0.2/.github/workflows/main.yml --- old/django-ipware-3.0.1/.github/workflows/main.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/.github/workflows/main.yml 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,52 @@ +name: MAIN + +# Run on push only for main +# Otherwise it may trigger concurrently `push & pull_request` on PRs. +on: + push: + branches: + - master + +jobs: + build: + name: Python ${{ matrix.python-version }}, django ${{ matrix.django-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8, 3.9, "3.10", pypy3] + django-version: [2.2, 3.0, 3.1, 3.2, 4.0] + exclude: + # excludes list + - python-version: 3.6 + django-version: 4.0 + - python-version: 3.7 + django-version: 4.0 + - python-version: pypy3 + django-version: 4.0 + steps: + - uses: actions/checkout@v2 + - name: setup python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + pip install coveralls + pip install "django~=${{ matrix.django-version }}.0" + - name: Run flake8 + run: | + pip install flake8 + flake8 --exclude=migrations,tests --ignore=E501,E241,E225,E128 . + - name: Run pycodestyle + run: | + pip install pycodestyle + pycodestyle --exclude=migrations,tests --ignore=E501,E241,E225,E128 . + - name: Run test + run: | + coverage run --source=ipware manage.py test + - name: Coveralls + run: coveralls --service=github + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/.gitignore new/django-ipware-4.0.2/.gitignore --- old/django-ipware-3.0.1/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/.gitignore 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,57 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/.vscode/settings.json new/django-ipware-4.0.2/.vscode/settings.json --- old/django-ipware-3.0.1/.vscode/settings.json 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/.vscode/settings.json 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,19 @@ +{ + "python.linting.enabled": false, + "cSpell.words": [ + "Neekman", + "Neekware", + "Pware", + "cmdclass", + "getattr", + "ipware", + "multicast", + "noqa", + "pycodestyle", + "pyflakes", + "routable", + "setuptools", + "stackoverflow", + "vneekman" + ] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/CHANGELOG.md new/django-ipware-4.0.2/CHANGELOG.md --- old/django-ipware-3.0.1/CHANGELOG.md 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/CHANGELOG.md 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,208 @@ +# 4.0.2 + +Enhancement: + +- Added support for Python 3.10 (Thx joshuadavidthomas) + +## 4.0.1 + +Enhancement: + +- Added test for django 4.0 (Thx PetrDlouhy) + +## 4.0.0 + +Enhancement: + +- Added test to cover more proxy scenarios (thx: Phillip Kuhrt) +- Up versioned major version number as some scenarios have changed + +## 3.0.4 / 3.0.5 / 3.0.6 / 3.0.7 + +Enhancement: + +- Clean ups + +## 3.0.3 + +Enhancement: + +- Add support for github action (@awais786) + +## 3.0.2 + +Enhancement: + +- Add support for ppc64le (@kishorkunal-raj) + +## 3.0.1 + +Fix: + +- Ensure no-required build artifacts won't get into the package + +## 3.0.0 + +Enhancement: + +- Remove deprecated logic +- Drop "official" support for py < 3.5 +- Update to latest Django + +## 2.1.1 + +Enhancement: + +- Added deprecation warnings preparing for version 3.0 +- Update to latest Django + +## 2.1.0 + +Enhancement: + +- Added more non-routable ip blocks (@wking) + +## 2.0.2 + +Enhancement: + +- Added the ability to private the request precedence order on each call + +## 2.0.1 + +Enhancement: + +- Added more private IP blocks to the default list + +## 2.0.0 + +Fix: + +- Update Django versions (@illagrenan) +- Update Readme (@sabueso) +- Added proxy count +- Moved version one readme to /docs + +## 1.1.6 + +Fix: + +- Fix trusted proxies Right2Left + Test & Bumped Django versions (@felixxm) +- Changed licensing to MIT + +## 1.1.5 + +Feature: + +- Added support for trusted proxy configuration + +## 1.1.4 + +Enhancement: + +- Added support for proxies with `underscores_in_headers off;` +- Handling hyphen as delimiter - ex: `X-FORWARDED-FOR` instead of `X_FORWARDED_FOR` +- Up version Django version in .travis.yml + +## 1.1.3 + +Fix: + +- Fix read me file updating `IPWARE_META_PRECEDENCE_ORDER` reference. + +## 1.1.2 + +Updates: + +- Added support for Django 1.8.6 and Python 3.5. +- Dropped support for Django 1.4.x and Python 2.6 and 3.2 + +## 1.1.1 + +Enhancement: + +- Added support for X_FORWARDED_FOR + +## 1.1.0 + +Enhancement: + +- Added support for 1.0.0.0/8 and 2.0.0.0/8 blocks + +## 1.0.0 + +Enhancement: + +- Promoting to production grade + +## 0.1.1 + +Enhancement: + +- Support for Left2Right or Right2Left Proxy IP Lookup + +## 0.1.0 + +Enhancement: + +- pypy support +- PY3.4 support + +## 0.0.9 + +Enhancement: + +- Django 1.7 official support +- First non-loopback private IP match is best matched now. + +## 0.0.8 + +Enhancement: + +- Django 1.7 support +- PEP8 Compliance +- Bump Alpha to Beta + +## 0.0.6 + +Enhancement: + +- Converted print statements to new format. (Python 3.x) +- Replaced deprecated unit test APIs + +## 0.0.5 + +Enhancement: + +- Added Python 3.2 and 3.3 support + +## 0.0.4 + +Enhancement: + +- Added changelog file +- Added more private ip prefixes + +## 0.0.3 + +Features: + +- Added get_ip() to return the best-matched IP +- Removed get_ip_address_from_request() + +Bugfixes: + +- Expended the private IP range + +## 0.0.2 + +Features: + +- IPv6 support +- Added get_real_ip(), the shorter version of get_ip_address_from_request() + +## 0.0.1 + +Features: + +- Initial Release diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/CONTRIBUTING.md new/django-ipware-4.0.2/CONTRIBUTING.md --- old/django-ipware-3.0.1/CONTRIBUTING.md 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/CONTRIBUTING.md 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,4 @@ +1. django-ipware is a reserved name. Please do not clone and publish as django-ipware2, django-ipware3 etc. +2. please review the issues first before creating a new one. +3. please visit the read me, or use stackoverflow for how to use this package. Do not create an issue for your questions. +4. please use a private message if you find a security issue. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/PKG-INFO new/django-ipware-4.0.2/PKG-INFO --- old/django-ipware-3.0.1/PKG-INFO 2020-08-07 05:22:49.000000000 +0200 +++ new/django-ipware-4.0.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,21 +0,0 @@ -Metadata-Version: 1.1 -Name: django-ipware -Version: 3.0.1 -Summary: A Django utility application that returns client's real IP address -Home-page: https://github.com/un33k/django-ipware -Author: Val Neekman -Author-email: i...@neekware.com -License: MIT -Description: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Topic :: Utilities diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/README.md new/django-ipware-4.0.2/README.md --- old/django-ipware-3.0.1/README.md 2020-08-07 05:22:24.000000000 +0200 +++ new/django-ipware-4.0.2/README.md 2021-12-16 18:03:54.000000000 +0100 @@ -1,5 +1,4 @@ -Django IPware -==================== +# Django IPware **A Django application to retrieve client's IP address** @@ -7,22 +6,18 @@ [![version-image]][version-link] [![coverage-image]][coverage-link] -Overview -==================== +# Overview **Best attempt** to get client's IP address while keeping it **DRY**. -Notice -==================== +# Notice -There is not a good *out-of-the-box* solution against fake IP addresses, aka *IP Address Spoofing*. +There is not a good `out-of-the-box` solution against fake IP addresses, aka `IP Address Spoofing`. You are encouraged to read the ([Advanced users](README.md#advanced-users)) section of this page and -use `trusted_proxies_ips` and/or `proxy_count` features to match your needs, especially *if* you are -planning to include `ipware` in any authentication, security or *anti-fraud* related architecture. +use `trusted_proxies_ips` and/or `proxy_count` features to match your needs, especially `if` you are +planning to include `ipware` in any authentication, security or `anti-fraud` related architecture. - -How to install -==================== +# How to install 1. easy_install django-ipware 2. pip install django-ipware @@ -34,50 +29,49 @@ b. cd into django-ipware-* directory c. run python setup.py install +# How to use + +```python + # In a view or a middleware where the `request` object is available -How to use -==================== + from ipware import get_client_ip + client_ip, is_routable = get_client_ip(request) + if client_ip is None: + # Unable to get the client's IP address + else: + # We got the client's IP address + if is_routable: + # The client's IP address is publicly routable on the Internet + else: + # The client's IP address is private - ```python - # In a view or a middleware where the `request` object is available + # Order of precedence is (Public, Private, Loopback, None) +``` - from ipware import get_client_ip - client_ip, is_routable = get_client_ip(request) - if client_ip is None: - # Unable to get the client's IP address - else: - # We got the client's IP address - if is_routable: - # The client's IP address is publicly routable on the Internet - else: - # The client's IP address is private +# Advanced users: - # Order of precedence is (Public, Private, Loopback, None) - ``` +- ### Precedence Order + The default meta precedence order is top to bottom. However, you may customize the order + by providing your own `IPWARE_META_PRECEDENCE_ORDER` by adding it to your project's settings.py -Advanced users: -==================== + ```python + # The default meta precedence order + IPWARE_META_PRECEDENCE_ORDER = ( + 'HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR', # <client>, <proxy1>, <proxy2> + 'HTTP_CLIENT_IP', + 'HTTP_X_REAL_IP', + 'HTTP_X_FORWARDED', + 'HTTP_X_CLUSTER_CLIENT_IP', + 'HTTP_FORWARDED_FOR', + 'HTTP_FORWARDED', + 'HTTP_VIA', + 'REMOTE_ADDR', + ) + ``` -- ### Precedence Order -The default meta precedence order is top to bottom. However, you may customize the order -by providing your own `IPWARE_META_PRECEDENCE_ORDER` by adding it to your project's settings.py + **Alternatively**, you can provide your custom _request header meta precedence order_ when calling `get_client_ip()`. - ```python - # The default meta precedence order - IPWARE_META_PRECEDENCE_ORDER = ( - 'HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR', # <client>, <proxy1>, <proxy2> - 'HTTP_CLIENT_IP', - 'HTTP_X_REAL_IP', - 'HTTP_X_FORWARDED', - 'HTTP_X_CLUSTER_CLIENT_IP', - 'HTTP_FORWARDED_FOR', - 'HTTP_FORWARDED', - 'HTTP_VIA', - 'REMOTE_ADDR', - ) - ``` -**Alternatively**, you can provide your custom *request header meta precedence order* when calling `get_client_ip()`. ```python get_client_ip(request, request_header_order=['X_FORWARDED_FOR']) get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR']) @@ -86,53 +80,53 @@ ### Private Prefixes You may customize the prefixes to indicate an IP address is private. This is done by adding your -own `IPWARE_PRIVATE_IP_PREFIX` to your project's settings.py. IP addresses matching the following -prefixes are considered *private* & are **not** publicly routable. +own `IPWARE_PRIVATE_IP_PREFIX` to your project's settings.py. IP addresses matching the following +prefixes are considered _private_ & are **not** publicly routable. - ```python - # The default private IP prefixes - IPWARE_PRIVATE_IP_PREFIX = getattr(settings, - 'IPWARE_PRIVATE_IP_PREFIX', ( - '0.', # messages to software - '10.', # class A private block - '100.64.', '100.65.', '100.66.', '100.67.', '100.68.', '100.69.', - '100.70.', '100.71.', '100.72.', '100.73.', '100.74.', '100.75.', - '100.76.', '100.77.', '100.78.', '100.79.', '100.80.', '100.81.', - '100.82.', '100.83.', '100.84.', '100.85.', '100.86.', '100.87.', - '100.88.', '100.89.', '100.90.', '100.91.', '100.92.', '100.93.', - '100.94.', '100.95.', '100.96.', '100.97.', '100.98.', '100.99.', - '100.100.', '100.101.', '100.102.', '100.103.', '100.104.', '100.105.', - '100.106.', '100.107.', '100.108.', '100.109.', '100.110.', '100.111.', - '100.112.', '100.113.', '100.114.', '100.115.', '100.116.', '100.117.', - '100.118.', '100.119.', '100.120.', '100.121.', '100.122.', '100.123.', - '100.124.', '100.125.', '100.126.', '100.127.', # carrier-grade NAT - '169.254.', # link-local block - '172.16.', '172.17.', '172.18.', '172.19.', - '172.20.', '172.21.', '172.22.', '172.23.', - '172.24.', '172.25.', '172.26.', '172.27.', - '172.28.', '172.29.', '172.30.', '172.31.', # class B private blocks - '192.0.0.', # reserved for IANA special purpose address registry - '192.0.2.', # reserved for documentation and example code - '192.168.', # class C private block - '198.18.', '198.19.', # reserved for inter-network communications between two separate subnets - '198.51.100.', # reserved for documentation and example code - '203.0.113.', # reserved for documentation and example code - '224.', '225.', '226.', '227.', '228.', '229.', '230.', '231.', '232.', - '233.', '234.', '235.', '236.', '237.', '238.', '239.', # multicast - '240.', '241.', '242.', '243.', '244.', '245.', '246.', '247.', '248.', - '249.', '250.', '251.', '252.', '253.', '254.', '255.', # reserved - ) + ( - '::', # Unspecified address - '::ffff:', '2001:10:', '2001:20:' # messages to software - '2001::', # TEREDO - '2001:2::', # benchmarking - '2001:db8:', # reserved for documentation and example code - 'fc00:', # IPv6 private block - 'fe80:', # link-local unicast - 'ff00:', # IPv6 multicast - ) - ) - ``` +```python +# The default private IP prefixes +IPWARE_PRIVATE_IP_PREFIX = getattr(settings, + 'IPWARE_PRIVATE_IP_PREFIX', ( + '0.', # messages to software + '10.', # class A private block + '100.64.', '100.65.', '100.66.', '100.67.', '100.68.', '100.69.', + '100.70.', '100.71.', '100.72.', '100.73.', '100.74.', '100.75.', + '100.76.', '100.77.', '100.78.', '100.79.', '100.80.', '100.81.', + '100.82.', '100.83.', '100.84.', '100.85.', '100.86.', '100.87.', + '100.88.', '100.89.', '100.90.', '100.91.', '100.92.', '100.93.', + '100.94.', '100.95.', '100.96.', '100.97.', '100.98.', '100.99.', + '100.100.', '100.101.', '100.102.', '100.103.', '100.104.', '100.105.', + '100.106.', '100.107.', '100.108.', '100.109.', '100.110.', '100.111.', + '100.112.', '100.113.', '100.114.', '100.115.', '100.116.', '100.117.', + '100.118.', '100.119.', '100.120.', '100.121.', '100.122.', '100.123.', + '100.124.', '100.125.', '100.126.', '100.127.', # carrier-grade NAT + '169.254.', # link-local block + '172.16.', '172.17.', '172.18.', '172.19.', + '172.20.', '172.21.', '172.22.', '172.23.', + '172.24.', '172.25.', '172.26.', '172.27.', + '172.28.', '172.29.', '172.30.', '172.31.', # class B private blocks + '192.0.0.', # reserved for IANA special purpose address registry + '192.0.2.', # reserved for documentation and example code + '192.168.', # class C private block + '198.18.', '198.19.', # reserved for inter-network communications between two separate subnets + '198.51.100.', # reserved for documentation and example code + '203.0.113.', # reserved for documentation and example code + '224.', '225.', '226.', '227.', '228.', '229.', '230.', '231.', '232.', + '233.', '234.', '235.', '236.', '237.', '238.', '239.', # multicast + '240.', '241.', '242.', '243.', '244.', '245.', '246.', '247.', '248.', + '249.', '250.', '251.', '252.', '253.', '254.', '255.', # reserved + ) + ( + '::', # Unspecified address + '::ffff:', '2001:10:', '2001:20:' # messages to software + '2001::', # TEREDO + '2001:2::', # benchmarking + '2001:db8:', # reserved for documentation and example code + 'fc00:', # IPv6 private block + 'fe80:', # link-local unicast + 'ff00:', # IPv6 multicast + ) +) +``` ### Trusted Proxies @@ -140,71 +134,70 @@ by providing the `trusted` proxy list when calling `get_client_ip(request, proxy_trusted_ips=['177.139.233.133'])`. In the following example, your load balancer (LB) can be seen as a `trusted` proxy. - ``` - `Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server - ^ - | - `Fake` Client <private> <---> <private> LB (Server) <private> ---^ - ``` - - - ```python - # In the above scenario, use your load balancer's IP address as a way to filter out unwanted requests. - client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133']) - - # If you have multiple proxies, simply add them to the list - client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133', '177.139.233.134']) - - # For proxy servers with fixed sub-domain and dynamic IP, use the following pattern. - client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.', '177.140']) - client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.', '177.139.240']) - ``` +``` + `Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server + ^ + | + `Fake` Client <private> <---> <private> LB (Server) <private> ---^ +``` + +```python +# In the above scenario, use your load balancer IP address as a way to filter out unwanted requests. +client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133']) + +# If you have multiple proxies, simply add them to the list +client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.133', '177.139.233.134']) + +# For proxy servers with fixed sub-domain and dynamic IP, use the following pattern. +client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.', '177.140']) +client_ip, is_routable = get_client_ip(request, proxy_trusted_ips=['177.139.233.', '177.139.240']) +``` + +`Please note:` By default, the `right-most` proxy in the chain is the `trusted` proxy and that is the one your django +server talks to. Therefore, `ipware` checks to see if the `right-most` proxy address starts with any ip pattern that was +passed in via the `proxy_trusted_ips` list. ### Proxy Count -If your Django server is behind a *known* number of proxy server(s), you can filter out unwanted requests -by providing the *number* of proxies when calling `get_client_ip(request, proxy_count=1)`. -In the following example, your load balancer (LB) can be seen as the *only* proxy. - - ``` - `Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server - ^ - | - `Fake` Client <private> ---^ - ``` - - ```python - # In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests. - client_ip, is_routable = get_client_ip(request, proxy_count=1) - - # The above may be very useful in cases where your proxy server's IP address is assigned dynamically. - # However, If you have the proxy IP address, you can use it in combination to the proxy count. - client_ip, is_routable = get_client_ip(request, proxy_count=1, proxy_trusted_ips=['177.139.233.133']) - ``` +If your Django server is behind a `known` number of proxy server(s), you can filter out unwanted requests +by providing the `number` of proxies when calling `get_client_ip(request, proxy_count=1)`. +In the following example, your load balancer (LB) can be seen as the `only` proxy. + +``` + `Real` Client <public> <---> <public> LB (Server) <private> <--------> <private> Django Server + ^ + | + `Fake` Client <private> ---^ +``` + +```python +# In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests. +client_ip, is_routable = get_client_ip(request, proxy_count=1) + +# The above may be very useful in cases where your proxy server's IP address is assigned dynamically. +# However, If you have the proxy IP address, you can use it in combination to the proxy count. +client_ip, is_routable = get_client_ip(request, proxy_count=1, proxy_trusted_ips=['177.139.233.133']) +``` ### Originating Request If your proxy server is configured such that the right-most IP address is that of the originating client, you can indicate `right-most` as your `proxy_order` when calling `get_client_ip(request, proxy_order="right-most")`. Please note that the [de-facto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) standard -for the originating client IP address is the `left-most` as per `<client>, <proxy1>, <proxy2>`. +for the originating client IP address is the `left-most` as per `<client>, <proxy1>, <proxy2>`. -Running the tests -==================== +# Running the tests To run the tests against the current environment: python manage.py test - -License -==================== +# License Released under a ([MIT](LICENSE)) license. +# Version -Version -==================== X.Y.Z Version `MAJOR` version -- when you make incompatible API changes, @@ -213,18 +206,13 @@ [status-image]: https://travis-ci.org/un33k/django-ipware.svg?branch=master [status-link]: https://travis-ci.org/un33k/django-ipware - [version-image]: https://img.shields.io/pypi/v/django-ipware.svg [version-link]: https://pypi.python.org/pypi/django-ipware - [coverage-image]: https://coveralls.io/repos/un33k/django-ipware/badge.svg [coverage-link]: https://coveralls.io/r/un33k/django-ipware - [download-image]: https://img.shields.io/pypi/dm/django-ipware.svg [download-link]: https://pypi.python.org/pypi/django-ipware - -Sponsors -==================== +# Sponsors [Neekware Inc.](http://neekware.com) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/django_ipware.egg-info/PKG-INFO new/django-ipware-4.0.2/django_ipware.egg-info/PKG-INFO --- old/django-ipware-3.0.1/django_ipware.egg-info/PKG-INFO 2020-08-07 05:22:49.000000000 +0200 +++ new/django-ipware-4.0.2/django_ipware.egg-info/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,21 +0,0 @@ -Metadata-Version: 1.1 -Name: django-ipware -Version: 3.0.1 -Summary: A Django utility application that returns client's real IP address -Home-page: https://github.com/un33k/django-ipware -Author: Val Neekman -Author-email: i...@neekware.com -License: MIT -Description: UNKNOWN -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Topic :: Utilities diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/django_ipware.egg-info/SOURCES.txt new/django-ipware-4.0.2/django_ipware.egg-info/SOURCES.txt --- old/django-ipware-3.0.1/django_ipware.egg-info/SOURCES.txt 2020-08-07 05:22:49.000000000 +0200 +++ new/django-ipware-4.0.2/django_ipware.egg-info/SOURCES.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,18 +0,0 @@ -LICENSE -README.md -setup.cfg -setup.py -django_ipware.egg-info/PKG-INFO -django_ipware.egg-info/SOURCES.txt -django_ipware.egg-info/dependency_links.txt -django_ipware.egg-info/top_level.txt -ipware/__init__.py -ipware/apps.py -ipware/defaults.py -ipware/ip.py -ipware/utils.py -ipware/tests/__init__.py -ipware/tests/tests_common.py -ipware/tests/tests_ipv4.py -ipware/tests/tests_ipv6.py -ipware/tests/testsettings.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/django_ipware.egg-info/dependency_links.txt new/django-ipware-4.0.2/django_ipware.egg-info/dependency_links.txt --- old/django-ipware-3.0.1/django_ipware.egg-info/dependency_links.txt 2020-08-07 05:22:49.000000000 +0200 +++ new/django-ipware-4.0.2/django_ipware.egg-info/dependency_links.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/django_ipware.egg-info/top_level.txt new/django-ipware-4.0.2/django_ipware.egg-info/top_level.txt --- old/django-ipware-3.0.1/django_ipware.egg-info/top_level.txt 2020-08-07 05:22:49.000000000 +0200 +++ new/django-ipware-4.0.2/django_ipware.egg-info/top_level.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -ipware -ipware/tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/docs/nginx.md new/django-ipware-4.0.2/docs/nginx.md --- old/django-ipware-3.0.1/docs/nginx.md 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/docs/nginx.md 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,26 @@ +### Nginx Users + +By default,using Ningx as a reverse proxy to Gunicorn doesn't forward the client's IP to gunicorn. +As a reverse proxy, NGINX will receive HTTP requests from clients and then send those requests to our +Gunicorn WSGI server. The problem is that NGINX hides information from our WSGI server. +The HTTP request that Gunicorn receives is not the same as the one that NGINX received from the client. +To solve this problem, open up your `nginx conf file` and add the following lines to the `location` block +``` +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header Host $host; +proxy_set_header X-Forwarded-Proto $scheme; +``` + +``` +server { + listen 80; + location / { + include proxy_params; + proxy_pass http://unix:/<where_your_sock_file_is>/coincard.sock; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + } +} + +``` \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/format.sh new/django-ipware-4.0.2/format.sh --- old/django-ipware-3.0.1/format.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/format.sh 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,11 @@ +#!/bin/bash + +# Ignoring autogenerated files +# -- Migration directories +# Ignoring error codes +# -- E128 continuation line under-indented for visual indent +# -- E225 missing whitespace around operator +# -- E501 line too long + +pycodestyle --exclude=migrations,tests --ignore=E128,E225,E241,E501 . +flake8 --exclude=migrations,tests --ignore=E128,E225,E241,E501 . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/ipware/__init__.py new/django-ipware-4.0.2/ipware/__init__.py --- old/django-ipware-3.0.1/ipware/__init__.py 2020-08-07 05:22:24.000000000 +0200 +++ new/django-ipware-4.0.2/ipware/__init__.py 2021-12-16 18:03:54.000000000 +0100 @@ -1,7 +1,3 @@ from .ip import get_client_ip # noqa default_app_config = 'ipware.apps.IPwareConfig' - -__author__ = 'Val Neekman @ Neekware Inc. [@vneekman]' -__description__ = "A Django application to retrieve user's IP address" -__version__ = '3.0.1' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/ipware/__version__.py new/django-ipware-4.0.2/ipware/__version__.py --- old/django-ipware-3.0.1/ipware/__version__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/ipware/__version__.py 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,8 @@ +__title__ = 'django-ipware' +__author__ = 'Val Neekman' +__author_email__ = 'i...@neekware.com' +__description__ = "A Django application to retrieve user's IP address" +__url__ = 'https://github.com/un33k/django-ipware' +__license__ = 'MIT' +__copyright__ = 'Copyright 2020 Val Neekman @ Neekware Inc.' +__version__ = '4.0.2' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/ipware/apps.py new/django-ipware-4.0.2/ipware/apps.py --- old/django-ipware-3.0.1/ipware/apps.py 2020-08-07 05:22:24.000000000 +0200 +++ new/django-ipware-4.0.2/ipware/apps.py 2021-12-16 18:03:54.000000000 +0100 @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class IPwareConfig(AppConfig): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/ipware/ip.py new/django-ipware-4.0.2/ipware/ip.py --- old/django-ipware-3.0.1/ipware/ip.py 2020-08-07 05:22:24.000000000 +0200 +++ new/django-ipware-4.0.2/ipware/ip.py 2021-12-16 18:03:54.000000000 +0100 @@ -48,7 +48,8 @@ if proxy_trusted_ips: for proxy in proxy_trusted_ips: - if proxy in ips[-1]: + # right most proxy is the most reliable proxy that talks to the django server + if ips[-1].startswith(proxy): client_ip, routable = util.get_ip_info(ips[0]) if client_ip and routable: return client_ip, routable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/ipware/tests/tests_ipv4.py new/django-ipware-4.0.2/ipware/tests/tests_ipv4.py --- old/django-ipware-3.0.1/ipware/tests/tests_ipv4.py 2020-08-07 05:22:24.000000000 +0200 +++ new/django-ipware-4.0.2/ipware/tests/tests_ipv4.py 2021-12-16 18:03:54.000000000 +0100 @@ -129,7 +129,7 @@ result = get_client_ip(request) self.assertEqual(result, ("177.139.233.139", True)) - def test_meta_proxy_trusted_ips(self): + def test_meta_proxy_trusted_ips_exact_ip_check(self): request = HttpRequest() request.META = { 'HTTP_X_FORWARDED_FOR': '177.139.233.139, 198.84.193.157, 198.84.193.158', @@ -137,6 +137,30 @@ result = get_client_ip(request, proxy_trusted_ips=['198.84.193.158']) self.assertEqual(result, ("177.139.233.139", True)) + def test_meta_proxy_trusted_ips_exact_ips_check(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '177.139.233.139, 198.84.193.157, 198.84.193.158', + } + result = get_client_ip(request, proxy_trusted_ips=['198.84.193.157', '198.84.193.158']) + self.assertEqual(result, ("177.139.233.139", True)) + + def test_meta_proxy_trusted_ips_subnet_start_with_check(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '177.139.233.139, 198.84.193.157, 198.84.193.158', + } + result = get_client_ip(request, proxy_trusted_ips=['198.84.193']) + self.assertEqual(result, ("177.139.233.139", True)) + + def test_meta_proxy_trusted_ips_does_not_start_with_check(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '177.139.233.139, 198.84.193.157, 198.84.193.158', + } + result = get_client_ip(request, proxy_trusted_ips=['84.193.158']) + self.assertEqual(result, (None, False)) + def test_meta_proxy_trusted_ips_proxy_count(self): request = HttpRequest() request.META = { @@ -197,7 +221,7 @@ ip = get_client_ip(request) self.assertEqual(ip, ("192.168.1.1", False)) - def test_best_matched_ip_private_precedence(self): + def test_best_matched_ip_private_loopback_precedence(self): request = HttpRequest() request.META = { 'HTTP_X_REAL_IP': '127.0.0.1', @@ -206,6 +230,15 @@ ip = get_client_ip(request) self.assertEqual(ip, ("192.168.1.1", False)) + def test_best_matched_ip_private_precedence(self): + request = HttpRequest() + request.META = { + 'HTTP_X_FORWARDED_FOR': '172.25.0.1', + 'REMOTE_ADDR': '172.25.0.3', + } + ip = get_client_ip(request) + self.assertEqual(ip, ("172.25.0.3", False)) + def test_100_low_range_public(self): request = HttpRequest() request.META = { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/manage.py new/django-ipware-4.0.2/manage.py --- old/django-ipware-3.0.1/manage.py 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/manage.py 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ipware.tests.testsettings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/pyproject.toml new/django-ipware-4.0.2/pyproject.toml --- old/django-ipware-3.0.1/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/pyproject.toml 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel" +] +build-backend = "setuptools.build_meta" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/requirement-dev.txt new/django-ipware-4.0.2/requirement-dev.txt --- old/django-ipware-3.0.1/requirement-dev.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/django-ipware-4.0.2/requirement-dev.txt 2021-12-16 18:03:54.000000000 +0100 @@ -0,0 +1,4 @@ +Django==4.0 +pycodestyle==2.7.0 +flake8==3.9.2 +twine==3.4.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/setup.cfg new/django-ipware-4.0.2/setup.cfg --- old/django-ipware-3.0.1/setup.cfg 2020-08-07 05:22:49.000000000 +0200 +++ new/django-ipware-4.0.2/setup.cfg 2021-12-16 18:03:54.000000000 +0100 @@ -1,10 +1,2 @@ -[bdist_wheel] -universal = 1 - [metadata] -license_file = LICENSE - -[egg_info] -tag_build = -tag_date = 0 - +license_file = LICENSE \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-ipware-3.0.1/setup.py new/django-ipware-4.0.2/setup.py --- old/django-ipware-3.0.1/setup.py 2020-08-07 05:22:24.000000000 +0200 +++ new/django-ipware-4.0.2/setup.py 2021-12-16 18:03:54.000000000 +0100 @@ -1,86 +1,83 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- - -from setuptools import setup -import re +# Learn more: https://github.com/un33k/setup.py import os import sys +from codecs import open +from shutil import rmtree +from setuptools import setup + -name = 'django-ipware' package = 'ipware' -description = "A Django utility application that returns client's real IP address" -url = 'https://github.com/un33k/django-ipware' -author = 'Val Neekman' -author_email = 'i...@neekware.com' -license = 'MIT' -install_requires = [''] -classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Web Environment', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Topic :: Utilities' -] - - -def get_version(package): - """ - Return package version as listed in `__version__` in `init.py`. - """ - init_py = open(os.path.join(package, '__init__.py')).read() - return re.search("^__version__ = ['\"]([^'\"]+)['\"]", init_py, re.MULTILINE).group(1) - - -def get_packages(package): - """ - Return root package and all sub-packages. - """ - return [dirpath - for dirpath, dirnames, filenames in os.walk(package) - if os.path.exists(os.path.join(dirpath, '__init__.py'))] - - -def get_package_data(package): - """ - Return all files under the root package, that are not in a - package themselves. - """ - walk = [(dirpath.replace(package + os.sep, '', 1), filenames) - for dirpath, dirnames, filenames in os.walk(package) - if not os.path.exists(os.path.join(dirpath, '__init__.py'))] - - filepaths = [] - for base, filenames in walk: - filepaths.extend([os.path.join(base, filename) - for filename in filenames]) - return {package: filepaths} +python_requires = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +here = os.path.abspath(os.path.dirname(__file__)) + +requires = [] +test_requirements = [] +about = {} +with open(os.path.join(here, package, '__version__.py'), 'r', 'utf-8') as f: + exec(f.read(), about) +with open('README.md', 'r', 'utf-8') as f: + readme = f.read() + + +def status(s): + print('\033[1m{0}\033[0m'.format(s)) + + +# 'setup.py publish' shortcut. if sys.argv[-1] == 'publish': - os.system("python setup.py sdist upload") - args = {'version': get_version(package)} - print("You probably want to also tag the version now:") - print(" git tag -a %(version)s -m 'version %(version)s' && git push --tags" % args) + try: + status('Removing previous builds???') + rmtree(os.path.join(here, 'dist')) + except OSError: + pass + + status('Building Source and Wheel (universal) distribution???') + os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable)) + + status('Uploading the package to PyPI via Twine???') + os.system('twine upload dist/*') + + status('Pushing git tags???') + os.system('git tag v{0}'.format(about['__version__'])) + os.system('git push --tags') sys.exit() - setup( - name=name, - version=get_version(package), - url=url, - license=license, - description=description, - author=author, - author_email=author_email, - packages=get_packages(package), - package_data=get_package_data(package), - install_requires=install_requires, - classifiers=classifiers + name=about['__title__'], + version=about['__version__'], + description=about['__description__'], + long_description=readme, + long_description_content_type='text/markdown', + author=about['__author__'], + author_email=about['__author_email__'], + url=about['__url__'], + packages=[package], + package_data={'': ['LICENSE']}, + package_dir={'ipware': 'ipware'}, + include_package_data=True, + python_requires=python_requires, + install_requires=requires, + license=about['__license__'], + zip_safe=False, + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Natural Language :: English', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + ], + cmdclass={}, + tests_require=test_requirements, + extras_require={}, + project_urls={}, )