def __init__(self, project_name, cache_bgg):
     if cache_bgg:
         self.client = BGGClient(cache=CacheBackendSqlite(
             path=f"{project_name}-cache.sqlite",
             ttl=60 * 60 * 24,
         ))
     else:
         self.client = BGGClient()
示例#2
0
 def __init__(self, cache_bgg):
     project_name = SETTINGS["project"]["name"]
     if cache_bgg:
         self.client = BGGClient(cache=CacheBackendSqlite(
             path=f"{SETTINGS['project']['name']}-cache.sqlite",
             ttl=60 * 60 * 24,
         ))
     else:
         self.client = BGGClient()
示例#3
0
    def retrieve(self, request, pk=None):
        """Handle GET requests for single game

        Returns:
            Response -- JSON serialized game instance
        """
        try:
            game = Game.objects.get(pk=pk)
            bgg = BGGClient()
            player = Player.objects.get(user=game.player.user)

            BGGObj = bgg.game(game_id=str(game.game))
            game1={}
            game1['name'] = game.name
            game1["api_id"] = game.game
            game1["api_game_name"]= BGGObj.name
            playerObj = PlayerSerializer(player, context={'request': request})
            game1['player'] = playerObj.data
            game1['host_descrip'] = game.host_descrip
            game1['max_players'] = BGGObj.max_players
            game1['min_players'] = BGGObj.min_players
            game1['category_ids'] = game.category_ids
            game1['categories'] = []
            for category in BGGObj.categories:
                game1['categories'].append(category)
            game1['image'] = BGGObj.image
            game1['thumb_nail'] = BGGObj.thumbnail
            return Response(game1)
        except Exception as ex:
            return HttpResponseServerError(ex)
示例#4
0
文件: db_worker.py 项目: rbtnx/foxbot
def get_games(username):
    """ Get games and game collection using bgg API2 
    returns: list of games and collection object """

    bgg = BGGClient(timeout=120, requests_per_minute=20)
    print("Getting collection from BGG..")
    collection = bgg.collection(username,
                                exclude_subtype='boardgameexpansion',
                                own=True,
                                wishlist=None)
    ids = [x.id for x in collection.items]
    game_list = []

    # get games from BGG
    try:
        print("Getting games from BGG..")
        game_list = bgg.game_list(ids)
        if not game_list:
            print("Error: empy list returned.")
    except:
        print("An Error occured..")
        raise TimeoutError
    else:
        print("Done.")
    return game_list, collection
示例#5
0
    def get_external_game(bgg_id):
        bgg = BGGClient()
        max_count = 10
        while max_count:
            try:
                return bgg.game(game_id=bgg_id)

            except bgg_exceptions.BGGValueError:
                print("[ERROR] Invalid parameters")
                raise

            except bgg_exceptions.BGGApiRetryError:
                print("[ERROR] Retry after delay, retrying...")
                BoardGameGeek._retry(max_count)

            except bgg_exceptions.BGGApiError:
                print("[ERROR] API response invalid or not parsed")
                BoardGameGeek._retry(max_count)

            except bgg_exceptions.BGGApiTimeoutError:
                print("[ERROR] Timeout")
                BoardGameGeek._retry(max_count)

            except Exception as err:
                print("[ERROR] Exception caught getting external game: " +
                      str(err))
                BoardGameGeek._retry(max_count)

        raise Exception
示例#6
0
def get_all_ratings(members, bgg=None):
    """Get the ratings for all users in the list members.

        Returns: A dict (gameid, game name) -> list of ratings
    """
    if bgg is None:
        bgg = BGGClient()

    all_member_ratings = dict()

    print 'Retrieving user ratings...'
    work_queue = Queue()
    for member in members:
        work_queue.put(member)

    while not work_queue.empty():
        print work_queue.qsize(), 'members to process'
        member = work_queue.get()
        print 'Fetching data for ', member
        try:
            user_ratings = get_user_ratings(member, bgg=bgg)
        except Exception:
            work_queue.put(member)
            continue
        all_member_ratings[member] = user_ratings

    print 'Ratings retrieved for all users.'

    return all_member_ratings
示例#7
0
def new_game():
    client = BGGClient()
    not_found = True
    while not_found:

        game_search = input_prompt(
            message=GAME_MESSAGE,
            validation_function=lambda x: True
            if x != "" else "Enter something!",
        )
        if game_search.lower() == "r":
            return

        games = client.search(game_search)

        game_names = [game.name for game in games]
        if not game_names:
            print("No games found")
            continue

        game_question_list = game_names + [GAME_CANCEL_OPTION]

        answer = list_prompt(message=GAME_CHOICE_MESSAGE,
                             items=game_question_list)
        if answer == GAME_CANCEL_OPTION:
            continue
        if confirmation_prompt(
                message=f"Are you sure you would like to add {answer}?"):
            not_found = False

    add_game(games[game_names.index(answer)])
