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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Set up documentation using `mkdocs`, published on readthedocs.com (#186)
- `Archive.get_random_entry()`

## [3.6.0] - 2024-10-15

Expand Down
1 change: 1 addition & 0 deletions libzim/libwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class Archive : public Wrapper<zim::Archive>
FORWARD(wrapper::Entry, getEntryByPath)
FORWARD(wrapper::Entry, getEntryByTitle)
FORWARD(wrapper::Entry, getMainEntry)
FORWARD(wrapper::Entry, getRandomEntry)
FORWARD(wrapper::Item, getIllustrationItem)
FORWARD(std::set<unsigned int>, getIllustrationSizes)
std::string getUuid() const
Expand Down
15 changes: 15 additions & 0 deletions libzim/libzim.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,21 @@ cdef class Archive:
raise KeyError(str(e))
return Entry.from_entry(move(entry))

def get_random_entry(self) -> Entry:
"""Get a random `Entry`.

Returns:
A random entry.

Raises:
KeyError: If no valid random entry is found.
"""
try:
entry = move(self.c_archive.getRandomEntry())
except RuntimeError as e:
raise KeyError(str(e))
return Entry.from_entry(move(entry))

@property
def metadata_keys(self) -> List[str]:
"""List of Metadata keys present in this archive.
Expand Down
1 change: 1 addition & 0 deletions libzim/reader.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Archive:
def get_entry_by_path(self, path: str) -> Entry: ...
def has_entry_by_title(self, title: str) -> bool: ...
def get_entry_by_title(self, title: str) -> Entry: ...
def get_random_entry(self) -> Entry: ...
@property
def metadata_keys(self) -> list[str]: ...
def get_metadata_item(self, name: str) -> Item: ...
Expand Down
1 change: 1 addition & 0 deletions libzim/zim.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ cdef extern from "libwrapper.h" namespace "wrapper":
vector[string] getMetadataKeys() except +

Entry getMainEntry() except +
Entry getRandomEntry() except +
Item getIllustrationItem() except +
Item getIllustrationItem(int size) except +
size_type getEntryCount() except +
Expand Down
18 changes: 17 additions & 1 deletion tests/test_libzim_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import pytest

import libzim.writer # pyright: ignore [reportMissingModuleSource]
from libzim.reader import Archive # pyright: ignore [reportMissingModuleSource]
from libzim.reader import Archive, Entry # pyright: ignore [reportMissingModuleSource]
from libzim.search import Query, Searcher # pyright: ignore [reportMissingModuleSource]
from libzim.suggestion import ( # pyright: ignore [reportMissingModuleSource]
SuggestionSearcher,
Expand Down Expand Up @@ -599,3 +599,19 @@ def filename(self):
assert zim != Different(fpath1)
assert zim == Sub(fpath1)
assert zim != Sub2(fpath1)


def test_reader_get_random_entry(all_zims):
zim_1 = Archive(all_zims / "zimfile.zim")

entry_1 = zim_1.get_random_entry()
entry_2 = zim_1.get_random_entry()
assert isinstance(entry_1, Entry)
assert isinstance(entry_2, Entry)
# this may occasionaly fail (1 chance over 129)
assert entry_1 != entry_2

# example.zim has no FRONT_ARTICLE (article_count=0): random cannot yield any result
zim_2 = Archive(all_zims / "example.zim")
with pytest.raises(KeyError):
zim_2.get_random_entry()