Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Cache.status property #193

Merged
merged 19 commits into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 43 additions & 12 deletions pycaching/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from pycaching.log import Log
from pycaching.log import Type as LogType
from pycaching.trackable import Trackable
from pycaching.util import lazy_loaded, parse_date, rot13
from pycaching.util import deprecated, lazy_loaded, parse_date, rot13

# prefix _type() function to avoid collisions with cache type
_type = type
Expand Down Expand Up @@ -145,7 +145,6 @@ def _from_print_page(cls, geocaching, guid, soup):
content.find(class_="HalfRight AlignRight").p.text.strip().partition(":")[2].strip()
)
cache_info["location"] = Point.from_string(content.find(class_="LatLong").text.strip())
cache_info["state"] = None # not on the page
attributes = [
img["src"].split("/")[-1].partition(".")[0].rpartition("-")
for img in content.find(class_="sortables").find_all("img")
Expand All @@ -170,7 +169,7 @@ def _from_api_record(cls, geocaching, record):
wp=record["code"],
name=record["name"],
type=Type.from_number(record["geocacheType"]),
state=Status(record["cacheStatus"]) == Status.enabled,
status=Status(record["cacheStatus"]),
found=record["userFound"],
size=Size.from_number(record["containerType"]),
difficulty=record["difficulty"],
Expand Down Expand Up @@ -213,7 +212,7 @@ def __init__(self, geocaching, wp, **kwargs):
"type",
"location",
"original_location",
"state",
"status",
"found",
"size",
"difficulty",
Expand Down Expand Up @@ -405,18 +404,31 @@ def type(self, type):

@property
@lazy_loaded
@deprecated
def state(self):
"""The cache status.

:code:`True` if cache is enabled, :code:`False` if cache is disabled.
:code:`True` if cache is enabled, otherwise :code:`False`.

:type: :class:`bool`
"""
return self._state
return self._status == Status.enabled

@state.setter
def state(self, state):
self._state = bool(state)
@property
@lazy_loaded
def status(self):
"""The cache status (Enabled, Disabled, Archived, Unpublished, Locked).

:type: :class:`.cache.Status`
"""
return self._status

@status.setter
def status(self, status):
if isinstance(status, Status):
self._status = status
else:
raise errors.ValueError("Passed object is not Status instance.")

@property
@lazy_loaded
Expand Down Expand Up @@ -780,7 +792,17 @@ def load(self):

self.location = Point.from_string(root.find(id="uxLatLon").text)

self.state = root.find("ul", "OldWarning") is None
# Cache status
BelKed marked this conversation as resolved.
Show resolved Hide resolved
if root.find(id="ctl00_ContentBody_disabledMessage"):
self.status = Status.disabled
elif root.find(id="ctl00_ContentBody_archivedMessage"):
self.status = Status.archived
elif root.find(id="unpublishedMessage") or root.find(id="unpublishedReviewerNoteMessage"):
self.status = Status.unpublished
elif root.find(id="ctl00_ContentBody_lockedMessage"):
self.status = Status.locked
else:
self.status = Status.enabled

log_image = root.find(id="ctl00_ContentBody_GeoNav_logTypeImage")
if log_image:
Expand Down Expand Up @@ -837,8 +859,11 @@ def load_quick(self):
"""Load basic cache details.

Use information from geocaching map tooltips. Therefore loading is very quick, but
the only loaded properties are: `name`, `type`, `state`, `size`, `difficulty`, `terrain`,
the only loaded properties are: `name`, `type`, `size`, `difficulty`, `terrain`,
`hidden`, `author`, `favorites` and `pm_only`.
It also loads `status`, but only for enabled caches. For other states, it can't be
completely determined (can't distinguish between archived and locked caches), so
lazy loading is used.

:raise .LoadError: If cache loading fails (probably because of not existing cache).
"""
Expand All @@ -853,7 +878,12 @@ def load_quick(self):
# prettify data
self.name = data["name"]
self.type = Type.from_string(data["type"]["text"])
self.state = data["available"]

# We can fill in status correctly only for enabled caches
BelKed marked this conversation as resolved.
Show resolved Hide resolved
# (locked caches are considered archived)
if data["available"]:
self.status = Status.enabled

self.size = Size.from_string(data["container"]["text"])
self.difficulty = data["difficulty"]["text"]
self.terrain = data["terrain"]["text"]
Expand Down Expand Up @@ -1412,3 +1442,4 @@ class Status(enum.IntEnum):
disabled = 1
archived = 2
unpublished = 3
locked = 4
5 changes: 3 additions & 2 deletions pycaching/geocaching.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import requests
from bs4.element import Script

from pycaching.cache import Cache, Size
from pycaching.cache import Cache, Size, Status
from pycaching.errors import Error, LoginFailedException, NotLoggedInException, PMOnlyException, TooManyRequestsError
from pycaching.geo import Point, Rectangle
from pycaching.log import Log
Expand Down Expand Up @@ -289,7 +289,8 @@ def search(self, point, limit=float("inf")):
badge = row.find("svg", class_="badge")
c.found = "found" in str(badge) if badge is not None else False
c.favorites = row.find(attrs={"data-column": "FavoritePoint"}).text
c.state = not (row.get("class") and "disabled" in row.get("class"))
if not (row.get("class") and "disabled" in row.get("class")):
BelKed marked this conversation as resolved.
Show resolved Hide resolved
c.status = Status.enabled
c.pm_only = row.find("td", "pm-upsell") is not None

if c.pm_only:
Expand Down
10 changes: 8 additions & 2 deletions test/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from datetime import date
from unittest import mock

from pycaching.cache import Cache, Size, Type, Waypoint
from pycaching.cache import Cache, Size, Status, Type, Waypoint
from pycaching.errors import LoadError, PMOnlyException
from pycaching.errors import ValueError as PycachingValueError
from pycaching.geo import Point
Expand All @@ -24,7 +24,7 @@ def setUp(self):
name="Testing",
type=Type.traditional,
location=Point(),
state=True,
status=Status.enabled,
found=False,
size=Size.micro,
difficulty=1.5,
Expand Down Expand Up @@ -115,6 +115,12 @@ def test_waypoints(self):
def test_state(self):
self.assertEqual(self.c.state, True)

def test_status(self):
BelKed marked this conversation as resolved.
Show resolved Hide resolved
self.assertEqual(self.c.status, Status.enabled)

def test_status_name(self):
self.assertEqual(self.c.status.name, "enabled")

def test_found(self):
self.assertEqual(self.c.found, False)

Expand Down