Skip to content

Commit 83e61f8

Browse files
committed
Added support for new item filters
1 parent f7e3ff6 commit 83e61f8

File tree

7 files changed

+101
-58
lines changed

7 files changed

+101
-58
lines changed

CHANGELOG.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,28 @@ Changelog
66
Due to this library relying on external content, older versions are not guaranteed to work.
77
Try to always use the latest version.
88

9+
3.5.0 (2020-09-22)
10+
==================
11+
12+
- Added support for the new filtering options added to current auctions:
13+
- Added new enumeration: ``AuctionSearchType``
14+
- Renamed ``AuctionFilters`` attribute ``item`` to ``search_string``.
15+
Property alias kept for backwards compatibility.
16+
- Added new attribute ``AuctionFilters.search_type``
17+
918
3.4.0 (2020-09-19)
10-
=================
19+
==================
1120

1221
- Added option to only parse the listed information of an auction, to skip the rest of the parsing.
1322
- Fixed wrong type hint in ``ListedAuction`` for ``status``.
1423

1524
3.3.0 (2020-09-09)
16-
=================
25+
==================
1726

1827
- Added support for the Character Bazaar
1928
- Added classes: ``CharacterBazaar``, ``ListedAuction`` and ``AuctionDetails`` and many auxiliary classes.
2029
- Client methods throw a ``SiteMaintenanceError`` when Tibia.com is under maintenance, to be able to tell apart from
21-
other network errors.
30+
other network errors.
2231

2332
.. v3.2.2:
2433

docs/api.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Enumerations are provided for various values in order to avoid depending on stri
3333
:members:
3434
:undoc-members:
3535

36+
.. autoclass:: AuctionSearchType
37+
:members:
38+
:undoc-members:
39+
3640
.. autoclass:: AuctionStatus
3741
:members:
3842
:undoc-members:

tests/resources/bazaar/tibiacom_current_all_filters.txt

Lines changed: 13 additions & 6 deletions
Large diffs are not rendered by default.

tests/tests_bazaar.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import unittest
33

44
from tests.tests_tibiapy import TestCommons
5-
from tibiapy import AuctionDetails, AuctionOrder, AuctionOrderBy, AuctionStatus, BattlEyeTypeFilter, BidType, \
5+
from tibiapy import AuctionDetails, AuctionOrder, AuctionOrderBy, AuctionSearchType, AuctionStatus, BattlEyeTypeFilter, \
6+
BidType, \
67
CharacterBazaar, \
78
InvalidContent, PvpTypeFilter, \
89
Sex, SkillFilter, \
@@ -51,23 +52,16 @@ def test_character_bazaar_from_content_current_all_filters_selected(self):
5152

5253
self.assertIsNotNone(bazaar)
5354
self.assertEqual(1, bazaar.page)
54-
self.assertEqual(1, bazaar.total_pages)
55-
self.assertEqual(9, bazaar.results_count)
56-
self.assertEqual(9, len(bazaar.entries))
55+
self.assertEqual(4, bazaar.total_pages)
56+
self.assertEqual(92, bazaar.results_count)
57+
self.assertEqual(25, len(bazaar.entries))
5758
self.assertIsNotNone(bazaar.url)
5859

5960
auction = bazaar.entries[0]
60-
self.assertEqual(36169, auction.auction_id)
61-
self.assertEqual(2600, auction.bid)
61+
self.assertEqual(82526, auction.auction_id)
62+
self.assertEqual(57000, auction.bid)
6263
self.assertEqual(BidType.MINIMUM, auction.bid_type)
6364
self.assertIsNotNone(auction.character_url)
64-
self.assertEqual(4, len(auction.displayed_items))
65-
66-
first_item = auction.displayed_items[0]
67-
self.assertEqual(1, first_item.count)
68-
self.assertEqual(9394, first_item.item_id)
69-
self.assertEqual("claw of 'The Noxious Spawn'", first_item.name)
70-
self.assertIsNotNone(first_item.image_url)
7165

7266
self.assertIsNotNone(bazaar.filters)
7367
self.assertEqual('Antica', bazaar.filters.world)
@@ -78,10 +72,11 @@ def test_character_bazaar_from_content_current_all_filters_selected(self):
7872
self.assertEqual(1000, bazaar.filters.max_level)
7973
self.assertEqual(SkillFilter.MAGIC_LEVEL, bazaar.filters.skill)
8074
self.assertEqual(1, bazaar.filters.min_skill_level)
81-
self.assertEqual(10, bazaar.filters.max_skill_level)
82-
self.assertEqual(AuctionOrderBy.MAGIC_LEVEL, bazaar.filters.order_by)
75+
self.assertEqual(50, bazaar.filters.max_skill_level)
76+
self.assertEqual(AuctionOrderBy.SHIELDING, bazaar.filters.order_by)
8377
self.assertEqual(AuctionOrder.HIGHEST_LATEST, bazaar.filters.order)
84-
self.assertEqual("destruction", bazaar.filters.item)
78+
self.assertEqual("potion", bazaar.filters.item)
79+
self.assertEqual(AuctionSearchType.ITEM_WILDCARD, bazaar.filters.search_type)
8580

