Skip to content

Commit

Permalink
Add ability to customize cookie dir (#128)
Browse files Browse the repository at this point in the history
πŸš€ v2.0.0-alpha.4 - Add ability to customize cookies directory

* And, default to a directory that is outside the module
(~/.linkedin_api/)
  • Loading branch information
tomquirk authored Oct 24, 2020
1 parent 705cea1 commit 97ba026
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 28 deletions.
2 changes: 1 addition & 1 deletion linkedin_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .linkedin import Linkedin

__title__ = "linkedin_api"
__version__ = "2.0.0-alpha.3"
__version__ = "2.0.0-alpha.4"
__description__ = "Python Wrapper for the Linkedin API"

__license__ = "MIT"
Expand Down
6 changes: 4 additions & 2 deletions linkedin_api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,17 @@ class Client(object):
"Accept-Language": "en-us",
}

def __init__(self, *, debug=False, refresh_cookies=False, proxies={}):
def __init__(
self, *, debug=False, refresh_cookies=False, proxies={}, cookies_dir=None
):
self.session = requests.session()
self.session.proxies.update(proxies)
self.session.headers.update(Client.REQUEST_HEADERS)
self.proxies = proxies
self.logger = logger
self.metadata = {}
self._use_cookie_cache = not refresh_cookies
self._cookie_repository = CookieRepository()
self._cookie_repository = CookieRepository(cookies_dir=cookies_dir)

logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)

Expand Down
32 changes: 15 additions & 17 deletions linkedin_api/cookie_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,34 @@ class CookieRepository(object):
TODO: refactor to use http.cookiejar.FileCookieJar
"""

@staticmethod
def save(cookies, username):
CookieRepository._ensure_cookies_dir()
cookiejar_filepath = CookieRepository._get_cookies_filepath(username)
def __init__(self, cookies_dir=settings.COOKIE_PATH):
self.cookies_dir = cookies_dir

def save(self, cookies, username):
self._ensure_cookies_dir()
cookiejar_filepath = self._get_cookies_filepath(username)
with open(cookiejar_filepath, "wb") as f:
pickle.dump(cookies, f)

@staticmethod
def get(username):
cookies = CookieRepository._load_cookies_from_cache(username)
def get(self, username):
cookies = self._load_cookies_from_cache(username)
if cookies and not CookieRepository._is_token_still_valid(cookies):
raise LinkedinSessionExpired

return cookies

@staticmethod
def _ensure_cookies_dir():
if not os.path.exists(settings.COOKIE_PATH):
os.makedirs(settings.COOKIE_PATH)
def _ensure_cookies_dir(self):
if not os.path.exists(self.cookies_dir):
os.makedirs(self.cookies_dir)

@staticmethod
def _get_cookies_filepath(username):
def _get_cookies_filepath(self, username):
"""
Return the absolute path of the cookiejar for a given username
"""
return "{}{}.jr".format(settings.COOKIE_PATH, username)
return "{}{}.jr".format(self.cookies_dir, username)

@staticmethod
def _load_cookies_from_cache(username):
cookiejar_filepath = CookieRepository._get_cookies_filepath(username)
def _load_cookies_from_cache(self, username):
cookiejar_filepath = self._get_cookies_filepath(username)
try:
with open(cookiejar_filepath, "rb") as f:
cookies = pickle.load(f)
Expand Down
7 changes: 5 additions & 2 deletions linkedin_api/linkedin.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,14 @@ def __init__(
debug=False,
proxies={},
cookies=None,
cookies_dir=None,
):
"""Constructor method"""
self.client = Client(
refresh_cookies=refresh_cookies, debug=debug, proxies=proxies
refresh_cookies=refresh_cookies,
debug=debug,
proxies=proxies,
cookies_dir=cookies_dir,
)
logging.basicConfig(level=logging.DEBUG if debug else logging.INFO)
self.logger = logger
Expand Down Expand Up @@ -485,7 +489,6 @@ def get_profile(self, public_id=None, urn_id=None):
:return: Profile data
:rtype: dict
"""

# NOTE this still works for now, but will probably eventually have to be converted to
# https://www.linkedin.com/voyager/api/identity/profiles/ACoAAAKT9JQBsH7LwKaE9Myay9WcX8OVGuDq9Uw
res = self._fetch(f"/identity/profiles/{public_id or urn_id}/profileView")
Expand Down
5 changes: 4 additions & 1 deletion linkedin_api/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import os
from pathlib import Path

HOME_DIR = str(Path.home())
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
COOKIE_PATH = os.path.join(ROOT_DIR, "cookies/")
LINKEDIN_API_USER_DIR = os.path.join(HOME_DIR, ".linkedin_api/")
COOKIE_PATH = os.path.join(LINKEDIN_API_USER_DIR, "cookies/")
14 changes: 9 additions & 5 deletions tests/test_cookie_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,31 @@ def mock_cookies(date=datetime.strptime("2050-05-04", "%Y-%m-%d")):


def test_save():
CookieRepository.save(mock_cookies(), "testuser")
repo = CookieRepository()
repo.save(mock_cookies(), "testuser")
assert True


def test_get():
c = CookieRepository.get("testuser")
repo = CookieRepository()
c = repo.get("testuser")
assert c is not None
assert c == mock_cookies()


def test_get_nonexistent_file():
c = CookieRepository.get("ghost")
repo = CookieRepository()
c = repo.get("ghost")
assert c is None


def test_get_expired():
CookieRepository.save(
repo = CookieRepository()
repo.save(
mock_cookies(date=datetime.strptime("2001-05-04", "%Y-%m-%d")), "testuserex"
)
try:
CookieRepository.get("testuserex")
repo.get("testuserex")
assert False
except LinkedinSessionExpired:
assert True

0 comments on commit 97ba026

Please sign in to comment.