diff --git a/.travis.yml b/.travis.yml
index 8e1e41c..72c2f56 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,10 @@
language: python
-before_install: pip install -r requirements.txt
+python:
+ - "2.7"
+ - "3.4"
+ - "3.5"
+ - "3.6"
+ - "3.7-dev"
-script: nosetests
\ No newline at end of file
+script: python setup.py test
diff --git a/packtrack/__init__.py b/packtrack/__init__.py
index 80d4852..969f14b 100755
--- a/packtrack/__init__.py
+++ b/packtrack/__init__.py
@@ -1,6 +1,6 @@
-from correios import EncomendaRepository
-from royal import RoyalMail
-from dhl_gm import DhlGmTracker
+from .correios import EncomendaRepository
+from .royal import RoyalMail
+from .dhl_gm import DhlGmTracker
class Correios(object):
diff --git a/packtrack/bs.py b/packtrack/bs.py
new file mode 100644
index 0000000..59f2676
--- /dev/null
+++ b/packtrack/bs.py
@@ -0,0 +1,9 @@
+import functools
+
+try:
+ from bs4 import BeautifulSoup
+ BeautifulSoup = functools.partial(BeautifulSoup, features="lxml")
+except ImportError:
+ from BeautifulSoup import BeautifulSoup
+
+BeautifulSoup = BeautifulSoup
diff --git a/packtrack/correios.py b/packtrack/correios.py
index 4514751..72a4f3c 100644
--- a/packtrack/correios.py
+++ b/packtrack/correios.py
@@ -15,7 +15,7 @@ def get(self, numero, auth=None):
return func(numero, **kwargs)
def _init_scraper(self, backend):
- from scraping import CorreiosWebsiteScraper, CorreiosRastroService
+ from .scraping import CorreiosWebsiteScraper, CorreiosRastroService
if backend is None:
backend = 'www2'
@@ -37,7 +37,7 @@ def adicionar_status(self, status):
d = datetime
self.status.append(status)
t_format = self.validar_data(status.data)
- self.status.sort(lambda x, y: 1 if d.strptime(x.data, t_format) > d.strptime(y.data, t_format) else -1)
+ self.status.sort(key=lambda x: d.strptime(x.data, t_format))
def validar_data(self, data):
if re.match('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$', data):
diff --git a/packtrack/royal.py b/packtrack/royal.py
index 38d2617..5032854 100644
--- a/packtrack/royal.py
+++ b/packtrack/royal.py
@@ -1,5 +1,6 @@
import requests
-from bs4 import BeautifulSoup
+
+from .bs import BeautifulSoup
class RoyalMail(object):
diff --git a/packtrack/scraping.py b/packtrack/scraping.py
index fc0c3b0..61f6f5d 100755
--- a/packtrack/scraping.py
+++ b/packtrack/scraping.py
@@ -1,15 +1,21 @@
import os
import re
-from HTMLParser import HTMLParser
-from BeautifulSoup import BeautifulSoup
+try:
+ from html.parser import HTMLParser
+ from html import unescape
+except ImportError:
+ from HTMLParser import HTMLParser
+ unescape = None
+
import requests
from requests.exceptions import RequestException
from zeep import Client as Zeep
from zeep.cache import InMemoryCache
from zeep.transports import Transport
-from correios import Encomenda, Status
+from .bs import BeautifulSoup
+from .correios import Encomenda, Status
class CorreiosWebsiteScraper(object):
@@ -65,6 +71,8 @@ def _text(self, value):
def _get_all_status_from_html(self, html):
status = []
html_parser = HTMLParser()
+ _unescape = unescape or html_parser.unescape
+
if "
).*', html, re.S)
@@ -80,15 +88,22 @@ def _get_all_status_from_html(self, html):
except AttributeError:
continue
for td in tds:
- content = td.renderContents().replace('\r', ' ') \
- .split('
')
- class_ = td['class']
+ content = td.renderContents()
+ content = content.replace(b'\r', b' ')
+ content = content.replace(b'\xa0', b' ')
+ content = content.replace(b'
', b'
')
+ content = content.split(b'
')
+
+ # bs4 return a list, bs3 return a string, join normalize
+ # this behaviour
+ class_ = "".join(td['class'])
+
if class_ == 'sroDtEvent':
data = '%s %s' % (content[0].strip(), content[1].strip())
local = '/'.join(self._text(content[2]).rsplit(' / ', 1)).upper()
elif class_ == 'sroLbEvent':
- situacao = html_parser.unescape(self._text(content[0]))
- detalhes = html_parser.unescape(self._text(content[1]))
+ situacao = _unescape(self._text(content[0]))
+ detalhes = _unescape(self._text(content[1]))
if detalhes:
detalhes = u'%s %s' % (situacao, detalhes)
status.append(Status(data=data, local=local,
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 5e0d12c..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-BeautifulSoup==3.2.1
-argparse==1.2.1
-beautifulsoup4==4.3.2
-lxml==2.3.5
-mockito==0.5.1
-requests==2.18.1
-wsgiref==0.1.2
-zeep==1.6.0
diff --git a/setup.py b/setup.py
index dfbab09..9e2c60c 100755
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,20 @@
# coding: UTF-8
from setuptools import setup
+import sys
+
+install_requires = [
+ 'requests >= 0.14.2',
+ 'lxml >= 3.0.0',
+ 'zeep >= 1.6.0',
+]
+if sys.version_info >= (3, 0):
+ install_requires.append('beautifulsoup4 >= 4.3.2')
+else:
+ install_requires.append('BeautifulSoup >= 3.1.0')
+
+tests_require = [
+]
+
setup(
name='packtrack',
@@ -12,11 +27,7 @@
keywords='encomendas track api',
url='https://github.com/aleborba/packtrack',
long_description='API Python para obter informacoes de encomendas. Para mais detalhes veja a documentacao no Github: https://github.com/aleborba/packtrack/blob/master/README.textile',
- install_requires=[
- 'BeautifulSoup >= 3.1.0',
- 'requests >= 0.14.2',
- 'beautifulsoup4 >= 4.3.2',
- 'lxml >= 2.3.5',
- 'zeep >= 1.6.0',
- ],
+ install_requires=install_requires,
+ test_suite="tests",
+ tests_require=tests_require,
)
diff --git a/tests/correios_api_test.py b/tests/correios_api_test.py
index 6777ec3..f5b62c4 100644
--- a/tests/correios_api_test.py
+++ b/tests/correios_api_test.py
@@ -1,7 +1,9 @@
import unittest
-from mock import Mock
-from mockito import when
+try:
+ from unittest.mock import Mock
+except ImportError:
+ from mock import Mock
from packtrack import Correios
@@ -10,20 +12,20 @@ class CorreiosTest(unittest.TestCase):
def test_should_use_repository_to_get_encomenda(self):
encomenda_repository_mock = Mock()
- when(encomenda_repository_mock).get('123', auth=None) \
- .thenReturn('encomenda123')
+ encomenda_repository_mock.get.return_value = "encomenda123"
Correios._backends[None] = encomenda_repository_mock
assert Correios.track('123') == 'encomenda123'
+ encomenda_repository_mock.get.assert_called_with("123", auth=None)
def test_service_should_receive_auth(self):
auth = ('mi', 'mimi')
encomenda_repository_mock = Mock()
- when(encomenda_repository_mock).get('123', auth=auth) \
- .thenReturn('encomenda123')
+ encomenda_repository_mock.get.return_value = "encomenda123"
Correios._backends['service'] = encomenda_repository_mock
assert Correios.track(
'123', backend='service', auth=auth) == 'encomenda123'
+ encomenda_repository_mock.get.assert_called_with("123", auth=auth)
diff --git a/tests/correios_test.py b/tests/correios_test.py
index d24712e..06b8abe 100644
--- a/tests/correios_test.py
+++ b/tests/correios_test.py
@@ -1,7 +1,9 @@
import unittest
-from mock import Mock
-from mockito import *
+try:
+ from unittest.mock import Mock
+except ImportError:
+ from mock import Mock
from packtrack.correios import Encomenda, Status, EncomendaRepository
@@ -11,8 +13,8 @@ def test_should_get_encomenda_by_numero(self):
encomenda_123 = Status(data='2009-01-28 17:49:00')
correios_website_scraper_mock = Mock()
- when(correios_website_scraper_mock).get_encomenda_info('123', auth=None).thenReturn(encomenda_123)
-
+ correios_website_scraper_mock.get_encomenda_info.return_value = encomenda_123
+
repository = EncomendaRepository()
repository.correios_website_scraper = correios_website_scraper_mock
encomenda = repository.get('123')
diff --git a/tests/scraping_test.py b/tests/scraping_test.py
index 547c605..7aff6f3 100644
--- a/tests/scraping_test.py
+++ b/tests/scraping_test.py
@@ -2,7 +2,10 @@
import os
import unittest
-import mock
+try:
+ from unittest import mock
+except ImportError:
+ import mock
from packtrack.scraping import CorreiosWebsiteScraper
from packtrack.dhl_gm import DhlGmTracker
@@ -17,9 +20,9 @@ def _assert_status(self, status, data, local, situacao, detalhes):
self.assertEqual(detalhes, status.detalhes)
def test_should_get_data_from_correios_website(self):
- example_file = open('%s/tests/correios_website/exemplo_rastreamento_correios1.html' % os.getcwd())
- sample_html = example_file.read()
- example_file.close()
+ filename = '%s/tests/correios_website/exemplo_rastreamento_correios1.html' % os.getcwd()
+ with open(filename, "rb") as f:
+ sample_html = f.read()
http_client_mock = mock.Mock()
response_mock = mock.Mock()