8681
def test_character_bazaar_from_content_empty(self):
8782
bazaar = CharacterBazaar.from_content(self.load_resource(FILE_BAZAAR_CURRENT_EMPTY))

tibiapy/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
__version__ = '3.5.0'
2+
__author__ = 'Allan Galarza'
3+
14
import logging
25

36
from tibiapy import abc, enums, utils
@@ -17,8 +20,6 @@
1720
from tibiapy.bazaar import *
1821
from tibiapy.client import *
1922

20-
__version__ = '3.4.0'
21-
2223
from logging import NullHandler
2324

2425
logging.getLogger(__name__).addHandler(NullHandler())

tibiapy/bazaar.py

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import datetime
22
import re
33
import urllib.parse
4-
from abc import abstractmethod
5-
6-
from typing import Dict, List, Optional, Type
4+
import warnings
5+
from typing import Dict, List, Optional
76

87
import bs4
98

109
from tibiapy import abc, InvalidContent, Sex, Vocation
1110
from tibiapy.abc import BaseCharacter
12-
from tibiapy.enums import AuctionOrder, AuctionOrderBy, AuctionStatus, BattlEyeTypeFilter, BazaarType, BidType, \
11+
from tibiapy.enums import AuctionOrder, AuctionOrderBy, AuctionSearchType, AuctionStatus, BattlEyeTypeFilter, \
12+
BazaarType, BidType, \
1313
PvpTypeFilter, \
1414
SkillFilter, \
1515
VocationAuctionFilter
16-
from tibiapy.utils import convert_line_breaks, get_tibia_url, parse_integer, parse_pagination, parse_tibia_datetime, \
16+
from tibiapy.utils import convert_line_breaks, deprecated, get_tibia_url, parse_integer, parse_pagination, \
17+
parse_tibia_datetime, \
1718
parse_tibia_money, \
1819
parse_tibiacom_content, \
1920
try_enum
@@ -95,6 +96,10 @@ class AuctionFilters(abc.Serializable):
9596
The minimum skill level of the selected :attr:`skill` to display.
9697
max_skill_level: :class:`int`
9798
The maximum skill level of the selected :attr:`skill` to display.
99+
search_string: :class:`str`
100+
The search term to filter out auctions.
101+
search_type: :class:`AuctionSearchType`
102+
The type of search to use. Defines the behaviour of :py:attr:`search_string`.
98103
"""
99104
__slots__ = (
100105
"world",
@@ -108,7 +113,8 @@ class AuctionFilters(abc.Serializable):
108113
"max_skill_level",
109114
"order_by",
110115
"order",
111-
"item",
116+
"search_string",
117+
"search_type",
112118
)
113119

114120
def __init__(self, **kwargs):
@@ -123,7 +129,8 @@ def __init__(self, **kwargs):
123129
self.max_skill_level: Optional[int] = kwargs.get("max_skill_level")
124130
self.order_by: Optional[AuctionOrderBy] = kwargs.get("order_by")
125131
self.order: Optional[AuctionOrder] = kwargs.get("order")
126-
self.item: Optional[str] = kwargs.get("item")
132+
self.search_string: Optional[str] = kwargs.get("search_string")
133+
self.search_type: Optional[AuctionSearchType] = kwargs.get("search_type")
127134

128135
def __repr__(self):
129136
attributes = ""
@@ -132,6 +139,21 @@ def __repr__(self):
132139
attributes += " %s=%r" % (attr, v)
133140
return "<{0.__class__.__name__}{1}>".format(self, attributes)
134141

142+
@property
143+
def item(self):
144+
""":class:`str`: The name of the item to search for.
145+
146+
.. deprecated:: 3.5.0
147+
Use :py:attr:`search_string` instead.
148+
"""
149+
warnings.warn("Deprecated, use 'search_string'instead", DeprecationWarning)
150+
return self.search_string
151+
152+
@item.setter
153+
@deprecated(instead="search_string")
154+
def item(self, value):
155+
self.search_string = value
156+
135157
@property
136158
def query_params(self):
137159
""":class:`str`: The query parameters representing this filter."""
@@ -147,7 +169,8 @@ def query_params(self):
147169
"filter_skillrangeto": self.max_skill_level,
148170
"order_column": self.order_by.value if self.order_by else None,
149171
"order_direction": self.order.value if self.order else None,
150-
"itemname": self.item,
172+
"searchstring": self.search_string,
173+
"searchtype": self.search_type.value if self.search_type else None,
151174
}
152175
return {k: v for k, v in params.items() if v}
153176

@@ -167,30 +190,22 @@ def _parse_filter_table(cls, table):
167190
filters = AuctionFilters()
168191
world_select = table.find("select", {"name": "filter_world"})
169192
selected_world_option = world_select.find("option", {"selected": True})
170-
if selected_world_option is None or not selected_world_option["value"]:
171-
filters.world = None
172-
else:
193+
if selected_world_option is not None and selected_world_option["value"]:
173194
filters.world = selected_world_option["value"]
174195

175196
pvp_select = table.find("select", {"name": "filter_worldpvptype"})
176197
selected_pvp_option = pvp_select.find("option", {"selected": True})
177-
if selected_pvp_option is None or not selected_pvp_option["value"]:
178-
filters.pvp_type = None
179-
else:
198+
if selected_pvp_option is not None and selected_pvp_option["value"]:
180199
filters.pvp_type = try_enum(PvpTypeFilter, parse_integer(selected_pvp_option["value"], None))
181200

182201
battleye_select = table.find("select", {"name": "filter_worldbattleyestate"})
183202
selected_battleye_option = battleye_select.find("option", {"selected": True})
184-
if selected_battleye_option is None or not selected_battleye_option["value"]:
185-
filters.battleye = None
186-
else:
203+
if selected_battleye_option is not None and selected_battleye_option["value"]:
187204
filters.battleye = try_enum(BattlEyeTypeFilter, parse_integer(selected_battleye_option["value"], None))
188205

189206
vocation_select = table.find("select", {"name": "filter_profession"})
190207
selected_vocation_option = vocation_select.find("option", {"selected": True})
191-
if selected_vocation_option is None or not selected_vocation_option["value"]:
192-
filters.vocation = None
193-
else:
208+
if selected_vocation_option is not None and selected_vocation_option["value"]:
194209
filters.vocation = try_enum(VocationAuctionFilter, parse_integer(selected_vocation_option["value"], None))
195210

196211
minlevel_input = table.find("input", {"name": "filter_levelrangefrom"})
@@ -200,9 +215,7 @@ def _parse_filter_table(cls, table):
200215

201216
skill_select = table.find("select", {"name": "filter_skillid"})
202217
selected_skill_option = skill_select.find("option", {"selected": True})
203-
if selected_skill_option is None or not selected_skill_option["value"]:
204-
filters.skill = None
205-
else:
218+
if selected_skill_option is not None and selected_skill_option["value"]:
206219
filters.skill = try_enum(SkillFilter, parse_integer(selected_skill_option["value"], None))
207220
min_skill_level_input = table.find("input", {"name": "filter_skillrangefrom"})
208221
max_skill_level_input = table.find("input", {"name": "filter_skillrangeto"})
@@ -211,20 +224,23 @@ def _parse_filter_table(cls, table):
211224

212225
order_by_select = table.find("select", {"name": "order_column"})
213226
selected_order_by_option = order_by_select.find("option", {"selected": True})
214-
if selected_order_by_option is None or not selected_order_by_option["value"]:
215-
filters.order_by = None
216-
else:
227+
if selected_order_by_option is not None and selected_order_by_option["value"]:
217228
filters.order_by = try_enum(AuctionOrderBy, parse_integer(selected_order_by_option["value"], None))
218229

219230
order_select = table.find("select", {"name": "order_direction"})
220231
selected_order_option = order_select.find("option", {"selected": True})
221-
if selected_order_option is None or not selected_order_option["value"]:
222-
filters.order = None
223-
else:
232+
if selected_order_option is not None and selected_order_option["value"]:
224233
filters.order = try_enum(AuctionOrder, parse_integer(selected_order_option["value"], None))
225234

226-
name_input = table.find("input", {"name": "itemname"})
227-
filters.item = name_input["value"] or None
235+
search_string_input = table.find("input", {"name": "searchstring"})
236+
if search_string_input is not None and search_string_input["value"]:
237+
filters.search_string = search_string_input["value"] or None
238+
239+
search_type_input = table.find("input", {"name": "searchtype", "checked": "checked"})
240+
241+
if search_type_input is not None and search_type_input["value"]:
242+
filters.search_type = try_enum(AuctionSearchType, parse_integer(search_type_input["value"], None))
243+
228244
return filters
229245

230246

tibiapy/enums.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
'AuctionOrder',
66
'AuctionOrderBy',
77
'AuctionStatus',
8+
'AuctionSearchType',
89
'Category',
910
'BattlEyeTypeFilter',
1011
'BazaarType',
@@ -78,6 +79,16 @@ class AuctionOrderBy(NumericEnum):
7879
SWORD_FIGHTING = 8
7980

8081

82+
class AuctionSearchType(NumericEnum):
83+
"""The possible search types."""
84+
ITEM_DEFAULT = 0
85+
"""Searches everything that includes the words on the search string."""
86+
ITEM_WILDCARD = 1
87+
"""Searches everything that includes the search string"""
88+
CHARACTER_NAME = 2
89+
"""Searches a character's name."""
90+
91+
8192
class AuctionStatus(BaseEnum):
8293
"""The possible values an auction might have."""
8394
IN_PROGRESS = 'in progress'

0 commit comments

Comments
 (0)