Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
SukiCZ committed Jun 23, 2024
2 parents 33fbb11 + 504f56c commit 4d0e341
Show file tree
Hide file tree
Showing 18 changed files with 1,096 additions and 33 deletions.
7 changes: 5 additions & 2 deletions boardgamegeek/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
BGGItemNotFoundError,
BGGValueError,
)
from .legacy_api import BGGClientLegacy

__all__ = [

__all__ = (
"BGGClient",
"BGGClientLegacy",
"BGGChoose",
"BGGRestrictSearchResultsTo",
"BGGRestrictPlaysTo",
Expand All @@ -40,6 +43,6 @@
"CacheBackendNone",
"CacheBackendSqlite",
"CacheBackendMemory",
]
)

__version__ = "1.1.6"
64 changes: 64 additions & 0 deletions boardgamegeek/legacy_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import logging

from .api import BGGCommon
from .api import CacheBackendMemory
from .api import DEFAULT_REQUESTS_PER_MINUTE
from .api import BGGValueError
from .api import request_and_parse_xml
from .loaders import create_geeklist_from_xml, add_geeklist_items_from_xml

log = logging.getLogger("boardgamegeek.legacy_api")

API_ENDPOINT = "https://www.boardgamegeek.com/xmlapi"


class BGGClientLegacy(BGGCommon):
def __init__(
self,
cache=CacheBackendMemory(ttl=3600),
timeout=15,
retries=3,
retry_delay=5,
disable_ssl=False,
requests_per_minute=DEFAULT_REQUESTS_PER_MINUTE,
):
super().__init__(
api_endpoint=API_ENDPOINT,
cache=cache,
timeout=timeout,
retries=retries,
retry_delay=retry_delay,
requests_per_minute=requests_per_minute,
)
self._search_api_url = None
self._thing_api_url = None
self._guild_api_url = None
self._user_api_url = None
self._plays_api_url = None
self._hot_api_url = None
self._collection_api_url = None
self._geeklist_api_url = API_ENDPOINT + "/geeklist"

def geeklist(self, listid, comments=False):
# Parameter validation
if not listid:
raise BGGValueError("List Id must be specified")
log.debug(f"retrieving list {listid}")

params = {}
if comments:
params["comments"] = 1
url = f"{self._geeklist_api_url}/{listid}"
xml_root = request_and_parse_xml(
self.requests_session,
url,
params=params,
timeout=self._timeout,
retries=self._retries,
retry_delay=self._retry_delay,
)

lst = create_geeklist_from_xml(xml_root, listid)
add_geeklist_items_from_xml(lst, xml_root)

return lst
27 changes: 15 additions & 12 deletions boardgamegeek/loaders/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
from .collection import add_collection_items_from_xml, create_collection_from_xml
from .game import add_game_comments_from_xml, create_game_from_xml
from .geeklist import add_geeklist_items_from_xml, create_geeklist_from_xml
from .guild import add_guild_members_from_xml, create_guild_from_xml
from .hotitems import add_hot_items_from_xml, create_hot_items_from_xml
from .plays import add_plays_from_xml, create_plays_from_xml

__all__ = [
create_collection_from_xml,
create_guild_from_xml,
create_hot_items_from_xml,
create_plays_from_xml,
create_game_from_xml,
add_collection_items_from_xml,
add_guild_members_from_xml,
add_hot_items_from_xml,
add_plays_from_xml,
add_game_comments_from_xml,
]
__all__ = (
"add_collection_items_from_xml",
"add_game_comments_from_xml",
"add_geeklist_items_from_xml",
"add_guild_members_from_xml",
"add_hot_items_from_xml",
"add_plays_from_xml",
"create_collection_from_xml",
"create_game_from_xml",
"create_geeklist_from_xml",
"create_guild_from_xml",
"create_hot_items_from_xml",
"create_plays_from_xml",
)
67 changes: 67 additions & 0 deletions boardgamegeek/loaders/geeklist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import datetime

from ..utils import xml_subelement_text
from ..objects.geeklist import GeekList


def parse_date(str_date):
return datetime.datetime.strptime(str_date, "%a, %d %b %Y %H:%M:%S %z")