示例#8
0
def search_boardgame(boardgame, game_type=None):
    """
    Uses the boardgamemeek XML API to search for games
    Currently supports boardgames and TT RPGS
    """
    if game_type is None:
        search_type = None
        game_type = 'boardgame'
    elif game_type == 'RPG':
        game_type = 'rpgitem'
        search_type = [BGGRestrictSearchResultsTo.RPG]
    bgg = BGGClient()
    res = bgg.search(boardgame, search_type=search_type)
    # this is terrible
    if len(res) == 0:
        return "I couldn't find any game similar to the title %s" % boardgame
    print([x.data() for x in res[0:10]])
    games = [x for x in res if boardgame.lower() == x.name.lower()]
    resp = ""
    if len(games) == 0:
        resp += ("Couldn't find game {} exactly, but I found {} which " +
                 "looks close\n").format(boardgame, len(res))
        games = [x for x in res if boardgame.lower() in x.name.lower()]
        if len(games) == 0:
            resp += "Well, not exactly close, "
            resp += "but here's the oldest one on the list\n"
            games = res
    g = sorted(games, key=lambda x: x.year)[0]
    url_format = "https://www.boardgamegeek.com/{game_tp}/{id}/{name}".format(
        game_tp=game_type, id=g.id, name=g.name.lower().replace(' ', '-'))
    return resp + url_format
示例#9
0
 def create_client():
     return BGGClient(cache=CacheBackendSqlite(
         path=BoardGameFactory.cache_location,
         ttl=BoardGameFactory.item_cache_duration),
                      timeout=60,
                      retry_delay=10,
                      retries=6)
示例#10
0
def collect_gamedata(game_list):
    """ Get game data from BGG.

    Description:
        Get game data in chunks of 50 games per api call

    inputs:
        game_list (list): List of ids

    returns:
        games (list): List of game objects """

    bgg = BGGClient(retries=6, retry_delay=4)

    chunksize = 50
    if len(game_list) < chunksize:
        games = bgg.game_list(game_list)
        return games

    games = []
    id_chunks = [
        game_list[i:i + chunksize] for i in range(0, len(game_list), chunksize)
    ]
    for i in id_chunks:
        games = games + bgg.game_list(i)
    return games
示例#11
0
def get_guild_user_list(guild_id, bgg=None):
    """Fetch the member list for a BGG Guild"""
    if bgg is None:
        bgg = BGGClient()

    print 'Fetching guild user list'
    guild = bgg.guild(guild_id)
    return list(guild.members)
示例#12
0
 def category_ids(self):
     bgg = BGGClient()
     id_list = []
     api_game = bgg.game(game_id=str(self.game))
     for category in api_game.categories:
         cat = Category.objects.get(name=category)
         id_list.append(cat.id)
     return id_list
示例#13
0
    def create(bgg_id):
        client = BGGClient()
        game = BoardGameGeek.get_external_game(bgg_id)

        bgg_game = BggGame(bggid=game.id)
        bgg_game = BoardGameGeek.convert_external_game(external=game,
                                                       game=bgg_game)
        bgg_game.save()
        return bgg_game
示例#14
0
    def is_full(self):
        gameObj = Game.objects.get(pk=self.game_id)
        bgg= BGGClient()
        game = bgg.game(game_id=str(gameObj.game))

        if len(self.player_list) >= int(game.max_players):
            return True
        else:
            return False
示例#15
0
    def need_players(self):
        gameObj = Game.objects.get(pk=self.game_id)
        bgg= BGGClient()
        game = bgg.game(game_id=str(gameObj.game))

        if len(self.player_list) < int(game.min_players):
            players_needed = int(game.min_players)- len(self.player_list)
            return players_needed
        else:
            return 0
示例#16
0
 def __init__(self, ids_file, names_file, details_file):
     '''ids_file - name of a file with/for BGG ids
        names_file - name of a file with/for BGG game names
        details_file - name of a file with/for BGG game details'''
     self._ids_file = ids_file
     self._ids = None
     self._names_file = names_file
     self._names = None
     self._details_file = details_file
     self._bgg = BGGClient()
示例#17
0
def get_collection(username: str) -> BGGClient.collection:
    bgg = BGGClient()
    for n in range(0, 8):
        try:
            return bgg.collection(username)
        except Exception as error:
            logging.warning(
                str(error) + ' error received, trying again in ' + str(3**n) +
                ' seconds')
            time.sleep(3**n)
    logging.error('too many errors, gg')
