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