add .netrc support (#22)
Use the '--netrc' cmdline option or set the 'netrc' config option to 'true' to enable the use of .netrc authentication data. The 'machine' names for the .netrc info are the lowercase extractor names (or categories): batoto, exhentai, nijie, pixiv, seiga.
This commit is contained in:
@@ -23,6 +23,15 @@ Description Directory path used as the base for all download destinations.
|
|||||||
=========== =====
|
=========== =====
|
||||||
|
|
||||||
|
|
||||||
|
netrc
|
||||||
|
-----
|
||||||
|
=========== =====
|
||||||
|
Type ``bool``
|
||||||
|
Default ``false``
|
||||||
|
Description Enable the use of |.netrc|_ authentication data.
|
||||||
|
=========== =====
|
||||||
|
|
||||||
|
|
||||||
cache.file
|
cache.file
|
||||||
----------
|
----------
|
||||||
=========== =====
|
=========== =====
|
||||||
@@ -331,7 +340,7 @@ Description The value of the ``limit`` parameter when loading
|
|||||||
|
|
||||||
|
|
||||||
extractor.reddit.morecomments
|
extractor.reddit.morecomments
|
||||||
-------------------------
|
-----------------------------
|
||||||
=========== =====
|
=========== =====
|
||||||
Type ``bool``
|
Type ``bool``
|
||||||
Default ``false``
|
Default ``false``
|
||||||
@@ -392,11 +401,13 @@ Description The ``refresh_token`` value you get from linking your Reddit account
|
|||||||
=========== =====
|
=========== =====
|
||||||
|
|
||||||
|
|
||||||
|
.. |.netrc| replace:: ``.netrc``
|
||||||
.. |tempfile.gettempdir()| replace:: ``tempfile.gettempdir()``
|
.. |tempfile.gettempdir()| replace:: ``tempfile.gettempdir()``
|
||||||
.. |requests.get()| replace:: ``requests.get()``
|
.. |requests.get()| replace:: ``requests.get()``
|
||||||
.. |mature_content| replace:: ``mature_content``
|
.. |mature_content| replace:: ``mature_content``
|
||||||
.. |webbrowser.open()| replace:: ``webbrowser.open()``
|
.. |webbrowser.open()| replace:: ``webbrowser.open()``
|
||||||
|
|
||||||
|
.. _.netrc: https://stackoverflow.com/tags/.netrc/info
|
||||||
.. _tempfile.gettempdir(): https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir
|
.. _tempfile.gettempdir(): https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir
|
||||||
.. _requests.get(): https://docs.python-requests.org/en/latest/user/advanced/#timeouts
|
.. _requests.get(): https://docs.python-requests.org/en/latest/user/advanced/#timeouts
|
||||||
.. _format string: https://docs.python.org/3/library/string.html#formatstrings
|
.. _format string: https://docs.python.org/3/library/string.html#formatstrings
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"base-directory": "/tmp/",
|
"base-directory": "/tmp/",
|
||||||
|
"netrc": false,
|
||||||
"downloader":
|
"downloader":
|
||||||
{
|
{
|
||||||
"http":
|
"http":
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ class BatotoExtractor():
|
|||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
"""Login and set necessary cookies"""
|
"""Login and set necessary cookies"""
|
||||||
username = self.config("username")
|
username, password = self.auth_info()
|
||||||
password = self.config("password")
|
|
||||||
if username:
|
if username:
|
||||||
cookies = self._login_impl(username, password)
|
cookies = self._login_impl(username, password)
|
||||||
for key, value in cookies.items():
|
for key, value in cookies.items():
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import netrc
|
||||||
import queue
|
import queue
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
@@ -42,6 +43,24 @@ class Extractor():
|
|||||||
return config.interpolate(
|
return config.interpolate(
|
||||||
("extractor", self.category, self.subcategory, key), default)
|
("extractor", self.category, self.subcategory, key), default)
|
||||||
|
|
||||||
|
def auth_info(self):
|
||||||
|
"""Return authentication information as (username, password) tuple"""
|
||||||
|
username = self.config("username")
|
||||||
|
password = None
|
||||||
|
|
||||||
|
if username:
|
||||||
|
password = self.config("password")
|
||||||
|
elif config.get(("netrc",), False):
|
||||||
|
try:
|
||||||
|
info = netrc.netrc().authenticators(self.category)
|
||||||
|
username, _, password = info
|
||||||
|
except (OSError, netrc.NetrcParseError) as exc:
|
||||||
|
self.log.error("netrc: %s", exc)
|
||||||
|
except TypeError:
|
||||||
|
self.log.warning("netrc: No authentication info")
|
||||||
|
|
||||||
|
return username, password
|
||||||
|
|
||||||
def request(self, url, encoding=None, *args, **kwargs):
|
def request(self, url, encoding=None, *args, **kwargs):
|
||||||
response = safe_request(self.session, url, *args, **kwargs)
|
response = safe_request(self.session, url, *args, **kwargs)
|
||||||
if encoding:
|
if encoding:
|
||||||
|
|||||||
@@ -182,13 +182,12 @@ class ExhentaiGalleryExtractor(Extractor):
|
|||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
"""Login and set necessary cookies"""
|
"""Login and set necessary cookies"""
|
||||||
username = self.config("username")
|
username, password = self.auth_info()
|
||||||
if not username:
|
if not username:
|
||||||
self.log.info("no username given; using e-hentai.org")
|
self.log.info("no username given; using e-hentai.org")
|
||||||
self.root = "https://e-hentai.org"
|
self.root = "https://e-hentai.org"
|
||||||
self.original = False
|
self.original = False
|
||||||
return
|
return
|
||||||
password = self.config("password")
|
|
||||||
cookies = self._login_impl(username, password)
|
cookies = self._login_impl(username, password)
|
||||||
for key, value in cookies.items():
|
for key, value in cookies.items():
|
||||||
self.session.cookies.set(
|
self.session.cookies.set(
|
||||||
|
|||||||
@@ -62,8 +62,7 @@ class NijieExtractor(AsynchronousExtractor):
|
|||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
"""Login and obtain session cookie"""
|
"""Login and obtain session cookie"""
|
||||||
username = self.config("username")
|
username, password = self.auth_info()
|
||||||
password = self.config("password")
|
|
||||||
self.session.cookies = self._login_impl(username, password)
|
self.session.cookies = self._login_impl(username, password)
|
||||||
|
|
||||||
@cache(maxage=30*24*60*60, keyarg=1)
|
@cache(maxage=30*24*60*60, keyarg=1)
|
||||||
|
|||||||
@@ -233,8 +233,7 @@ class PixivAPI():
|
|||||||
def __init__(self, extractor):
|
def __init__(self, extractor):
|
||||||
self.session = extractor.session
|
self.session = extractor.session
|
||||||
self.log = extractor.log
|
self.log = extractor.log
|
||||||
self.username = extractor.config("username")
|
self.username, self.password = extractor.auth_info()
|
||||||
self.password = extractor.config("password")
|
|
||||||
self.user_info = None
|
self.user_info = None
|
||||||
self.session.headers.update({
|
self.session.headers.update({
|
||||||
"Referer": "https://www.pixiv.net/",
|
"Referer": "https://www.pixiv.net/",
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ class SeigaExtractor(Extractor):
|
|||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
"""Login and set necessary cookies"""
|
"""Login and set necessary cookies"""
|
||||||
username = self.config("username")
|
username, password = self.auth_info()
|
||||||
password = self.config("password")
|
|
||||||
self.session.cookies = self._login_impl(username, password)
|
self.session.cookies = self._login_impl(username, password)
|
||||||
|
|
||||||
@cache(maxage=7*24*60*60, keyarg=1)
|
@cache(maxage=7*24*60*60, keyarg=1)
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ def build_parser():
|
|||||||
"-p", "--password",
|
"-p", "--password",
|
||||||
metavar="PASS", action=ConfigAction, dest="password",
|
metavar="PASS", action=ConfigAction, dest="password",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--netrc",
|
||||||
|
action=ConfigConstAction, nargs=0, dest="netrc", const=True,
|
||||||
|
help="Use .netrc authentication data",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-i", "--input-file",
|
"-i", "--input-file",
|
||||||
metavar="FILE", dest="inputfile",
|
metavar="FILE", dest="inputfile",
|
||||||
|
|||||||
Reference in New Issue
Block a user