示例#18
0
def get_user(username: str) -> User:
    logging.info(f'fetching data from user {username} from bgg')
    bgg = BGGClient()
    for n in range(0, 8):
        try:
            user_data = bgg.user(username)
            logging.info('user data received')
            return user_data
        except Exception as error:
            logging.warning(str(error) + ' error received, trying again in ' + str(3**n) + ' seconds')
            time.sleep(3**n)
    logging.error('too many errors, gg')
示例#19
0
def get_user_ratings(username, bgg=None):
    """Returns a dict: gameid -> rating"""
    if bgg is None:
        bgg = BGGClient()

    collection = bgg.collection(username)

    user_ratings = dict()
    for item in collection:
        if item.rating:
            user_ratings[item.id] = item.rating

    return user_ratings
示例#20
0
def get_game_info(game_id, bgg=None):
    """Fetch the BGG info for game having game_id"""
    if bgg is None:
        bgg = BGGClient()

    print 'Fetching info for game', str(game_id)

    game = None
    while game is None:
        try:
            game = bgg.game(game_id=game_id)
        except Exception:
            print 'Trying to fetch again...'
            continue

    return game
示例#21
0
    def get(self, request):
        form = SearchForm(request.GET)
        if form.is_valid():
            bgg = BGGClient()
            query = form.cleaned_data["query"]
            query = bgg.search(query)
            query = [q.data() for q in query]

            keys = ['id', 'name', 'type', 'yearpublished']

            query_items = [[(key, data[key]) for key in keys]
                           for data in query]

            return render(request, "results.html", {
                "query_items": query_items,
                "keys": keys,
            })
        else:
            return render(request, "main.html", {"form": form})
示例#22
0
def user(request, username, owned, rating):
    bgg = BGGClient(retries=10, retry_delay=10)
    coll = bgg.collection(username)
    running_score = defaultdict(float)
    n = 0
    for game in coll:
        game_obj, game_created = BoardGame.objects.get_or_create(
            title=game.name, bgg_id=game.id)
        coll_obj, created = BGGCollection.objects.update_or_create(
            boardgame=game_obj,
            rating=game.rating,
            owned=bool(game.owned),
            comment=game.comment,
        )

        if game_created:  # Newly added board games would not have genre and mechanism
            continue

        if bool(owned) and not bool(game.owned):
            continue

        if game.rating is not None:
            if rating > game.rating:
                continue

        combined_score = _recommend_boardgames(game_obj)
        n += 1

        for k, v in combined_score.items():
            running_score[k] += v

    running_score = {k: v / n for k, v in running_score.items()}
    running_score = sorted(running_score.items(), key=lambda x: -x[1])

    return render(
        request, 'genome/user.html', {
            'username': username,
            'recs': running_score,
            'form': form,
            'user_form': user_form,
        })
示例#23
0
def open_file_find_games(path, out=None):
    lines = None
    with open(path, 'r') as file:
        lines = [l.strip() for l in file.readlines()]
    click.echo('Read {} lines'.format(len(lines)))

    client = BGGClient()
    games = search_games(lines, client)
    click.echo('Found {} games'.format(len(games)))

    if out:
        with open(out, 'w', newline='') as file:
            fieldnames = list(printable_game_dict(games[0].data()).keys())
            csvfile = csv.DictWriter(file,
                                     delimiter=',',
                                     fieldnames=fieldnames)
            csvfile.writeheader()

            for game in games:
                printable = printable_game_dict(game.data())
                logger.debug(printable)
                csvfile.writerow(printable)
示例#24
0
def main(user, member_data_file):
    bgg = BGGClient()

    with open(member_data_file, 'r') as data_file:
        member_data = yaml.load(data_file)

    user_data = member_data[user]
    del member_data[user]
    user_collection_size = len(user_data)

    member_scores = list()
    for user, ratings in member_data.iteritems():
        score = 0
        games_in_common = 0
        for game, rating in user_data.iteritems():
            if game in ratings:
                diff = (rating - ratings[game])**2
                score += diff
                games_in_common += 1
        member_scores.append({
            'user': user,
            'score': score,
            'common': games_in_common
        })

    member_scores = filter(lambda x: x['common'] >= 0.5 * user_collection_size,
                           member_scores)
    member_scores.sort(key=lambda x: x['score'])

    filename = user + '_followers.yml'
    with open(filename, 'w') as fo:
        yaml.dump(member_scores, fo)

    for i in range(5):
        member = member_scores[i]
        print member['user'], member['score'], member['common']
