Skip to content

Instantly share code, notes, and snippets.

@stefan2904
Last active March 30, 2023 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefan2904/b1a4b21656f2c3b44ab598e652d7cc1a to your computer and use it in GitHub Desktop.
Save stefan2904/b1a4b21656f2c3b44ab598e652d7cc1a to your computer and use it in GitHub Desktop.
Sync Firefox Cookies to Emacs' url-cookie (see also README below)
#!/usr/bin/env python3
# ~/.emacs.d/url/cookies
# https://github.com/borisbabic/browser_cookie3
# ;; A cookie is stored internally as a vector of 7 slots
# ;; [ url-cookie NAME VALUE EXPIRES LOCALPART DOMAIN SECURE ]
from datetime import datetime
from browser_cookie3 import Firefox
TEMPLATE = """
;; Emacs-W3 HTTP cookies file
;; Automatically generated file!!! DO NOT EDIT!!!
;; file content imported from browser cookies on {}
(setq url-cookie-storage
{}
)
(setq url-cookie-secure-storage
{}
)
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; End:
"""
#DOMAINFILTER = []
DOMAINFILTER = ['github.com', 'gitlab.com']
def domainIsInteresting(domain):
if len(DOMAINFILTER) == 0:
return True
for df in DOMAINFILTER:
if domain.endswith(df):
return True
return False
def getCookies(cj, Secure):
cookies = {}
for cookie in cj:
# apparently `url-cookie-secure-storage` is not used? so load cookies in both stores for now
#if cookie.secure is not Secure:
# continue
if cookie.domain not in cookies:
cookies[cookie.domain] = []
value = cookie.value.replace('"', '')
cline = '[url-cookie "{}" "{}" "{}" "{}" "{}" {}]'.format(cookie.name, value, cookie.expires, cookie.path, cookie.domain, 't' if cookie.secure else 'nil')
cookies[cookie.domain].append(cline)
cstore = []
for domain, clines in cookies.items():
if not domainIsInteresting(domain):
continue
if len(cstore) == 0:
cstore.append(' \'(')
cstore.append(' ("{}"'.format(domain))
for cline in clines:
cstore.append(" " + cline)
cstore.append(" )")
if len(cstore) != 0:
cstore.append(' )')
else:
cstore.append('\'nil')
return cstore
def main():
cj = Firefox().load()
# print(Firefox().find_cookie_file())
cookies = getCookies(cj, False)
cookies_secure = getCookies(cj, True)
cfile = TEMPLATE.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'\n'.join(cookies),
'\n'.join(cookies_secure))
print(cfile)
if __name__ == '__main__':
# python3 syncFirefoxCookiesToEmacs.py > ~/.emacs.d/url/cookies
main()

I used this script to allow org-web-tools to use my Firefox cookies (see this issue). The following is currently required to enable this:

overloaded org-web-tools--get-url (set no-cookies to nil)

(only modified parameters of call to url-retrieve-synchronously)

(defun org-web-tools--get-url (url)
  "Return content for URL as string.
This uses `url-retrieve-synchronously' to make a request with the
URL, then returns the response body.  Since that function returns
the entire response, including headers, we must remove the
headers ourselves."
  (let* ((response-buffer (url-retrieve-synchronously url))
         (encoded-html (with-current-buffer response-buffer
                         ;; Skip HTTP headers.
                         ;; FIXME: Byte-compiling says that `url-http-end-of-headers' is a free
                         ;; variable, which seems to be because it's not declared by url.el with
                         ;; `defvar'.  Yet this seems to work fine...
                         (delete-region (point-min) url-http-end-of-headers)
                         (buffer-string))))
    ;; NOTE: Be careful to kill the buffer, because `url' doesn't close it automatically.
    (kill-buffer response-buffer)
    (with-temp-buffer
      ;; For some reason, running `decode-coding-region' in the
      ;; response buffer has no effect, so we have to do it in a
      ;; temp buffer.
      (insert encoded-html)
      (condition-case nil
          ;; Fix undecoded text
          (decode-coding-region (point-min) (point-max) 'utf-8)
        (coding-system-error nil))
      (buffer-string))))

make sure cookie file is loaded

(url-cookie-parse-file "~/.emacs.d/url/cookies")

use another browser?

Simply switch out the browser in main() with another of the supported browsers.

Warning

Obviously calling python3 syncFirefoxCookiesToEmacs.py > ~/.emacs.d/url/cookies overwrites your existing cookies. If you use url-cookie with other cookies, you might consider a different approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment