Skip to content

Commit 32d93db

Browse files
committed
2 parents 3430622 + 9ff5688 commit 32d93db

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

src/osw/wtsite.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,24 @@ def from_credentials(
217217
site = wt.create_site_object(_domain, "", _credentials)
218218
return cls(WtSite.WtSiteLegacyConfig(site=site))
219219

220+
def try_and_renew_token(func):
221+
""" "Tries to execute the method call. If the auth token has expired already,
222+
the token is renewed and the method call is retried.
223+
224+
This decorator should be used closest to to the funciton definition (before
225+
any other decorator).
226+
"""
227+
228+
def wrapper(self, *args, **kwargs):
229+
try:
230+
return func(self, *args, **kwargs)
231+
except mwclient.errors.APIError:
232+
# Refresh token for longer taking processes
233+
self._site.get_token("csrf", force=True)
234+
return func(self, *args, **kwargs)
235+
236+
return wrapper
237+
220238
class GetPageParam(OswBaseModel):
221239
titles: Union[str, List[str]]
222240
"""title string or list of title strings of the pages to download"""
@@ -252,6 +270,7 @@ class GetPageResult(OswBaseModel):
252270
class Config:
253271
arbitrary_types_allowed = True # allows to use WtPage in type hints
254272

273+
@try_and_renew_token
255274
def get_page(self, param: GetPageParam) -> GetPageResult:
256275
"""Downloads a page or a list of pages from the site.
257276
@@ -319,6 +338,7 @@ def get_page_(title: str, index: int = None):
319338
return self.GetPageResult(pages=pages, errors=exceptions)
320339

321340
@deprecated("Use get_page instead")
341+
@try_and_renew_token
322342
def get_WtPage(self, title: str = None):
323343
"""Creates a new WtPage object for the given title
324344
and loads the page from the site if the page already exists.
@@ -341,6 +361,7 @@ class GetPageContentResult(OswBaseModel):
341361
class Config:
342362
arbitrary_types_allowed = True
343363

364+
@try_and_renew_token
344365
def get_page_content(self, full_page_titles: List[str]) -> GetPageContentResult:
345366
get_page_res = self.get_page(WtSite.GetPageParam(titles=full_page_titles))
346367
contents_dict = {}
@@ -395,6 +416,7 @@ def _clear_cookies(self):
395416
class SearchParam(wt.SearchParam):
396417
pass
397418

419+
@try_and_renew_token
398420
def prefix_search(self, text: Union[str, SearchParam]):
399421
"""Send a prefix search request to the site.
400422
@@ -409,6 +431,7 @@ def prefix_search(self, text: Union[str, SearchParam]):
409431
"""
410432
return wt.prefix_search(self._site, text)
411433

434+
@try_and_renew_token
412435
def semantic_search(self, query: Union[str, SearchParam]):
413436
"""Send a swm ask query to the site.
414437
@@ -437,6 +460,7 @@ class ModifySearchResultsParam(OswBaseModel):
437460
dryrun: bool = False
438461
"""if True, no actual changes are made"""
439462

463+
@try_and_renew_token
440464
def modify_search_results(
441465
self,
442466
mode: str,
@@ -512,6 +536,7 @@ def __init__(self, **data):
512536
if self.parallel is None:
513537
self.parallel = False
514538

539+
@try_and_renew_token
515540
def upload_page(
516541
self,
517542
param: Union[UploadPageParam, "WtPage", List["WtPage"]],
@@ -579,6 +604,7 @@ def __init__(self, **data):
579604
if self.parallel is None:
580605
self.parallel = False
581606

607+
@try_and_renew_token
582608
def copy_pages(self, param: CopyPagesParam):
583609
"""Copies pages from a source site to this (target) site."""
584610

@@ -626,6 +652,7 @@ def __init__(self, **data):
626652
if len(self.page) > 5 and self.parallel is None:
627653
self.parallel = True
628654

655+
@try_and_renew_token
629656
def delete_page(
630657
self,
631658
param: Union["WtPage", List["WtPage"], str, List[str], DeletePageParam],
@@ -697,6 +724,7 @@ class CreatePagePackageParam(OswBaseModel):
697724
class Config:
698725
arbitrary_types_allowed = True
699726

727+
@try_and_renew_token
700728
def create_page_package(self, param: CreatePagePackageParam):
701729
"""Create a page package, which is a locally stored collection of wiki pages
702730
and their slots, based on a configuration object.
@@ -858,6 +886,7 @@ class ReadPagePackageResult(OswBaseModel):
858886
class Config:
859887
arbitrary_types_allowed = True
860888

889+
@try_and_renew_token
861890
def read_page_package(self, param: ReadPagePackageParam) -> ReadPagePackageResult:
862891
"""Read a page package, which is a locally stored collection of wiki pages and
863892
their slots' content.
@@ -1007,6 +1036,7 @@ class UploadPagePackageParam(OswBaseModel):
10071036
class Config:
10081037
arbitrary_types_allowed = True
10091038

1039+
@try_and_renew_token
10101040
def upload_page_package(self, param: UploadPagePackageParam):
10111041
"""Uploads a page package to the wiki defined by a list of WtPage objects or
10121042
a storage path.
@@ -1031,6 +1061,7 @@ def upload_page_package(self, param: UploadPagePackageParam):
10311061
for page in pages:
10321062
page.edit()
10331063

1064+
@try_and_renew_token
10341065
def get_file_pages(self, limit: int = 1000000) -> List[str]:
10351066
"""Get all file pages in the wiki"""
10361067
full_page_titles = wt.prefix_search(
@@ -1039,6 +1070,7 @@ def get_file_pages(self, limit: int = 1000000) -> List[str]:
10391070
)
10401071
return full_page_titles
10411072

1073+
@try_and_renew_token
10421074
def get_file_info_and_usage(
10431075
self,
10441076
page_titles: Union[str, List[str], SearchParam],
@@ -1156,6 +1188,7 @@ def _replace_jsonld_context_mapping(
11561188
)
11571189
return context
11581190

1191+
@try_and_renew_token
11591192
def get_jsonld_context_loader(self, params: JsonLdContextLoaderParams = None):
11601193
if params is None:
11611194
params = self.JsonLdContextLoaderParams()
@@ -1275,6 +1308,24 @@ def init(self):
12751308
# todo: set content for slots not in revision["slots"] (use
12761309
# SLOTS) --> create empty slots
12771310

1311+
def try_and_renew_token(func):
1312+
"""Tries to execute the method call. If the auth token has expired already,
1313+
the token is renewed and the method call is retried.
1314+
1315+
This decorator should be used closest to to the funciton definition (before
1316+
any other decorator).
1317+
"""
1318+
1319+
def wrapper(self, *args, **kwargs):
1320+
try:
1321+
return func(self, *args, **kwargs)
1322+
except mwclient.errors.APIError:
1323+
# Refresh token for longer taking processes
1324+
self.wtSite._site.get_token("csrf", force=True)
1325+
return func(self, *args, **kwargs)
1326+
1327+
return wrapper
1328+
12781329
def parse_main_slot(self):
12791330
"""Parses the main slot content of the page
12801331
Requires wikitext dependencies installed with 'pip install osw[wikitext]'
@@ -1646,6 +1697,7 @@ def _edit(
16461697
if changed:
16471698
self.changed = True
16481699

1700+
@try_and_renew_token
16491701
def delete(self, comment: str = None):
16501702
"""Deletes the page from the site
16511703
@@ -1656,6 +1708,7 @@ def delete(self, comment: str = None):
16561708
"""
16571709
self._page.delete(comment)
16581710

1711+
@try_and_renew_token
16591712
def move(self, new_title: str, comment: str = None, redirect: bool = True):
16601713
"""Moves (=renames) the page to a new title
16611714
@@ -1713,6 +1766,7 @@ class PageCopyResult(OswBaseModel):
17131766
class Config:
17141767
arbitrary_types_allowed = True
17151768

1769+
@try_and_renew_token
17161770
def copy(self, config: CopyPageConfig) -> PageCopyResult:
17171771
if config.comment is None:
17181772
config.comment = f"[bot edit] Copied from {config.source_site.mw_site.host}"
@@ -1874,6 +1928,7 @@ def dump_slot_content(slot_key_, content_type_, content_):
18741928

18751929
return package_page
18761930

1931+
@try_and_renew_token
18771932
def get_file_info_and_usage(
18781933
self, debug: bool = False
18791934
) -> Dict[str, Union[str, List[str]]]:
@@ -1894,6 +1949,7 @@ def get_file_info_and_usage(
18941949
title=wt.SearchParam(query=self.title, debug=debug),
18951950
)[0]
18961951

1952+
@try_and_renew_token
18971953
def find_file_page_refs_in_slots(self, slots: List[str] = None) -> List[str]:
18981954
"""Find all file page references in the content of the given slots."""
18991955
if slots is None:
@@ -1939,6 +1995,7 @@ def find_file_page_refs_in_slots(self, slots: List[str] = None) -> List[str]:
19391995
print("Warning: Error while parsing uuid in editor template")
19401996
return list(set(file_page_refs))
19411997

1998+
@try_and_renew_token
19421999
def purge(self):
19432000
"""Purge the page from the site cache.
19442001
Triggers a rebuild / refresh of the page.
@@ -1962,6 +2019,7 @@ class ExportResult(OswBaseModel):
19622019
success: bool
19632020
"""if true, the export was successful, else false"""
19642021

2022+
@try_and_renew_token
19652023
def export_xml(self, config: Optional[ExportConfig] = None) -> ExportResult:
19662024
"""Exports the page to XML
19672025
@@ -2035,6 +2093,7 @@ class ImportResult(OswBaseModel):
20352093
imported_revisions: int
20362094
error_msg: Optional[str] = None
20372095

2096+
@try_and_renew_token
20382097
def import_xml(self, config: ImportConfig) -> ImportResult:
20392098
"""Imports the page from an XML export
20402099

0 commit comments

Comments
 (0)