Skip to content
Merged
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
59 changes: 59 additions & 0 deletions src/osw/wtsite.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,24 @@ def from_credentials(
site = wt.create_site_object(_domain, "", _credentials)
return cls(WtSite.WtSiteLegacyConfig(site=site))

def try_and_renew_token(func):
""" "Tries to execute the method call. If the auth token has expired already,
the token is renewed and the method call is retried.

This decorator should be used closest to to the funciton definition (before
any other decorator).
"""

def wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except mwclient.errors.APIError:
# Refresh token for longer taking processes
self._site.get_token("csrf", force=True)
return func(self, *args, **kwargs)

return wrapper

class GetPageParam(OswBaseModel):
titles: Union[str, List[str]]
"""title string or list of title strings of the pages to download"""
Expand Down Expand Up @@ -252,6 +270,7 @@ class GetPageResult(OswBaseModel):
class Config:
arbitrary_types_allowed = True # allows to use WtPage in type hints

@try_and_renew_token
def get_page(self, param: GetPageParam) -> GetPageResult:
"""Downloads a page or a list of pages from the site.

Expand Down Expand Up @@ -319,6 +338,7 @@ def get_page_(title: str, index: int = None):
return self.GetPageResult(pages=pages, errors=exceptions)

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

@try_and_renew_token
def get_page_content(self, full_page_titles: List[str]) -> GetPageContentResult:
get_page_res = self.get_page(WtSite.GetPageParam(titles=full_page_titles))
contents_dict = {}
Expand Down Expand Up @@ -395,6 +416,7 @@ def _clear_cookies(self):
class SearchParam(wt.SearchParam):
pass

@try_and_renew_token
def prefix_search(self, text: Union[str, SearchParam]):
"""Send a prefix search request to the site.

Expand All @@ -409,6 +431,7 @@ def prefix_search(self, text: Union[str, SearchParam]):
"""
return wt.prefix_search(self._site, text)

@try_and_renew_token
def semantic_search(self, query: Union[str, SearchParam]):
"""Send a swm ask query to the site.

Expand Down Expand Up @@ -437,6 +460,7 @@ class ModifySearchResultsParam(OswBaseModel):
dryrun: bool = False
"""if True, no actual changes are made"""

@try_and_renew_token
def modify_search_results(
self,
mode: str,
Expand Down Expand Up @@ -512,6 +536,7 @@ def __init__(self, **data):
if self.parallel is None:
self.parallel = False

@try_and_renew_token
def upload_page(
self,
param: Union[UploadPageParam, "WtPage", List["WtPage"]],
Expand Down Expand Up @@ -579,6 +604,7 @@ def __init__(self, **data):
if self.parallel is None:
self.parallel = False

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

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

@try_and_renew_token
def delete_page(
self,
param: Union["WtPage", List["WtPage"], str, List[str], DeletePageParam],
Expand Down Expand Up @@ -697,6 +724,7 @@ class CreatePagePackageParam(OswBaseModel):
class Config:
arbitrary_types_allowed = True

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

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

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

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

@try_and_renew_token
def get_file_info_and_usage(
self,
page_titles: Union[str, List[str], SearchParam],
Expand Down Expand Up @@ -1156,6 +1188,7 @@ def _replace_jsonld_context_mapping(
)
return context

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

def try_and_renew_token(func):
"""Tries to execute the method call. If the auth token has expired already,
the token is renewed and the method call is retried.

This decorator should be used closest to to the funciton definition (before
any other decorator).
"""

def wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except mwclient.errors.APIError:
# Refresh token for longer taking processes
self.wtSite._site.get_token("csrf", force=True)
return func(self, *args, **kwargs)

return wrapper

def parse_main_slot(self):
"""Parses the main slot content of the page
Requires wikitext dependencies installed with 'pip install osw[wikitext]'
Expand Down Expand Up @@ -1646,6 +1697,7 @@ def _edit(
if changed:
self.changed = True

@try_and_renew_token
def delete(self, comment: str = None):
"""Deletes the page from the site

Expand All @@ -1656,6 +1708,7 @@ def delete(self, comment: str = None):
"""
self._page.delete(comment)

@try_and_renew_token
def move(self, new_title: str, comment: str = None, redirect: bool = True):
"""Moves (=renames) the page to a new title

Expand Down Expand Up @@ -1713,6 +1766,7 @@ class PageCopyResult(OswBaseModel):
class Config:
arbitrary_types_allowed = True

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

return package_page

@try_and_renew_token
def get_file_info_and_usage(
self, debug: bool = False
) -> Dict[str, Union[str, List[str]]]:
Expand All @@ -1894,6 +1949,7 @@ def get_file_info_and_usage(
title=wt.SearchParam(query=self.title, debug=debug),
)[0]

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

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

@try_and_renew_token
def export_xml(self, config: Optional[ExportConfig] = None) -> ExportResult:
"""Exports the page to XML

Expand Down Expand Up @@ -2035,6 +2093,7 @@ class ImportResult(OswBaseModel):
imported_revisions: int
error_msg: Optional[str] = None

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

Expand Down
Loading