From ed499cb49c510d122e2cfbc7985818823e6d1ac0 Mon Sep 17 00:00:00 2001 From: Alexander Graf <17130992+aandergr@users.noreply.github.com> Date: Sat, 6 Jun 2020 10:49:41 +0200 Subject: [PATCH] Let --sessionfile default to a more persistent path (#659) The presence of a sessionfile avoids the usage of the failure-prone login mechanism. This commit addresses a suggestion in #615 to store the sessionfile in a persistent path rather than a path within a temporary directory if no --sessionfile parameter is given. The default path is now: $XDG_CONFIG_HOME/instaloader/session-USERNAME or ~/.config/instaloader/session-USERNAME on Unix, %LOCALAPPDATA%\Instaloader\session-USERNAME on Windows. If no file exists in the new path, Instaloader tries loading from the path where the sessionfile was stored before this commit, hence it automatically migrates to the new sessionfile path. --- docs/basic-usage.rst | 15 ++++++++------- docs/cli-options.rst | 5 ++--- instaloader/instaloader.py | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/docs/basic-usage.rst b/docs/basic-usage.rst index 5933522..057eb88 100644 --- a/docs/basic-usage.rst +++ b/docs/basic-usage.rst @@ -51,7 +51,7 @@ invoke it with instaloader --login=your_username profile [profile ...] When logging in, Instaloader **stores the session cookies** in a file in your -temporary directory, which will be reused later the next time :option:`--login` +home directory, which will be reused later the next time :option:`--login` is given. So you can download private profiles **non-interactively** when you already have a valid session cookie file. @@ -291,17 +291,18 @@ Instaloader as Cronjob Instaloader is suitable for running as a cronjob to periodically update your personal Instagram archive. The :option:`--quiet` option disables user interactions and logging of non-error messages. To non-interactively use -Instaloader logged-in, create a session file, e.g. in your home directory:: +Instaloader logged-in, create a session file:: - instaloader --login=your_username --sessionfile=~/.instaloader-session + instaloader --login=your_username -Then use the same parameters in your cronjob to load the session and download +Then use the same parameter in your cronjob to load the session and download the given targets:: - instaloader --login=your_username --sessionfile=~/.instaloader-session --quiet [...] + instaloader --login=your_username --quiet [...] -Without :option:`--sessionfile` option, Instaloader saves the session file in -a path within your temporary directory. +Instaloader saves the session file to +``~/.config/instaloader/session-YOUR-USERNAME``. See +:option:`--sessionfile` option for how to override this path. Programming Instaloader ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/cli-options.rst b/docs/cli-options.rst index dac3568..8f3f3ec 100644 --- a/docs/cli-options.rst +++ b/docs/cli-options.rst @@ -193,9 +193,8 @@ Instaloader to login. .. option:: --sessionfile SESSIONFILE, -f SESSIONFILE - Path for loading and storing session key file. Defaults to a path within - your temporary directory, encoding your local username and your Instagram - profile name. + Path for loading and storing session key file. Defaults to + ``~/.config/instaloader/session-YOUR-USERNAME``. .. option:: --password YOUR-PASSWORD, -p YOUR-PASSWORD diff --git a/instaloader/instaloader.py b/instaloader/instaloader.py index 1ef41a3..56ea4e1 100644 --- a/instaloader/instaloader.py +++ b/instaloader/instaloader.py @@ -27,6 +27,20 @@ from .structures import (Hashtag, Highlight, JsonExportable, Post, PostLocation, def get_default_session_filename(username: str) -> str: """Returns default session filename for given username.""" + sessionfilename = "session-{}".format(username) + if platform.system() == "Windows": + # on Windows, use %LOCALAPPDATA%\Instaloader\session-USERNAME + localappdata = os.getenv("LOCALAPPDATA") + if localappdata is not None: + return os.path.join(localappdata, "Instaloader", sessionfilename) + # legacy fallback - store in temp dir if %LOCALAPPDATA% is not set + return os.path.join(tempfile.gettempdir(), ".instaloader-" + getpass.getuser(), sessionfilename) + # on Unix, use ~/.config/instaloader/session-USERNAME + return os.path.join(os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), "instaloader", sessionfilename) + + +def get_legacy_session_filename(username: str) -> str: + """Returns legacy (until v4.4.3) default session filename for given username.""" dirname = tempfile.gettempdir() + "/" + ".instaloader-" + getpass.getuser() filename = dirname + "/" + "session-" + username return filename.lower() @@ -441,6 +455,8 @@ class Instaloader: """ if filename is None: filename = get_default_session_filename(username) + if not os.path.exists(filename): + filename = get_legacy_session_filename(username) with open(filename, 'rb') as sessionfile: self.context.load_session_from_file(username, sessionfile) self.context.log("Loaded session from %s." % filename)