Skip to content

Commit feec4fa

Browse files
committed
Add generic pagination utils
1 parent 1b2ff61 commit feec4fa

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

cloudbot/util/pager.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from threading import RLock
2+
3+
4+
class Pager:
5+
"""Multiline pager
6+
7+
Takes a string with newlines and paginates it to certain size chunks
8+
"""
9+
10+
@classmethod
11+
def from_multiline_string(cls, s):
12+
return cls(s.splitlines())
13+
14+
def __init__(self, lines, chunk_size=2):
15+
# This lock should always be acquired when accessing data from this object
16+
# Added here due to extensive use of threads throughout plugins
17+
self.lock = RLock()
18+
self.chunk_size = chunk_size
19+
self.chunks = tuple(
20+
lines[i:i + self.chunk_size]
21+
for i in range(0, len(lines), self.chunk_size)
22+
)
23+
self.current_pos = 0
24+
25+
def format_chunk(self, chunk, pagenum):
26+
chunk = list(chunk)
27+
if len(self.chunks) > 1:
28+
chunk[-1] += " (page {}/{})".format(pagenum + 1, len(self.chunks))
29+
return chunk
30+
31+
def next(self):
32+
with self.lock:
33+
if self.current_pos > len(self.chunks):
34+
return None
35+
36+
chunk = self[self.current_pos]
37+
self.current_pos += 1
38+
return chunk
39+
40+
def get(self, index):
41+
"""Get a specific page"""
42+
return self[index]
43+
44+
def __getitem__(self, item):
45+
"""Get a specific page"""
46+
with self.lock:
47+
chunk = self.chunks[item]
48+
return self.format_chunk(chunk, item)
49+
50+
def __len__(self):
51+
with self.lock:
52+
return len(self.chunks)
53+
54+
55+
def paginated_list(data, delim=" \u2022 ", suffix='...', max_len=256, page_size=2):
56+
lines = [""]
57+
for item in data:
58+
if len(item) > max_len:
59+
# The length of a single item is longer then our max line length, split it
60+
lines.append(item[:max_len])
61+
lines.append(item[max_len:])
62+
elif len(lines[-1]) + len(item) > max_len:
63+
lines.append(item)
64+
else:
65+
if lines[-1]:
66+
lines[-1] += delim
67+
68+
lines[-1] += item
69+
70+
formatted_lines = [
71+
"{}{}".format(line, suffix) for line in lines
72+
]
73+
return Pager(formatted_lines, chunk_size=page_size)

0 commit comments

Comments
 (0)