Skip to content

Commit

Permalink
Python 3
Browse files Browse the repository at this point in the history
  • Loading branch information
iurisilvio committed Jan 11, 2021
1 parent 9f27ffc commit eb0f65a
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 77 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.pyc
*.coverage
.eggs
dist
build
packtrack.egg-info
Expand Down
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
language: python

before_install: pip install -r requirements.txt
before_install:
- python setup.py install
- pip install -r requirements-dev.txt

script: nosetests
script: nosetests
6 changes: 3 additions & 3 deletions packtrack/__init__.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down
5 changes: 2 additions & 3 deletions packtrack/correios.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand All @@ -34,10 +34,9 @@ def __init__(self, numero):
self.status = []

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 s: datetime.strptime(s.data, t_format))

def validar_data(self, data):
if re.match('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$', data):
Expand Down
45 changes: 16 additions & 29 deletions packtrack/scraping.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import os
import re
from HTMLParser import HTMLParser
from html import unescape

from BeautifulSoup import BeautifulSoup
from bs4 import BeautifulSoup
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 .correios import Encomenda, Status


class CorreiosWebsiteScraper(object):
Expand Down Expand Up @@ -46,49 +46,36 @@ def get_encomenda_info(self, numero):
except RequestException:
return None

html = response.content

html = response.text
if html:
try:
html = html.decode('latin-1')
except UnicodeDecodeError:
pass
encomenda = Encomenda(numero)
for status in self._get_all_status_from_html(html):
encomenda.adicionar_status(status)
return encomenda

def _text(self, value):
value = BeautifulSoup(value.strip()).text
return value.replace(' ', ' ')
text = BeautifulSoup(value.strip(), 'html.parser').text
return re.sub(r'[\s\t]+', ' ', text)

def _get_all_status_from_html(self, html):
status = []
html_parser = HTMLParser()
if "<table" not in html:
return status
html_info = re.search('.*(<table.*</table>).*', html, re.S)
if not html_info:
return status

table = html_info.group(1)
soup = BeautifulSoup(table)

for tr in soup.table:
# O bs4 converte o &nbsp; para \xa0 ao invés de espaço.
clean_html = html.replace('&nbsp;', ' ')
soup = BeautifulSoup(clean_html, 'html.parser')
for tr in soup.select('table.sro tr'):
try:
tds = tr.findAll('td')
except AttributeError:
continue
for td in tds:
content = td.renderContents().replace('\r', ' ') \
.split('<br />')
content = td.encode_contents().decode().replace('\r', ' ').split('<br/>')
class_ = td['class']
if class_ == 'sroDtEvent':
if 'sroDtEvent' in class_:
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]))
local = '/'.join(self._text(content[2]).rsplit(' / ', 1)).upper().rstrip('/')
elif 'sroLbEvent' in class_:
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,
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nose
8 changes: 0 additions & 8 deletions requirements.txt

This file was deleted.

7 changes: 3 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

setup(
name='packtrack',
version='1.6',
version='2.0',
packages=['packtrack'],
author='Ale Borba',
author_email='[email protected]',
Expand All @@ -13,9 +13,8 @@
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',
'requests',
'beautifulsoup4 >= 4.9.3',
'lxml >= 2.3.5',
'zeep >= 1.6.0',
],
Expand Down
18 changes: 7 additions & 11 deletions tests/correios_api_test.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
import unittest

from mock import Mock
from mockito import when
from unittest import TestCase
from unittest.mock import Mock

from packtrack import Correios


class CorreiosTest(unittest.TestCase):
class CorreiosTest(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)
12 changes: 6 additions & 6 deletions tests/correios_test.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import unittest

from mock import Mock
from mockito import *
from unittest.mock import Mock

from packtrack.correios import Encomenda, Status, EncomendaRepository


class EncomendaRepositoryTest(unittest.TestCase):

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')
assert encomenda
assert encomenda.data == '2009-01-28 17:49:00'
correios_website_scraper_mock.get_encomenda_info.assert_called_with('123', auth=None)

def test_select_default_backend(self):
repository = EncomendaRepository()
Expand Down
20 changes: 9 additions & 11 deletions tests/scraping_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# encoding: UTF-8
import os
import unittest

import mock
from unittest.mock import Mock

from packtrack.scraping import CorreiosWebsiteScraper
from packtrack.dhl_gm import DhlGmTracker
Expand All @@ -17,14 +16,13 @@ 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()
with open(f'{os.getcwd()}/tests/correios_website/exemplo_rastreamento_correios1.html', 'r', encoding='latin-1') as f:
sample_html = f.read()

http_client_mock = mock.Mock()
response_mock = mock.Mock()
http_client_mock = Mock()
response_mock = Mock()
http_client_mock.post.return_value = response_mock
response_mock.content = sample_html
response_mock.text = sample_html

correios_website_scraper = CorreiosWebsiteScraper(http_client_mock)
numero = 'PJ859656941BR'
Expand All @@ -47,10 +45,10 @@ class CorreiosTimeoutTest(unittest.TestCase):

def test_timeout_undefined(self):

http_client_mock = mock.Mock()
response_mock = mock.Mock()
http_client_mock = Mock()
response_mock = Mock()
http_client_mock.post.return_value = response_mock
response_mock.content = ''
response_mock.text = ''
TIMEOUT = 3
scraper = CorreiosWebsiteScraper(http_client_mock, timeout=TIMEOUT)
scraper.get_encomenda_info('ES446391025BR')
Expand Down

0 comments on commit eb0f65a

Please sign in to comment.