Source code for friendlypins.user

"""Interfaces for interacting with Pinterest users"""
import logging
import json
from datetime import datetime
from dateutil import tz
from friendlypins.board import Board


[docs]class User(object): """Abstraction around a Pinterest user and their associated data""" def __init__(self, url, rest_io): """ Args: url (str): URL for this user, relative to the API root rest_io (RestIO): reference to the Pinterest REST API """ self._log = logging.getLogger(__name__) self._io = rest_io self._relative_url = url self._data_cache = None
[docs] @staticmethod def default_fields(): """list (str): list of fields we pre-populate when loading user data""" return [ "id", "username", "first_name", "last_name", "bio", "created_at", "counts", "image", "account_type", "url" ]
[docs] def refresh(self): """Updates cached response data describing the state of this user NOTE: This method simply clears the internal cache, and updated information will automatically be pulled on demand as additional queries are made through the API""" self._data_cache = None
@property def _data(self): """dict: JSON response containing details of the users' profile This internal helper caches the user profile data to minimize the number of calls to the REST API, to make more efficient use of rate limitations. """ if self._data_cache is not None: return self._data_cache self._log.debug("Getting authenticated user details...") fields = ",".join(self.default_fields()) temp = self._io.get(self._relative_url, {"fields": fields}) assert 'data' in temp self._data_cache = temp["data"] return self._data_cache def __str__(self): return json.dumps(dict(self._data), sort_keys=True, indent=4) def __repr__(self): return "<{0} ({1} {2})>".format( self.__class__.__name__, self.first_name, self.last_name) @property def unique_id(self): """int: Gets the internal unique ID associated with the user""" return int(self._data['id']) @property def first_name(self): """str: the first name of the user""" return self._data['first_name'] @property def last_name(self): """str: the last name of the user""" return self._data['last_name'] @property def name(self): """str: the full name of the user alias for first_name + last_name """ return "{0} {1}".format(self.first_name, self.last_name).strip() @property def username(self): """str: display name, used for logging in to Pinterest""" return self._data["username"] @property def url(self): """str: the URL of the users profile""" return self._data['url'] @property def num_pins(self): """int: the total number of pins owned by this user""" return self._data['counts']['pins'] @property def num_boards(self): """int: the total number of boards owned by this user""" return self._data['counts']['boards'] @property def num_followers(self): """int: number of people following this Pinterest user""" return self._data["counts"]["followers"] @property def created(self): """datetime.datetime: when this user's profile was created""" # sample datetime to parse: "2020-07-21T16:16:03" (in UTC) raw_date = self._data["created_at"] retval = datetime.strptime(raw_date, "%Y-%m-%dT%H:%M:%S") return retval.replace(tzinfo=tz.tzutc()) @property def account_type(self): """str: type of Pinterest account (ie: individual / business)""" return self._data["account_type"] @property def bio(self): """str: description of who this user is""" return self._data["bio"] @property def boards(self): """Board: Generator for iterating over the boards owned by this user""" self._log.debug('Loading boards for user %s...', self._relative_url) properties = { "fields": ','.join(Board.default_fields()) } board_url = "{0}/boards".format(self._relative_url) for cur_page in self._io.get_pages(board_url, properties): assert 'data' in cur_page for cur_item in cur_page['data']: yield Board.from_json(cur_item, self._io)
[docs] def create_board(self, name, description=None): """Creates a new board for the currently authenticated user Args: name (str): name for the new board description (str): optional descriptive text for the board Returns: Board: reference to the newly created board """ properties = { "fields": ','.join(Board.default_fields()) } data = {"name": name} if description: data["description"] = description result = self._io.post("boards", data, properties) return Board.from_json(result['data'], self._io)
if __name__ == "__main__": # pragma: no cover pass