Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 32 additions & 22 deletions newapi/api_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ def __init__(
username: str,
password: str,
cookies_dir: str | None = settings.paths.cookies_dir,
use_cookies: bool = True,
) -> None:
"""
Initialise the client, load any saved cookies, and ensure the session
Expand All @@ -426,22 +427,27 @@ def __init__(
self._password = password # kept private — never log or expose this

# ── Cookie path ────────────────────────────────────────────────────

self._cookie_path: Path = get_cookie_path(cookies_dir or settings.paths.cookies_dir, family, lang, username)

self._cookie_path = None
self.use_cookies = use_cookies
# ── mwclient Site ──────────────────────────────────────────────────
logger.debug("Creating mwclient.Site for %s.%s", lang, family)
logger.debug("Creating mwclient.Site for %s.%s.org", lang, family)
self.api_url = f"https://{self.lang}.{self.family}.org/w/api.php"

if self.api_url == "https://www.mdwiki.org/w/api.php":
self.api_url = "https://mdwiki.org/w/api.php"

try:
self._site = mwclient.Site(f"{self.lang}.{self.family}.org", do_init=False)
except Exception as exc:
raise WikiClientError(f"Invalid site ID: {self.lang}.{self.family}") from exc
raise WikiClientError(f"Invalid site ID: {self.lang}.{self.family}.org") from exc

# ── Inject saved cookies ───────────────────────────────────────────
# mwclient stores its requests.Session at site.connection.
self.cj = self._make_cookiejar(self._cookie_path)
self._site.connection.cookies = self.cj
self.cj = None
if self.use_cookies:
self._cookie_path: Path = get_cookie_path(cookies_dir or settings.paths.cookies_dir, family, lang, username)
self.cj = self._make_cookiejar(self._cookie_path)
self._site.connection.cookies = self.cj

# ── Wrap the session with retry / CSRF / maxlag logic ──────────────
# wrap_session(self._site.connection, self._site)
Expand All @@ -468,12 +474,13 @@ def _on_assertnameduserfailed(self) -> None:
Called by the base-class retry loop; never call directly.
"""
logger.warning(
"assertnameduserfailed for %s on %s.%s — clearing cookies and re-logging in",
"assertnameduserfailed for %s on %s.%s.org — clearing cookies and re-logging in",
self.username,
self.lang,
self.family,
)
_delete_cookie_file(self._cookie_path, reason="assertnameduserfailed")
if self.use_cookies:
_delete_cookie_file(self._cookie_path, reason="assertnameduserfailed")
self._do_login()

# ------------------------------------------------------------------
Expand Down Expand Up @@ -561,14 +568,16 @@ def _ensure_logged_in(self) -> None:
if getattr(self._site, "logged_in", None):
logger.info(f"Session already authenticated {self._site.logged_in=}")
return
if self._cookie_path.exists():
try:
self._site.site_init()
if self._site.logged_in:
logger.info("Revived session via cookies as %s", self._site.username)
return
except Exception:
logger.exception("Error in site_init")

if self.use_cookies:
if self._cookie_path.exists():
try:
self._site.site_init()
if self._site.logged_in:
logger.info("Revived session via cookies as %s", self._site.username)
return
except Exception:
logger.exception("Error in site_init")

# if not self._site.logged_in: self._do_login()
# don't login yet, user can use login() method
Expand Down Expand Up @@ -611,16 +620,17 @@ def _do_login(self) -> None:
try:
self._site.login(self.username, self._password)
except mwclient.errors.LoginError as exc:
raise LoginError(f"login failed for {self.username} on {self.lang}.{self.family}: {exc}") from exc
raise LoginError(f"login failed for {self.username} on {self.lang}.{self.family}.org: {exc}") from exc

if self._site.logged_in:
logger.info(
"Logged in successfully as %s on %s.%s",
"Logged in successfully as %s on %s.%s.org",
self.username,
self.lang,
self.family,
)
self.save_cookies(self.cj)
if self.use_cookies:
self.save_cookies(self.cj)

# ── Public methods ─────────────────────────────────────────────────────

