Merge branch 'subtree'
[fanfix.git] / src / be / nikiroo / fanfix / reader / CliReader.java
CommitLineData
d7367179 1package be.nikiroo.fanfix.reader;
08fe2e33
NR
2
3import java.io.IOException;
08fe2e33
NR
4import java.util.List;
5
6import be.nikiroo.fanfix.Instance;
08fe2e33
NR
7import be.nikiroo.fanfix.bundles.StringId;
8import be.nikiroo.fanfix.data.Chapter;
9import be.nikiroo.fanfix.data.MetaData;
10import be.nikiroo.fanfix.data.Paragraph;
11import be.nikiroo.fanfix.data.Story;
91b82a5c
NR
12import be.nikiroo.fanfix.searchable.BasicSearchable;
13import be.nikiroo.fanfix.searchable.SearchableTag;
14import be.nikiroo.fanfix.supported.SupportType;
d7367179 15import be.nikiroo.utils.Image;
74a43961 16import be.nikiroo.utils.StringUtils;
08fe2e33
NR
17
18/**
19 * Command line {@link Story} reader.
20 * <p>
21 * Will output stories to the console.
22 *
23 * @author niki
24 */
d7367179
NR
25public 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);
bc2ea776 29
d7367179
NR
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();
bc2ea776 46 if (meta == null) {
89cb07a6 47 throw new IOException("No story to read");
08fe2e33 48 }
08fe2e33 49
08fe2e33
NR
50 String title = "";
51 String author = "";
52
bc2ea776
NR
53 if (meta.getTitle() != null) {
54 title = meta.getTitle();
55 }
08fe2e33 56
bc2ea776
NR
57 if (meta.getAuthor() != null) {
58 author = "©" + meta.getAuthor();
59 if (meta.getDate() != null && !meta.getDate().isEmpty()) {
60 author = author + " (" + meta.getDate() + ")";
08fe2e33
NR
61 }
62 }
63
64 System.out.println(title);
65 System.out.println(author);
66 System.out.println("");
67
d7367179 68 for (Chapter chap : story) {
08fe2e33 69 if (chap.getName() != null && !chap.getName().isEmpty()) {
d7367179
NR
70 System.out.println(Instance.getInstance().getTrans().getString(
71 StringId.CHAPTER_NAMED, chap.getNumber(),
08fe2e33
NR
72 chap.getName()));
73 } else {
d7367179
NR
74 System.out.println(Instance.getInstance().getTrans()
75 .getString(StringId.CHAPTER_UNNAMED, chap.getNumber()));
08fe2e33
NR
76 }
77 }
78 }
79
d7367179
NR
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();
bc2ea776 85 if (meta == null) {
edd46289
NR
86 throw new IOException("No story to read");
87 }
88
d7367179 89 if (chapter <= 0 || chapter > story.getChapters().size()) {
08fe2e33
NR
90 System.err.println("Chapter " + chapter + ": no such chapter");
91 } else {
d7367179
NR
92 Chapter chap = story.getChapters().get(chapter - 1);
93 System.out.println(
94 "Chapter " + chap.getNumber() + ": " + chap.getName());
95 System.out.println();
96
08fe2e33 97 for (Paragraph para : chap) {
d7367179
NR
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 }
08fe2e33
NR
106 System.out.println("");
107 }
108 }
109 }
110
d7367179 111 public void listSearchables() throws IOException {
b31a0db0
NR
112 for (SupportType type : SupportType.values()) {
113 if (BasicSearchable.getSearchable(type) != null) {
114 System.out.println(type);
115 }
116 }
117 }
118
d7367179
NR
119 public void searchBooksByKeyword(SupportType searchOn, String keywords,
120 int page, int item) throws IOException {
124442f1
NR
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) {
d7367179
NR
129 System.out.println(
130 "Page " + page + " of stories for: " + keywords);
124442f1
NR
131 displayStories(metas);
132 } else {
133 // ! 1-based index !
e92e4ae3 134 if (item <= 0 || item > metas.size()) {
124442f1
NR
135 throw new IOException("Index out of bounds: " + item);
136 }
137
138 MetaData meta = metas.get(item - 1);
139 displayStory(meta);
140 }
141 }
91b82a5c 142 }
b3b9a1cd 143
d7367179
NR
144 public void searchBooksByTag(SupportType searchOn, int page, int item,
145 Integer... tags) throws IOException {
b3b9a1cd 146
aaeabf3a
NR
147 BasicSearchable search = BasicSearchable.getSearchable(searchOn);
148 SearchableTag stag = search.getTag(tags);
b3b9a1cd 149
aaeabf3a
NR
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++;
91b82a5c 157 }
aaeabf3a 158 } else {
91b82a5c
NR
159 if (page <= 0) {
160 if (stag.isLeaf()) {
81acd363 161 System.out.println(search.searchPages(stag));
91b82a5c
NR
162 } else {
163 System.out.println(stag.getCount());
164 }
165 } else {
166 List<MetaData> metas = null;
167 List<SearchableTag> subtags = null;
168 int count;
b3b9a1cd 169
91b82a5c
NR
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 }
b3b9a1cd 177
91b82a5c
NR
178 if (item > 0) {
179 if (item <= count) {
180 if (metas != null) {
181 MetaData meta = metas.get(item - 1);
124442f1 182 displayStory(meta);
91b82a5c
NR
183 } else {
184 SearchableTag subtag = subtags.get(item - 1);
aaeabf3a 185 displayTag(subtag);
91b82a5c
NR
186 }
187 } else {
d7367179
NR
188 System.out.println(
189 "Invalid item: only " + count + " items found");
91b82a5c
NR
190 }
191 } else {
192 if (metas != null) {
8b153400
NR
193 // TODO i18n
194 System.out.println(String.format("Content of %s: ",
aaeabf3a 195 stag.getFqName()));
124442f1 196 displayStories(metas);
91b82a5c 197 } else {
8b153400
NR
198 // TODO i18n
199 System.out.println(String.format("Subtags of %s: ",
aaeabf3a
NR
200 stag.getFqName()));
201 displayTags(subtags);
91b82a5c
NR
202 }
203 }
204 }
91b82a5c
NR
205 }
206 }
124442f1 207
aaeabf3a
NR
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
124442f1
NR
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
aaeabf3a
NR
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
124442f1
NR
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 }
08fe2e33 256}