mirror of
https://github.com/Garmelon/PFERD.git
synced 2023-12-21 10:23:01 +01:00
Crawl files in the info tab
This commit is contained in:
parent
b54b3b979c
commit
87b67e9271
@ -36,6 +36,7 @@ ambiguous situations.
|
|||||||
message. This combines nicely with the `no-delete-prompt-override` strategy,
|
message. This combines nicely with the `no-delete-prompt-override` strategy,
|
||||||
causing PFERD to mostly ignore local-only files.
|
causing PFERD to mostly ignore local-only files.
|
||||||
- support for mediacast video listings
|
- support for mediacast video listings
|
||||||
|
- crawling of files in info tab
|
||||||
|
|
||||||
## 3.4.3 - 2022-11-29
|
## 3.4.3 - 2022-11-29
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ class IliasElementType(Enum):
|
|||||||
FOLDER = "folder"
|
FOLDER = "folder"
|
||||||
FORUM = "forum"
|
FORUM = "forum"
|
||||||
LINK = "link"
|
LINK = "link"
|
||||||
|
INFO_TAB = "info_tab"
|
||||||
LEARNING_MODULE = "learning_module"
|
LEARNING_MODULE = "learning_module"
|
||||||
BOOKING = "booking"
|
BOOKING = "booking"
|
||||||
MEETING = "meeting"
|
MEETING = "meeting"
|
||||||
@ -120,9 +121,25 @@ class IliasPage:
|
|||||||
if self._is_content_page():
|
if self._is_content_page():
|
||||||
log.explain("Page is a content page, searching for elements")
|
log.explain("Page is a content page, searching for elements")
|
||||||
return self._find_copa_entries()
|
return self._find_copa_entries()
|
||||||
|
if self._is_info_tab():
|
||||||
|
log.explain("Page is info tab, searching for elements")
|
||||||
|
return self._find_info_tab_entries()
|
||||||
log.explain("Page is a normal folder, searching for elements")
|
log.explain("Page is a normal folder, searching for elements")
|
||||||
return self._find_normal_entries()
|
return self._find_normal_entries()
|
||||||
|
|
||||||
|
def get_info_tab(self) -> Optional[IliasPageElement]:
|
||||||
|
tab: Optional[Tag] = self._soup.find(
|
||||||
|
name="a",
|
||||||
|
attrs={"href": lambda x: x and "cmdClass=ilinfoscreengui" in x}
|
||||||
|
)
|
||||||
|
if tab is not None:
|
||||||
|
return IliasPageElement(
|
||||||
|
IliasElementType.INFO_TAB,
|
||||||
|
self._abs_url_from_link(tab),
|
||||||
|
"infos"
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
def get_description(self) -> Optional[BeautifulSoup]:
|
def get_description(self) -> Optional[BeautifulSoup]:
|
||||||
def is_interesting_class(name: str) -> bool:
|
def is_interesting_class(name: str) -> bool:
|
||||||
return name in ["ilCOPageSection", "ilc_Paragraph", "ilc_va_ihcap_VAccordIHeadCap"]
|
return name in ["ilCOPageSection", "ilc_Paragraph", "ilc_va_ihcap_VAccordIHeadCap"]
|
||||||
@ -209,7 +226,11 @@ class IliasPage:
|
|||||||
log.explain("Requesting *all* future meetings")
|
log.explain("Requesting *all* future meetings")
|
||||||
return self._uncollapse_future_meetings_url()
|
return self._uncollapse_future_meetings_url()
|
||||||
if not self._is_content_tab_selected():
|
if not self._is_content_tab_selected():
|
||||||
return self._select_content_page_url()
|
if self._page_type != IliasElementType.INFO_TAB:
|
||||||
|
log.explain("Selecting content tab")
|
||||||
|
return self._select_content_page_url()
|
||||||
|
else:
|
||||||
|
log.explain("Crawling info tab, skipping content select")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _is_forum_page(self) -> bool:
|
def _is_forum_page(self) -> bool:
|
||||||
@ -281,6 +302,10 @@ class IliasPage:
|
|||||||
def _is_content_tab_selected(self) -> bool:
|
def _is_content_tab_selected(self) -> bool:
|
||||||
return self._select_content_page_url() is None
|
return self._select_content_page_url() is None
|
||||||
|
|
||||||
|
def _is_info_tab(self) -> bool:
|
||||||
|
might_be_info = self._soup.find("form", attrs={"name": lambda x: x == "formInfoScreen"}) is not None
|
||||||
|
return self._page_type == IliasElementType.INFO_TAB and might_be_info
|
||||||
|
|
||||||
def _select_content_page_url(self) -> Optional[IliasPageElement]:
|
def _select_content_page_url(self) -> Optional[IliasPageElement]:
|
||||||
tab = self._soup.find(
|
tab = self._soup.find(
|
||||||
id="tab_view_content",
|
id="tab_view_content",
|
||||||
@ -389,6 +414,23 @@ class IliasPage:
|
|||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
def _find_info_tab_entries(self) -> List[IliasPageElement]:
|
||||||
|
items = []
|
||||||
|
links: List[Tag] = self._soup.select("a.il_ContainerItemCommand")
|
||||||
|
|
||||||
|
for link in links:
|
||||||
|
if "cmdClass=ilobjcoursegui" not in link["href"]:
|
||||||
|
continue
|
||||||
|
if "cmd=sendfile" not in link["href"]:
|
||||||
|
continue
|
||||||
|
items.append(IliasPageElement(
|
||||||
|
IliasElementType.FILE,
|
||||||
|
self._abs_url_from_link(link),
|
||||||
|
_sanitize_path_name(link.getText())
|
||||||
|
))
|
||||||
|
|
||||||
|
return items
|
||||||
|
|
||||||
def _find_opencast_video_entries(self) -> List[IliasPageElement]:
|
def _find_opencast_video_entries(self) -> List[IliasPageElement]:
|
||||||
# ILIAS has three stages for video pages
|
# ILIAS has three stages for video pages
|
||||||
# 1. The initial dummy page without any videos. This page contains the link to the listing
|
# 1. The initial dummy page without any videos. This page contains the link to the listing
|
||||||
|
@ -85,6 +85,7 @@ _DIRECTORY_PAGES: Set[IliasElementType] = set([
|
|||||||
IliasElementType.EXERCISE,
|
IliasElementType.EXERCISE,
|
||||||
IliasElementType.EXERCISE_FILES,
|
IliasElementType.EXERCISE_FILES,
|
||||||
IliasElementType.FOLDER,
|
IliasElementType.FOLDER,
|
||||||
|
IliasElementType.INFO_TAB,
|
||||||
IliasElementType.MEETING,
|
IliasElementType.MEETING,
|
||||||
IliasElementType.MEDIACAST_VIDEO_FOLDER,
|
IliasElementType.MEDIACAST_VIDEO_FOLDER,
|
||||||
IliasElementType.OPENCAST_VIDEO_FOLDER,
|
IliasElementType.OPENCAST_VIDEO_FOLDER,
|
||||||
@ -262,6 +263,8 @@ instance's greatest bottleneck.
|
|||||||
next_stage_url = None
|
next_stage_url = None
|
||||||
|
|
||||||
elements.extend(page.get_child_elements())
|
elements.extend(page.get_child_elements())
|
||||||
|
if info_tab := page.get_info_tab():
|
||||||
|
elements.append(info_tab)
|
||||||
if description_string := page.get_description():
|
if description_string := page.get_description():
|
||||||
description.append(description_string)
|
description.append(description_string)
|
||||||
|
|
||||||
@ -705,7 +708,7 @@ instance's greatest bottleneck.
|
|||||||
log.explain(f"URL: {next_stage_url}")
|
log.explain(f"URL: {next_stage_url}")
|
||||||
|
|
||||||
soup = await self._get_page(next_stage_url)
|
soup = await self._get_page(next_stage_url)
|
||||||
page = IliasPage(soup, next_stage_url, None)
|
page = IliasPage(soup, next_stage_url, element)
|
||||||
|
|
||||||
if next := page.get_next_stage_element():
|
if next := page.get_next_stage_element():
|
||||||
next_stage_url = next.url
|
next_stage_url = next.url
|
||||||
@ -768,14 +771,14 @@ instance's greatest bottleneck.
|
|||||||
log.explain_topic(f"Parsing initial HTML page for {fmt_path(cl.path)}")
|
log.explain_topic(f"Parsing initial HTML page for {fmt_path(cl.path)}")
|
||||||
log.explain(f"URL: {element.url}")
|
log.explain(f"URL: {element.url}")
|
||||||
soup = await self._get_page(element.url)
|
soup = await self._get_page(element.url)
|
||||||
page = IliasPage(soup, element.url, None)
|
page = IliasPage(soup, element.url, element)
|
||||||
if next := page.get_learning_module_data():
|
if next := page.get_learning_module_data():
|
||||||
elements.extend(await self._crawl_learning_module_direction(
|
elements.extend(await self._crawl_learning_module_direction(
|
||||||
cl.path, next.previous_url, "left"
|
cl.path, next.previous_url, "left", element
|
||||||
))
|
))
|
||||||
elements.append(next)
|
elements.append(next)
|
||||||
elements.extend(await self._crawl_learning_module_direction(
|
elements.extend(await self._crawl_learning_module_direction(
|
||||||
cl.path, next.next_url, "right"
|
cl.path, next.next_url, "right", element
|
||||||
))
|
))
|
||||||
|
|
||||||
# Reflect their natural ordering in the file names
|
# Reflect their natural ordering in the file names
|
||||||
@ -797,7 +800,8 @@ instance's greatest bottleneck.
|
|||||||
self,
|
self,
|
||||||
path: PurePath,
|
path: PurePath,
|
||||||
start_url: Optional[str],
|
start_url: Optional[str],
|
||||||
dir: Union[Literal["left"], Literal["right"]]
|
dir: Union[Literal["left"], Literal["right"]],
|
||||||
|
parent_element: IliasPageElement
|
||||||
) -> List[IliasLearningModulePage]:
|
) -> List[IliasLearningModulePage]:
|
||||||
elements: List[IliasLearningModulePage] = []
|
elements: List[IliasLearningModulePage] = []
|
||||||
|
|
||||||
@ -810,7 +814,7 @@ instance's greatest bottleneck.
|
|||||||
log.explain_topic(f"Parsing HTML page for {fmt_path(path)} ({dir}-{counter})")
|
log.explain_topic(f"Parsing HTML page for {fmt_path(path)} ({dir}-{counter})")
|
||||||
log.explain(f"URL: {next_element_url}")
|
log.explain(f"URL: {next_element_url}")
|
||||||
soup = await self._get_page(next_element_url)
|
soup = await self._get_page(next_element_url)
|
||||||
page = IliasPage(soup, next_element_url, None)
|
page = IliasPage(soup, next_element_url, parent_element)
|
||||||
if next := page.get_learning_module_data():
|
if next := page.get_learning_module_data():
|
||||||
elements.append(next)
|
elements.append(next)
|
||||||
if dir == "left":
|
if dir == "left":
|
||||||
|
Loading…
Reference in New Issue
Block a user