示例#25
0
 def __init__(self):
     project_name = SETTINGS["project"]["name"]
     self.client = BGGClient(cache=CacheBackendSqlite(
         path=f"{project_name}-cache.sqlite", ttl=60 * 60 * 24))
import re
import time
from bs4 import BeautifulSoup
from boardgamegeek import BGGClient
import scrapy
from scrapy.spiders import CrawlSpider
from scrapy.item import Item, Field
# from selenium.common.exceptions import NoSuchElementException
# pip install boardgamegeek2 to install boardgameGeek
#I have used selenium to scrape using XPATH
from selenium import webdriver

gameurl = 'https://boardgamegeek.com/boardgame/'
bgg = BGGClient()

#based on the platform download phantomjs and give the path to the the executable
browser = webdriver.PhantomJS()


class Game(Item):
    id = Field()
    title = Field()
    geek_rate = Field()
    avg_rate = Field()
    num_votes = Field()
    type = Field()
    yearpublished = Field()
    minplayers = Field()
    maxplayers = Field()
    playingtime = Field()
    minplaytime = Field()
示例#27
0
#!/usr/bin/env python3

from math import ceil

from boardgamegeek import BGGClient, BGGRestrictCollectionTo as restrict
from boardgamegeek.cache import CacheBackendSqlite

INCH_TO_CM = 2.54  # Exactly!

bgg = BGGClient(cache=CacheBackendSqlite(path=".cache.bgg2", ttl=3600 * 24))

collection = bgg.collection('arnauldvm',
                            own=True,
                            exclude_subtype=restrict.BOARD_GAME_EXTENSION,
                            version=True)
print(f"{collection}")

unknown_boxes_count = 0

longest_dimension = 0

long_boxes_count = 0
long_boxes_total_height = 0

average_boxes_count = 0
average_boxes_total_height = 0

small_boxes_count = 0
small_boxes_total_height = 0

for game in collection:
示例#28
0
    def list(self, request):
        """Handle GET requests to game Categories resource

        Returns:
            Response -- JSON serialized list of park ProductCategorys
        """
        # Creating game dictionary of custom info from game object and API boardgame object so user can see info from both
        bgg = BGGClient()
        search_term = self.request.query_params.get('search', None)
        game_list = []
        if search_term is None:
            games = Game.objects.all()
            collection = []

            for game in games:
                BGGObj = bgg.game(game_id=str(game.game))
                game1={}
                game1['id'] = game.id
                game1['name'] = game.name
                game1["api_id"] = game.game
                owner = Player.objects.get(user=game.player.user)
                playerObj = PlayerSerializer(owner, context={'request': request})
                game1['player'] = playerObj.data
                game1['host_descrip'] = game.host_descrip
                game1['game_descrip'] = BGGObj.description
                game1['max_players'] = BGGObj.max_players
                game1['min_players'] = BGGObj.min_players
                game1['category_ids'] = game.category_ids
                game1['category_names'] = []
                for category in BGGObj.categories:
                    game1['category_names'].append(category)
                game1['image'] = BGGObj.image
                game1['thumb_nail'] = BGGObj.thumbnail
                game_list.append(game1)
        else:
            # If there is a search query param, we are searching BGG API for game results for user to choose from
            results = bgg.games(search_term)
            for result in results:
                game1={}
                game1["name"] = result.name
                game1["min_players"] = result.min_players
                game1["max_players"] = result.max_players
                game1["api_id"] = result.id
                game1["description"] = result.description
                game1["image"] = result.image
                game_list.append(game1)


        # Query param to fetch a logged in user's games
        user_game = self.request.query_params.get('user_game', None)
        # query param to fetch games by category
        category = self.request.query_params.get('category', None)



        if (user_game is not None) or (category is not None):
            if user_game is not None:
                for game in game_list:
                    if (+game['player']['id'] == +request.auth.user_id) & (game not in collection):
                        collection.append(game)


            if category is not None:
                for game in game_list:
                    for id in game["category_ids"]:
                        if (str(id) ==category) & (game not in collection):
                            collection.append(game)

            game_list = collection
        else:
            pass





        return Response(game_list)
示例#29
0
def bgg():
    return BGGClient(cache=CacheBackendNone(), retries=2, retry_delay=1)