Expand All @@ -633,7 +643,7 @@ def login(self, force: bool = False) -> None:
"""
if force or not self._site.logged_in:
logger.info(
"Forcing re-login for %s on %s.%s",
"Forcing re-login for %s on %s.%s.org",
self.username,
self.lang,
self.family,
Expand Down Expand Up @@ -803,7 +813,7 @@ def post_continue(
logger.debug("Applying continue_params: %s", continue_params)
page_params.update(continue_params)

body = self.client_request(page_params)
body = self.client_request_safe(page_params)

if not body:
logger.debug("empty response, stopping")
Expand Down
11 changes: 10 additions & 1 deletion newapi/client_wiki/all_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ class AllAPIS:
new_api = main_api.NewApi()
"""

def __init__(self, lang: str, family: str, username: str, password: str) -> None:
def __init__(
self,
lang: str,
family: str,
username: str,
password: str,
use_cookies: bool = True,
) -> None:
self.lang = lang
self.family = family
self.username = username
self.password = password
self.use_cookies = use_cookies
self.login_bot = self._login()

def MainPage(self, title: str, *args, **kwargs) -> super_page.MainPage:
Expand All @@ -44,6 +52,7 @@ def _login(self) -> WikiLoginClient:
family=self.family,
username=self.username,
password=self.password,
use_cookies=self.use_cookies,
)
return client

Expand Down
2 changes: 1 addition & 1 deletion newapi/client_wiki/categories/category_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def get_cat_new(self, cac: str) -> dict:
if continue_params:
params.update(continue_params)

api_data = self.login_bot.client_request(params, method="get")
api_data = self.login_bot.client_request_safe(params, method="get")

if not api_data:
logger.info(f"api is False for {cac}")
Expand Down
30 changes: 15 additions & 15 deletions newapi/client_wiki/pages/super_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def import_page(self, family="wikipedia"):
"assignknownusers": 1,
}

data = self.client_request(params)
data = self.login_bot.client_request_safe(params)

done = data.get("import", [{}])[0].get("revisions", 0)

Expand Down Expand Up @@ -166,7 +166,7 @@ def find_create_data(self):
"rvdir": "newer",
}

data = self.login_bot.client_request(params, method="get")
data = self.login_bot.client_request_safe(params, method="get")

pages = data.get("query", {}).get("pages", {})

Expand Down Expand Up @@ -207,7 +207,7 @@ def get_text(self, redirects=False):

if redirects:
params["redirects"] = 1
data = self.login_bot.client_request(params, method="get")
data = self.login_bot.client_request_safe(params, method="get")

pages = data.get("query", {}).get("pages", {})

Expand Down Expand Up @@ -288,7 +288,7 @@ def get_infos(self):

# _data_ = { "continue": {}, "query": { "pages": { "9124097": { "pageid": 9124097, "ns": 0, "title": "طواف العالم للدراجات 2023", "categories": [], "langlinks": [], "templates": [{ "ns": 10, "title": "قالب:-" }], "linkshere": [{ "pageid": 189150, "ns": 0, "title": "طواف فرنسا" }], "iwlinks": [{ "prefix": "commons", "*": "Category:2023_UCI_World_Tour" }], "contentmodel": "wikitext", "pagelanguage": "ar", "pagelanguagehtmlcode": "ar", "pagelanguagedir": "rtl", "touched": "2023-03-07T11:53:53Z", "lastrevid": 61366100, "length": 985, } } }, }

data = self.login_bot.client_request(params, method="get")
data = self.login_bot.client_request_safe(params, method="get")

# xs = { 'batchcomplete': True, 'query': { 'pages': [{ 'pageid': 151314, 'ns': 10, 'title': 'قالب:أوب', 'categories': [{ 'ns': 14, 'title': 'تصنيف:قوالب تستخدم أنماط القوالب', 'sortkey': '', 'sortkeyprefix': '', 'hidden': False }, { 'ns': 14, 'title': 'تصنيف:cc', 'sortkey': 'v', 'sortkeyprefix': 'أوب', 'hidden': True }], 'langlinks': [{ 'lang': 'bh', 'title': 'टेम्पलेट:AWB' }], 'templates': [{ 'ns': 10, 'title': 'قالب:No redirect' }], 'linkshere': [{ 'pageid': 308641, 'ns': 10, 'title': 'قالب:AWB', 'redirect': True }], 'iwlinks': [{ 'prefix': 'd', 'title': 'Q4063270' }], 'contentmodel': 'wikitext', 'pagelanguage': 'ar', 'pagelanguagehtmlcode': 'ar', 'pagelanguagedir': 'rtl', 'touched': '2023-03-05T22:10:23Z', 'lastrevid': 61388266, 'length': 3477, }] }, }

