Commit | Line | Data |
---|---|---|
f3ad0817 | 1 | class library(object): |
6a1e046b FT |
2 | """Class representing a single source of multiple mangas.""" |
3 | ||
4 | def byname(self, prefix): | |
5 | """Returns an iterable object of all mangas in this library | |
6 | whose names (case-insensitively) begin with the given | |
7 | prefix. | |
8 | ||
9 | All libraries should implement this.""" | |
10 | raise NotImplementedError() | |
11 | ||
12 | def __iter__(self): | |
13 | """Return an iterator of all known mangas in this library. | |
14 | ||
15 | Not all libraries need implement this.""" | |
16 | raise NotImplementedError("manga.lib.library iterator") | |
f3ad0817 | 17 | |
3683ab38 FT |
18 | class pagetree(object): |
19 | """Base class for objects in the tree of pages and pagelists. | |
20 | ||
21 | All pagetree objects should contain an attribute `stack', contains | |
22 | a list of pairs. The last pair in the list should be the pagetree | |
23 | object which yielded this pagetree object, along with the index | |
24 | which yielded it. Every non-last pair should be the same | |
25 | information for the pair following it. The only objects with empty | |
26 | `stack' lists should be `manga' objects.""" | |
27 | pass | |
28 | ||
29 | class pagelist(pagetree): | |
6a1e046b FT |
30 | """Class representing a list of either pages, or nested |
31 | pagelists. Might be, for instance, a volume or a chapter. | |
32 | ||
33 | All pagelists should contain an attribute `name', containing some | |
34 | human-readable Unicode representation of the pagelist.""" | |
35 | ||
36 | def __len__(self): | |
37 | """Return the number of (direct) sub-nodes in this pagelist. | |
38 | ||
39 | All pagelists need to implement this.""" | |
40 | raise NotImplementedError() | |
41 | ||
42 | def __getitem__(self, idx): | |
43 | """Return the direct sub-node of the given index in this | |
44 | pagelist. Sub-node indexes are always zero-based and | |
45 | contiguous, regardless of any gaps in the underlying medium, | |
46 | which should be indicated instead by way of the `name' | |
47 | attribute. | |
48 | ||
49 | All pagelists need to implement this.""" | |
50 | raise NotImplementedError() | |
f3ad0817 FT |
51 | |
52 | class manga(pagelist): | |
6a1e046b FT |
53 | """Class reprenting a single manga. Includes the pagelist class, |
54 | and all constraints valid for it.""" | |
f3ad0817 FT |
55 | pass |
56 | ||
3683ab38 | 57 | class page(pagetree): |
6a1e046b FT |
58 | """Class representing a single page of a manga. Pages make up the |
59 | leaf nodes of a pagelist tree. | |
60 | ||
61 | All pages should contain an attribute `manga', referring back to | |
62 | the containing manga instance.""" | |
63 | ||
64 | def open(self): | |
65 | """Open a stream for the image this page represents. The | |
66 | returned object should be an imgstream class. | |
67 | ||
68 | All pages need to implement this.""" | |
69 | raise NotImplementedError() | |
70 | ||
71 | class imgstream(object): | |
72 | """An open image I/O stream for a manga page. Generally, it should | |
73 | be file-like. This base class implements the resource-manager | |
74 | interface for use in `with' statements, calling close() on itself | |
75 | when exiting the with-scope. | |
76 | ||
77 | All imgstreams should contain an attribute `ctype', being the | |
78 | Content-Type of the image being read by the stream.""" | |
79 | ||
80 | def __enter__(self): | |
81 | return self | |
82 | ||
83 | def __exit__(self, *exc_info): | |
84 | self.close() | |
85 | ||
86 | def close(self): | |
87 | """Close this stream.""" | |
88 | raise NotImplementedError() | |
89 | ||
90 | def read(self, sz = None): | |
91 | """Read SZ bytes from the stream, or the entire rest of the | |
92 | stream of SZ is not given.""" | |
93 | raise NotImplementedError() | |
07be272b | 94 | |
055ad3fd FT |
95 | class cursor(object): |
96 | def __init__(self, ob): | |
97 | self.cur = self.descend(ob) | |
98 | ||
99 | def descend(self, ob): | |
100 | while isinstance(ob, pagelist): | |
101 | ob = ob[0] | |
102 | if not isinstance(ob, page): | |
103 | raise TypeError("object in page tree was unexpectedly not a pagetree") | |
104 | return ob | |
07be272b FT |
105 | |
106 | def next(self): | |
055ad3fd FT |
107 | for n, i in reversed(self.cur.stack): |
108 | if i < len(n) - 1: | |
109 | self.cur = self.descend(n[i + 1]) | |
110 | return self.cur | |
111 | raise StopIteration() | |
112 | ||
113 | def prev(self): | |
114 | for n, i in reversed(self.cur,stack): | |
115 | if i > 0: | |
116 | self.cur = self.descend(n[i - 1]) | |
117 | return self.cur | |
118 | raise StopIteration() | |
07be272b FT |
119 | |
120 | def __iter__(self): | |
121 | return self |