示例#30
0
def main(users=None, raw_data=None, generate_report=False, prune=None):
    bgg = BGGClient()

    # if not users and not raw_data: get users, get user ratings, process ratings
    # if users and not raw_data: load users, get user ratings, process ratings
    # if raw data: load users, load user ratings, process ratings

    now_str = str(datetime.datetime.now())
    filename_tag = '_'.join(now_str[:10].split())

    if raw_data is None:
        # load members from file or query for current list
        if users is None:
            members = get_guild_user_list(PUNCHING_CARDBOARD, bgg=bgg)
            of = open('members_' + filename_tag + '.txt', 'w')
            for member in members:
                of.write(member + '\n')
        else:
            members = load_members_from_file(users)

        guild_size = len(members)
        print 'Members list loaded: %d guild members' % guild_size
        member_ratings = get_all_ratings(members, bgg=bgg)
        guild_ratings = collapse_ratings(member_ratings)

        print 'Processing results...'
        print '%d games rated' % len(guild_ratings)
        top_games = list()
        for game_id, ratings in guild_ratings.iteritems():
            num_ratings = len(ratings)
            avg_rating = round(mean(ratings), 3)
            sd_ratings = round(stdev(ratings), 3)
            top_games.append((game_id, num_ratings, avg_rating, sd_ratings))

        # Sort the list
        top_games.sort(key=lambda x: x[2], reverse=True)

        # Write out the raw data to this point
        current_time_str = str(datetime.datetime.now())
        rating_data = dict()
        rating_data[SUMMARY] = { GUILD_MEMBER_COUNT: guild_size,
                              TOTAL_GAMES: len(guild_ratings),
                              TIME: current_time_str
                            }
        rating_data[MEMBERS] = members
        rating_data[SORTED_GAMES] = top_games
        with open('guild_data_' + filename_tag + '.json', 'w') as raw_data_file:
            json.dump(rating_data, raw_data_file)
        with open('member_data_' + filename_tag + '.yml', 'w') as raw_data_file:
            yaml.dump(member_ratings, raw_data_file)

    elif raw_data is not None:
        rating_data = json.load(open(raw_data, 'r'))

    # Either path we now have rating_data
    top_games = rating_data[SORTED_GAMES]
    member_count = rating_data[SUMMARY][GUILD_MEMBER_COUNT]

    # If we want to prune the games
    if prune is not None:
        pruned_games = list()
        with open(prune, 'r') as f:
            reader = csv.reader(f)
            for row in reader:
                gameid = int(row[0])
                matches = [x for x in top_games if x[0] == gameid]
                if len(matches) == 1:
                    match = matches[0]
                    matched_game = (row[1], match[0], match[1], match[2], match[3])
                elif len(matches) == 0:
                    matched_game = (row[1], gameid, 0, 0, 0)
                else:
                    print 'ERROR'
                    return
                pruned_games.append(matched_game)
        pruned_games.sort(key=lambda x: x[3], reverse=True)
        for idx, game in enumerate(pruned_games):
            label = str(idx + 1) + '.'
            print label, game[0], game[2], game[3], game[4]
        return
    else:
        top_games = filter(lambda x: x[1] >= 0.1 * member_count, top_games)

    # Get the top 50
    top50 = list()
    top_games.sort(key=lambda x: x[2], reverse=True)
    count_of_printed = 0
    for game in top_games:
        game_info = get_game_info(game[0], bgg)
        if not game_info.expansion:
            count_of_printed += 1
            top50.append((game_info.name, game[0], game[1], game[2], game[3]))
        if count_of_printed > 49:
            break

    # Get the bottom 10
    bottom10 = list()
    top_games.sort(key=lambda x: x[2])
    count_of_printed = 0
    for game in top_games:
        game_info = get_game_info(game[0], bgg)
        if not game_info.expansion:
            count_of_printed += 1
            bottom10.append((game_info.name, game[0], game[1], game[2], game[3]))
        if count_of_printed > 9:
            break

    # Get the most variable
    variable10 = list()
    top_games.sort(key=lambda x: x[3], reverse=True)
    count_of_printed = 0
    for game in top_games:
        game_info = get_game_info(game[0], bgg)
        if not game_info.expansion:
            count_of_printed += 1
            variable10.append((game_info.name, game[0], game[1], game[2], game[3]))
        if count_of_printed > 9:
            break

    # Get the most rated
    most10 = list()
    top_games.sort(key=lambda x: x[1], reverse=True)
    count_of_printed = 0
    for game in top_games:
        game_info = get_game_info(game[0], bgg)
        if not game_info.expansion:
            count_of_printed += 1
            most10.append((game_info.name, game[0], game[1], game[2], game[3]))
        if count_of_printed > 9:
            break

    fi = open('lists_' + filename_tag + '.json', 'w')
    lists_dict = dict()
    lists_dict['top50'] = top50
    lists_dict['bottom10'] = bottom10
    lists_dict['variable10'] = variable10
    lists_dict['most10'] = most10
    json.dump(lists_dict, fi)

    print 'Finished'