Expand Down Expand Up @@ -351,7 +351,7 @@ def get_text_html(self):
"prop": "text",
}

data = self.client_request(params)
data = self.login_bot.client_request_safe(params)

# _data_ = { 'warnings': { 'main': { 'warnings': 'Unrecognized parameter: bot.' } }, 'parse': { 'title': 'ويكيبيديا:ملعب', 'pageid': 361534, 'text': '' } }

Expand All @@ -367,7 +367,7 @@ def get_redirect_target(self):
"redirects": 1,
}

data = self.login_bot.client_request(params, method="get")
data = self.login_bot.client_request_safe(params, method="get")

# _pages_ = { 'batchcomplete': '', 'query': { 'redirects': [{ 'from': 'Yemen', 'to': 'اليمن' }], 'pages': {}, 'normalized': [{ 'from': 'yemen', 'to': 'Yemen' }] } }

Expand All @@ -390,7 +390,7 @@ def get_words(self):
"srsearch": self.title,
"srlimit": srlimit,
}
data = self.client_request(params)
data = self.login_bot.client_request_safe(params)

if not data:
return 0
Expand Down Expand Up @@ -431,7 +431,7 @@ def get_extlinks(self):
# params = {**params, **continue_params}
params.update(continue_params)

json1 = self.login_bot.client_request(params, method="get")
json1 = self.login_bot.client_request_safe(params, method="get")

continue_params = json1.get("continue", {})

Expand All @@ -458,7 +458,7 @@ def get_userinfo(self):
"ususers": self.user,
}

data = self.login_bot.client_request(params, method="get")
data = self.login_bot.client_request_safe(params, method="get")

# _userinfo_ = { "id": 229481, "name": "Mr. Ibrahem", "groups": ["editor", "reviewer", "rollbacker", "*", "user", "autoconfirmed"] }

Expand Down Expand Up @@ -717,7 +717,7 @@ def save(

# params['basetimestamp'] = self.revisions_data.timestamp

pop = self.login_bot.client_request(params)
pop = self.login_bot.client_request_safe(params)

if not pop:
return False
Expand Down Expand Up @@ -759,7 +759,7 @@ def purge(self):
"titles": self.title,
}

data = self.client_request(params)
data = self.login_bot.client_request_safe(params)

if not data:
logger.info("<<lightred>> ** purge error. ")
Expand Down Expand Up @@ -835,7 +835,7 @@ def create(
"createonly": 1,
}

pop = self.login_bot.client_request(params)
pop = self.login_bot.client_request_safe(params)

if not pop:
return False
Expand Down Expand Up @@ -893,7 +893,7 @@ def page_backlinks(self, ns=0):

# x = { 'batchcomplete': True, 'limits': { 'backlinks': 2500 }, 'query': { 'redirects': [{ 'from': 'فريدريش زيمرمان', 'to': 'فريدريش تسيمرمان' }], 'pages': [{ 'pageid': 2941285, 'ns': 0, 'title': 'فولفغانغ شويبله' }, { 'pageid': 4783977, 'ns': 0, 'title': 'وزارة الشؤون الرقمية والنقل' }, { 'pageid': 5218323, 'ns': 0, 'title': 'فريدريش تسيمرمان' }, { 'pageid': 6662649, 'ns': 0, 'title': 'غونتر كراوزه' }] } }

# data = self.client_request(params)
# data = self.client_request_safe(params)
# pages = data.get("query", {}).get("pages", [])

pages = self.post_continue(params, "query", _p_="pages", p_empty=[])
Expand Down Expand Up @@ -921,7 +921,7 @@ def page_links(self) -> list:
"formatversion": "2",
"page": self.title,
}
# data = self.client_request(params)
# data = self.client_request_safe(params)
# data = data.get('parse', {}).get('links', [])

data: list = self.post_continue(params, "parse", _p_="links", p_empty=[])
Expand All @@ -942,7 +942,7 @@ def page_links_query(self, plnamespace="*"):
"pllimit": "max",
"converttitles": 1,
}
# data = self.client_request(params)
# data = self.client_request_safe(params)
# data = data.get('query', {}).get('links', [])

data = self.post_continue(params, "query", _p_="links", p_empty=[])
Expand Down
Loading
Loading