@@ -109,7 +109,7 @@ class Cache(object):
109
109
"print_page" : "seek/cdpf.aspx" ,
110
110
}
111
111
112
- def __init__ (self , geocaching , wp , ** kwargs ):
112
+ def __init__ (self , geocaching , wp = None , ** kwargs ):
113
113
"""Create a cache instance.
114
114
115
115
:param .Geocaching geocaching: Reference to :class:`.Geocaching` instance, used for loading
@@ -125,8 +125,8 @@ def __init__(self, geocaching, wp, **kwargs):
125
125
126
126
known_kwargs = {"name" , "type" , "location" , "original_location" , "state" , "found" , "size" ,
127
127
"difficulty" , "terrain" , "author" , "hidden" , "attributes" , "summary" ,
128
- "description" , "hint" , "favorites" , "pm_only" , "url" , " waypoints" , "_logbook_token " ,
129
- "_trackable_page_url " , "guid " }
128
+ "description" , "hint" , "favorites" , "pm_only" , "waypoints" , "guid " ,
129
+ "_logbook_token " , "_trackable_page_url " }
130
130
131
131
for name in known_kwargs :
132
132
if name in kwargs :
@@ -181,12 +181,13 @@ def wp(self, wp):
181
181
self ._wp = wp
182
182
183
183
@property
184
+ @lazy_loaded
184
185
def guid (self ):
185
186
"""The cache GUID. An identifier used at some places on geoaching.com
186
187
187
188
:type: :class:`str`
188
189
"""
189
- return getattr ( self , " _guid" , None )
190
+ return self . _guid
190
191
191
192
@guid .setter
192
193
def guid (self , guid ):
@@ -532,32 +533,47 @@ def _trackable_page_url(self, trackable_page_url):
532
533
self .__trackable_page_url = trackable_page_url
533
534
534
535
def load (self ):
535
- """Load all possible cache details.
536
+ """Load cache details.
537
+
538
+ .. note::
539
+ This method is called automatically when you access a property which isn't yet filled in
540
+ (so-called "lazy loading"). You don't have to call it explicitly.
536
541
537
- Use full cache details page. Therefore all possible properties are filled in, but the
542
+ This method picks the loading method based on the available cache ID:
543
+
544
+ + If a GUID is known, it uses :meth:`.Cache.load_print`.
545
+ + Else if a WP is known, it uses :meth:`.Cache.load_normal`.
546
+ + Else, it throws a :class:`.LoadError`.
547
+
548
+ For details on different loading methods, please see their documentation. Feel free not to
549
+ call this method, but please use directly that one, which better suits your needs.
550
+
551
+ :raise .PMOnlyException: If cache is PM only and current user is basic member.
552
+ :raise .LoadError: If cache cannot be loaded.
553
+ """
554
+ if hasattr (self , "_guid" ):
555
+ return self .load_print ()
556
+ elif hasattr (self , "_wp" ):
557
+ return self .load_normal ()
558
+ else :
559
+ raise errors .LoadError ("Cache lacks info for loading" )
560
+
561
+ def load_normal (self ):
562
+ """Load all cache details.
563
+
564
+ It uses a full cache details page. Therefore all possible properties are filled in, but the
538
565
loading is a bit slow.
539
566
540
567
If you want to load basic details about a PM only cache, the :class:`.PMOnlyException` is
541
- still thrown, but avaliable details are filled in. If you know, that the cache you are
568
+ thrown, but all available details are filled in. If you know, that the cache you are
542
569
loading is PM only, please consider using :meth:`load_quick` as it will load the same
543
- details, but quicker.
544
-
545
- .. note::
546
- This method is called automatically when you access a property which isn't yet filled in
547
- (so-called "lazy loading"). You don't have to call it explicitly.
570
+ details, but faster.
548
571
549
572
:raise .PMOnlyException: If cache is PM only and current user is basic member.
550
573
:raise .LoadError: If cache loading fails (probably because of not existing cache).
551
574
"""
552
575
try :
553
- # pick url based on what info we have right now
554
- if hasattr (self , "url" ):
555
- root = self .geocaching ._request (self .url )
556
- elif hasattr (self , "_wp" ):
557
- root = self .geocaching ._request (self ._urls ["cache_details" ],
558
- params = {"wp" : self ._wp })
559
- else :
560
- raise errors .LoadError ("Cache lacks info for loading" )
576
+ root = self .geocaching ._request (self ._urls ["cache_details" ], params = {"wp" : self ._wp })
561
577
except errors .Error as e :
562
578
# probably 404 during cache loading - cache not exists
563
579
raise errors .LoadError ("Error in loading cache" ) from e
@@ -567,7 +583,7 @@ def load(self):
567
583
568
584
cache_details = root .find (id = "ctl00_divContentMain" ) if self .pm_only else root .find (id = "cacheDetails" )
569
585
570
- # details also avaliable for basic members for PM only caches -----------------------------
586
+ # details also available for basic members for PM only caches -----------------------------
571
587
572
588
if self .pm_only :
573
589
self .wp = cache_details .find ("li" , "li__gccode" ).text .strip ()
@@ -587,6 +603,7 @@ def load(self):
587
603
self .size = Size .from_string (details [8 ])
588
604
589
605
self .favorites = int (details [11 ])
606
+
590
607
else :
591
608
# parse from <title> - get first word
592
609
try :
@@ -668,27 +685,41 @@ def load(self):
668
685
else :
669
686
self ._trackable_page_url = None
670
687
671
- # Additional Waypoints
688
+ # additional Waypoints
672
689
self .waypoints = Waypoint .from_html (root , "ctl00_ContentBody_Waypoints" )
673
690
674
- logging .debug ("Cache loaded: {}" .format (self ))
691
+ logging .debug ("Cache loaded (normal) : {}" .format (self ))
675
692
676
693
def load_quick (self ):
677
694
"""Load basic cache details.
678
695
679
- Use information from geocaching map tooltips. Therefore loading is very quick, but
680
- the only loaded properties are: `name`, `type`, `state`, `size`, `difficulty`, `terrain`,
681
- `hidden`, `author`, `favorites` and `pm_only`.
696
+ Uses a data from geocaching map tooltips. Therefore loading is very quick, but the only
697
+ loaded properties are:
698
+
699
+ + `name`
700
+ + `type`
701
+ + `state`
702
+ + `size`
703
+ + `difficulty`
704
+ + `terrain`
705
+ + `hidden`
706
+ + `author`
707
+ + `favorites`
708
+ + `pm_only`
682
709
683
710
:raise .LoadError: If cache loading fails (probably because of not existing cache).
684
711
"""
685
- res = self .geocaching ._request (self ._urls ["tiles_server" ],
686
- params = {"i" : self .wp },
687
- expect = "json" )
712
+ try :
713
+ res = self .geocaching ._request (self ._urls ["tiles_server" ],
714
+ params = {"i" : self ._wp },
715
+ expect = "json" )
716
+
717
+ if res ["status" ] == "failed" or len (res ["data" ]) != 1 :
718
+ msg = res ["msg" ] if "msg" in res else "Unknown error (probably not existing cache)"
719
+ raise errors .LoadError (msg )
688
720
689
- if res ["status" ] == "failed" or len (res ["data" ]) != 1 :
690
- msg = res ["msg" ] if "msg" in res else "Unknown error (probably not existing cache)"
691
- raise errors .LoadError ("Cache {} cannot be loaded: {}" .format (self , msg ))
721
+ except errors .Error as e :
722
+ raise errors .LoadError ("Error in loading cache" ) from e
692
723
693
724
data = res ["data" ][0 ]
694
725
@@ -705,37 +736,49 @@ def load_quick(self):
705
736
self .pm_only = data ["subrOnly" ]
706
737
self .guid = res ["data" ][0 ]["g" ]
707
738
708
- logging .debug ("Cache loaded: {}" .format (self ))
739
+ logging .debug ("Cache loaded (quick) : {}" .format (self ))
709
740
710
- def load_by_guid (self ):
711
- """Load cache details using the GUID to request and parse the caches
712
- 'print-page'. Loading as many properties as possible except the
713
- following ones, since they are not present on the 'print-page':
741
+ def load_print (self ):
742
+ """Load most of the cache details.
714
743
715
- + original_location
716
- + state
717
- + found
718
- + pm_only
744
+ Uses a cache print page. This is significantly faster, but requires a GUID to be set. If
745
+ the GUID is missing, it calls :meth:`.Cache.load_quick` to get it by a WP, which is both
746
+ still faster than :meth:`.Cache.load_normal`!
719
747
720
- :raise .PMOnlyException: If the PM only warning is shown on the page
748
+ However, not all properties are presented on the print page, so the following ones are not
749
+ loaded:
750
+
751
+ + `original_location`
752
+ + `state`
753
+ + `found`
754
+ + `pm_only`
755
+
756
+ Also, in comparison to :meth:`.Cache.load_normal` – if the cache is PM-only, this method
757
+ doesn't load anything.
758
+
759
+ :raise .PMOnlyException: If the cache is PM only.
760
+ :raise .LoadError: If cache loading fails (probably because of not existing cache).
721
761
"""
722
- # If GUID has not yet been set, load it using the "tiles_server"
723
- # utilizing `load_quick()`
724
- if not self . guid :
762
+ # if GUID has not yet been set, load it using the `load_quick()`
763
+ # the getattr() will prevent lazy-loading of GUID
764
+ if not getattr ( self , "_guid" , None ) :
725
765
self .load_quick ()
726
766
727
- res = self .geocaching ._request (self ._urls ["print_page" ],
728
- params = {"guid" : self .guid })
767
+ try :
768
+ res = self .geocaching ._request (self ._urls ["print_page" ], params = {"guid" : self ._guid })
769
+ except errors .Error as e :
770
+ raise errors .LoadError ("Error in loading cache" ) from e
771
+
729
772
if res .find ("p" , "Warning" ) is not None :
730
773
raise errors .PMOnlyException ()
774
+
775
+ self .wp = res .find (id = "Header" ).find_all ("h1" )[- 1 ].text
776
+
731
777
content = res .find (id = "Content" )
732
778
733
779
self .name = content .find ("h2" ).text
734
780
735
- self .wp = res .find (id = "Header" ).find_all ("h1" )[- 1 ].text
736
-
737
- self .location = Point .from_string (
738
- content .find ("p" , "LatLong Meta" ).text )
781
+ self .location = Point .from_string (content .find ("p" , "LatLong Meta" ).text )
739
782
740
783
type_img = os .path .basename (content .find ("img" ).get ("src" ))
741
784
self .type = Type .from_filename (os .path .splitext (type_img )[0 ])
@@ -764,11 +807,9 @@ def load_by_guid(self):
764
807
in attributes_raw if not appendix .startswith ("blank" )
765
808
}
766
809
767
- self .summary = content .find (
768
- "h2" , text = "Short Description" ).find_next ("div" ).text
810
+ self .summary = content .find ("h2" , text = "Short Description" ).find_next ("div" ).text
769
811
770
- self .description = content .find (
771
- "h2" , text = "Long Description" ).find_next ("div" ).text
812
+ self .description = content .find ("h2" , text = "Long Description" ).find_next ("div" ).text
772
813
773
814
self .hint = content .find (id = "uxEncryptedHint" ).text
774
815
@@ -777,6 +818,8 @@ def load_by_guid(self):
777
818
778
819
self .waypoints = Waypoint .from_html (content , "Waypoints" )
779
820
821
+ logging .debug ("Cache loaded (print): {}" .format (self ))
822
+
780
823
def _logbook_get_page (self , page = 0 , per_page = 25 ):
781
824
"""Load one page from logbook.
782
825
0 commit comments