Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / fanfix / reader / CliReader.java
1 package be.nikiroo.fanfix.reader;
2
3 import java.io.IOException;
4 import java.util.List;
5
6 import be.nikiroo.fanfix.Instance;
7 import be.nikiroo.fanfix.bundles.StringId;
8 import be.nikiroo.fanfix.data.Chapter;
9 import be.nikiroo.fanfix.data.MetaData;
10 import be.nikiroo.fanfix.data.Paragraph;
11 import be.nikiroo.fanfix.data.Story;
12 import be.nikiroo.fanfix.searchable.BasicSearchable;
13 import be.nikiroo.fanfix.searchable.SearchableTag;
14 import be.nikiroo.fanfix.supported.SupportType;
15 import be.nikiroo.utils.Image;
16 import be.nikiroo.utils.StringUtils;
17
18 /**
19 * Command line {@link Story} reader.
20 * <p>
21 * Will output stories to the console.
22 *
23 * @author niki
24 */
25 public class CliReader extends BasicReader {
26 public void listBooks(String source) throws IOException {
27 List<MetaData> stories = Instance.getInstance().getLibrary().getList()
28 .filter(source, null, null);
29
30 for (MetaData story : stories) {
31 String author = "";
32 if (story.getAuthor() != null && !story.getAuthor().isEmpty()) {
33 author = " (" + story.getAuthor() + ")";
34 }
35
36 System.out.println(
37 story.getLuid() + ": " + story.getTitle() + author);
38 }
39 }
40
41 public void listChapters(Story story) throws IOException {
42 if (story == null || story.getMeta() == null) {
43 throw new IOException("No story to read");
44 }
45 MetaData meta = story.getMeta();
46 if (meta == null) {
47 throw new IOException("No story to read");
48 }
49
50 String title = "";
51 String author = "";
52
53 if (meta.getTitle() != null) {
54 title = meta.getTitle();
55 }
56
57 if (meta.getAuthor() != null) {
58 author = "©" + meta.getAuthor();
59 if (meta.getDate() != null && !meta.getDate().isEmpty()) {
60 author = author + " (" + meta.getDate() + ")";
61 }
62 }
63
64 System.out.println(title);
65 System.out.println(author);
66 System.out.println("");
67
68 for (Chapter chap : story) {
69 if (chap.getName() != null && !chap.getName().isEmpty()) {
70 System.out.println(Instance.getInstance().getTrans().getString(
71 StringId.CHAPTER_NAMED, chap.getNumber(),
72 chap.getName()));
73 } else {
74 System.out.println(Instance.getInstance().getTrans()
75 .getString(StringId.CHAPTER_UNNAMED, chap.getNumber()));
76 }
77 }
78 }
79
80 public void printChapter(Story story, int chapter) throws IOException {
81 if (story == null || story.getMeta() == null) {
82 throw new IOException("No story to read");
83 }
84 MetaData meta = story.getMeta();
85 if (meta == null) {
86 throw new IOException("No story to read");
87 }
88
89 if (chapter <= 0 || chapter > story.getChapters().size()) {
90 System.err.println("Chapter " + chapter + ": no such chapter");
91 } else {
92 Chapter chap = story.getChapters().get(chapter - 1);
93 System.out.println(
94 "Chapter " + chap.getNumber() + ": " + chap.getName());
95 System.out.println();
96
97 for (Paragraph para : chap) {
98 Image img = para.getContentImage();
99 if (img != null) {
100 String sz = StringUtils.formatNumber(img.getSize(), 1);
101 System.out.println("[Image: " + sz + "]");
102 } else {
103 System.out.println(
104 para.getContent() == null ? "" : para.getContent());
105 }
106 System.out.println("");
107 }
108 }
109 }
110
111 public void listSearchables() throws IOException {
112 for (SupportType type : SupportType.values()) {
113 if (BasicSearchable.getSearchable(type) != null) {
114 System.out.println(type);
115 }
116 }
117 }
118
119 public void searchBooksByKeyword(SupportType searchOn, String keywords,
120 int page, int item) throws IOException {
121 BasicSearchable search = BasicSearchable.getSearchable(searchOn);
122
123 if (page == 0) {
124 System.out.println(search.searchPages(keywords));
125 } else {
126 List<MetaData> metas = search.search(keywords, page);
127
128 if (item == 0) {
129 System.out.println(
130 "Page " + page + " of stories for: " + keywords);
131 displayStories(metas);
132 } else {
133 // ! 1-based index !
134 if (item <= 0 || item > metas.size()) {
135 throw new IOException("Index out of bounds: " + item);
136 }
137
138 MetaData meta = metas.get(item - 1);
139 displayStory(meta);
140 }
141 }
142 }
143
144 public void searchBooksByTag(SupportType searchOn, int page, int item,
145 Integer... tags) throws IOException {
146
147 BasicSearchable search = BasicSearchable.getSearchable(searchOn);
148 SearchableTag stag = search.getTag(tags);
149
150 if (stag == null) {
151 // TODO i18n
152 System.out.println("Known tags: ");
153 int i = 1;
154 for (SearchableTag s : search.getTags()) {
155 System.out.println(String.format("%d: %s", i, s.getName()));
156 i++;
157 }
158 } else {
159 if (page <= 0) {
160 if (stag.isLeaf()) {
161 System.out.println(search.searchPages(stag));
162 } else {
163 System.out.println(stag.getCount());
164 }
165 } else {
166 List<MetaData> metas = null;
167 List<SearchableTag> subtags = null;
168 int count;
169
170 if (stag.isLeaf()) {
171 metas = search.search(stag, page);
172 count = metas.size();
173 } else {
174 subtags = stag.getChildren();
175 count = subtags.size();
176 }
177
178 if (item > 0) {
179 if (item <= count) {
180 if (metas != null) {
181 MetaData meta = metas.get(item - 1);
182 displayStory(meta);
183 } else {
184 SearchableTag subtag = subtags.get(item - 1);
185 displayTag(subtag);
186 }
187 } else {
188 System.out.println(
189 "Invalid item: only " + count + " items found");
190 }
191 } else {
192 if (metas != null) {
193 // TODO i18n
194 System.out.println(String.format("Content of %s: ",
195 stag.getFqName()));
196 displayStories(metas);
197 } else {
198 // TODO i18n
199 System.out.println(String.format("Subtags of %s: ",
200 stag.getFqName()));
201 displayTags(subtags);
202 }
203 }
204 }
205 }
206 }
207
208 private void displayTag(SearchableTag subtag) {
209 // TODO: i18n
210 String stories = "stories";
211 String num = StringUtils.formatNumber(subtag.getCount());
212 System.out.println(String.format("%s (%s), %s %s", subtag.getName(),
213 subtag.getFqName(), num, stories));
214 }
215
216 private void displayStory(MetaData meta) {
217 System.out.println(meta.getTitle());
218 System.out.println();
219 System.out.println(meta.getUrl());
220 System.out.println();
221 System.out.println("Tags: " + meta.getTags());
222 System.out.println();
223 for (Paragraph para : meta.getResume()) {
224 System.out.println(para.getContent());
225 System.out.println("");
226 }
227 }
228
229 private void displayTags(List<SearchableTag> subtags) {
230 int i = 1;
231 for (SearchableTag subtag : subtags) {
232 String total = "";
233 if (subtag.getCount() > 0) {
234 total = StringUtils.formatNumber(subtag.getCount());
235 }
236
237 if (total.isEmpty()) {
238 System.out
239 .println(String.format("%d: %s", i, subtag.getName()));
240 } else {
241 System.out.println(String.format("%d: %s (%s)", i,
242 subtag.getName(), total));
243 }
244
245 i++;
246 }
247 }
248
249 private void displayStories(List<MetaData> metas) {
250 int i = 1;
251 for (MetaData meta : metas) {
252 System.out.println(i + ": " + meta.getTitle());
253 i++;
254 }
255 }
256 }