def add_geeklist_comments_from_xml(geeklist_or_item, xml_root):
added_comments = False
for comment in xml_root.findall("comment"):
# initial data for this collection item
data = {
"username": comment.attrib["username"],
"date": parse_date(comment.attrib["date"]) or None,
"postdate": parse_date(comment.attrib["postdate"]) or None,
"editdate": parse_date(comment.attrib["editdate"]) or None,
"thumbs": int(comment.attrib["thumbs"]),
"text": comment.text.strip(),
}
geeklist_or_item.add_comment(data)
added_comments = True
return added_comments


def create_geeklist_from_xml(xml_root, listid):
data = {
"id": listid,
"name": xml_subelement_text(xml_root, "title"), # need a name for a thing!
"postdate": xml_subelement_text(xml_root, "postdate", parse_date, quiet=True),
"editdate": xml_subelement_text(xml_root, "editdate", parse_date, quiet=True),
"thumbs": xml_subelement_text(xml_root, "thumbs", int),
"numitems": xml_subelement_text(xml_root, "numitems", int),
"username": xml_subelement_text(xml_root, "username"),
"description": xml_subelement_text(xml_root, "description"),
}
geeklist = GeekList(data)
add_geeklist_comments_from_xml(geeklist, xml_root)
return geeklist


def add_geeklist_items_from_xml(geeklist, xml_root):
added_items = False
for item in xml_root.findall("item"):
# initial data for this geeklist item
data = {
"id": item.attrib["id"],
"username": item.attrib["username"],
"postdate": parse_date(item.attrib["postdate"]) or None,
"editdate": parse_date(item.attrib["editdate"]) or None,
"thumbs": int(item.attrib["thumbs"]),
"body": xml_subelement_text(item, "body"),
}
listitem = geeklist.add_item(data)
object_data = {
"id": item.attrib["objectid"],
"name": item.attrib["objectname"],
"imageid": item.attrib["imageid"],
"type": item.attrib["objecttype"],
"subtype": item.attrib["subtype"],
}
listitem.set_object(object_data)
add_geeklist_comments_from_xml(listitem, xml_root)
added_items = True
return added_items
17 changes: 16 additions & 1 deletion boardgamegeek/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import argparse
import logging

from boardgamegeek.api import HOT_ITEM_CHOICES, BGGClient
from boardgamegeek.api import BGGClient, HOT_ITEM_CHOICES
from boardgamegeek import BGGClientLegacy

log = logging.getLogger("boardgamegeek")
log_fmt = "[%(levelname)s] %(message)s"
Expand Down Expand Up @@ -60,6 +61,14 @@ def main():
"-H", "--hot-items", help="List all hot items by type", choices=HOT_ITEM_CHOICES
)
p.add_argument("-S", "--search", help="search and return results")

p.add_argument("-l", "--geeklist", type=int, help="get geeklist by id")
p.add_argument(
"--nocomments",
help="disable getting the comments with geeklist",
action="store_true",
)

p.add_argument("--debug", action="store_true")
p.add_argument(
"--retries",
Expand Down Expand Up @@ -98,6 +107,7 @@ def main():
args.plays_by_game,
args.hot_items,
args.search,
args.geeklist,
]
):
p.error("no action specified!")
Expand Down Expand Up @@ -160,6 +170,11 @@ def main():
r._format(log)
log.info("")

if args.geeklist:
oldbgg = BGGClientLegacy(timeout=args.timeout, retries=args.retries)
geeklist = oldbgg.geeklist(args.geeklist, comments=not args.nocomments)
geeklist._format(log)


if __name__ == "__main__":
main()
6 changes: 3 additions & 3 deletions boardgamegeek/objects/games.py
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ def users_wanting(self):
:rtype: integer
:return: ``None`` if n/a
"""
return self._data.get("wanting")
return self._stats.users_wanting

@property
def users_wishing(self):
Expand All @@ -1149,7 +1149,7 @@ def users_wishing(self):
:rtype: integer
:return: ``None`` if n/a
"""
return self._data.get("wishing")
return self._stats.users_wishing

@property
def users_commented(self):
Expand All @@ -1158,7 +1158,7 @@ def users_commented(self):
:rtype: integer
:return: ``None`` if n/a
"""
return self._data.get("numcomments")
return self._stats.users_commented

@property
def rating_num_weights(self):
Expand Down
Loading

0 comments on commit 4d0e341

Please sign in to comment.