f1ee71c1195d6337461dc35e6d9fdbfdde7a3ef2
1 package be
.nikiroo
.fanfix
.supported
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
6 import java
.net
.URISyntaxException
;
8 import java
.util
.ArrayList
;
10 import java
.util
.Map
.Entry
;
11 import java
.util
.Scanner
;
13 import be
.nikiroo
.fanfix
.Instance
;
14 import be
.nikiroo
.fanfix
.bundles
.Config
;
17 * Support class for local stories encoded in textual format, with a few rules:
19 * <li>The title must be on the first line</li>
20 * <li>The author (preceded by nothing, "by " or "©") must be on the second
21 * line, possibly with the publication date in parenthesis (i.e., "
22 * <tt>By Unknown (3rd October 1998)</tt>")</li>
23 * <li>Chapters must be declared with "<tt>Chapter x</tt>" or "
24 * <tt>Chapter x: NAME OF THE CHAPTER</tt>", where "<tt>x</tt>" is the chapter
26 * <li>A description of the story must be given as chapter number 0</li>
27 * <li>A cover may be present, with the same filename but a PNG, JPEG or JPG
33 class Text
extends BasicSupport
{
35 protected boolean isHtml() {
40 public String
getSourceName() {
45 protected String
getPublisher(URL source
, InputStream in
)
51 protected String
getSubject(URL source
, InputStream in
) throws IOException
{
53 File file
= new File(source
.toURI());
54 return file
.getParentFile().getName();
55 } catch (URISyntaxException e
) {
56 throw new IOException("Cannot parse the URL to File: "
57 + source
.toString(), e
);
63 protected String
getLang(URL source
, InputStream in
) throws IOException
{
64 @SuppressWarnings("resource")
65 Scanner scan
= new Scanner(in
, "UTF-8");
66 scan
.useDelimiter("\\n");
68 scan
.next(); // Author (Date)
69 String chapter0
= scan
.next(); // empty or Chapter 0
70 while (chapter0
.isEmpty()) {
71 chapter0
= scan
.next();
74 String lang
= detectChapter(chapter0
);
76 lang
= super.getLang(source
, in
);
78 lang
= lang
.toUpperCase();
85 protected String
getTitle(URL source
, InputStream in
) throws IOException
{
86 @SuppressWarnings("resource")
87 Scanner scan
= new Scanner(in
, "UTF-8");
88 scan
.useDelimiter("\\n");
93 protected String
getAuthor(URL source
, InputStream in
) throws IOException
{
94 @SuppressWarnings("resource")
95 Scanner scan
= new Scanner(in
, "UTF-8");
96 scan
.useDelimiter("\\n");
98 String authorDate
= scan
.next();
100 String author
= authorDate
;
101 int pos
= authorDate
.indexOf('(');
103 author
= authorDate
.substring(0, pos
);
110 protected String
getDate(URL source
, InputStream in
) throws IOException
{
111 @SuppressWarnings("resource")
112 Scanner scan
= new Scanner(in
, "UTF-8");
113 scan
.useDelimiter("\\n");
115 String authorDate
= scan
.next();
118 int pos
= authorDate
.indexOf('(');
120 date
= authorDate
.substring(pos
+ 1).trim();
121 pos
= date
.lastIndexOf(')');
123 date
= date
.substring(0, pos
).trim();
131 protected String
getDesc(URL source
, InputStream in
) {
132 return getChapterContent(source
, in
, 0);
136 protected URL
getCover(URL source
, InputStream in
) {
139 path
= new File(source
.toURI()).getPath();
140 } catch (URISyntaxException e
) {
145 for (String ext
: new String
[] { ".txt", ".text", ".story" }) {
146 if (path
.endsWith(ext
)) {
147 path
= path
.substring(0, path
.length() - ext
.length());
151 return getImage(source
, path
);
155 protected List
<Entry
<String
, URL
>> getChapters(URL source
, InputStream in
) {
156 List
<Entry
<String
, URL
>> chaps
= new ArrayList
<Entry
<String
, URL
>>();
157 @SuppressWarnings("resource")
158 Scanner scan
= new Scanner(in
, "UTF-8");
159 scan
.useDelimiter("\\n");
160 boolean descSkipped
= false;
161 boolean prevLineEmpty
= false;
162 while (scan
.hasNext()) {
163 String line
= scan
.next();
164 if (prevLineEmpty
&& detectChapter(line
) != null) {
166 String chapName
= Integer
.toString(chaps
.size());
167 int pos
= line
.indexOf(':');
168 if (pos
>= 0 && pos
+ 1 < line
.length()) {
169 chapName
= line
.substring(pos
+ 1).trim();
171 final URL value
= source
;
172 final String key
= chapName
;
173 chaps
.add(new Entry
<String
, URL
>() {
174 public URL
setValue(URL value
) {
178 public URL
getValue() {
182 public String
getKey() {
191 prevLineEmpty
= line
.trim().isEmpty();
198 protected String
getChapterContent(URL source
, InputStream in
, int number
) {
199 StringBuilder builder
= new StringBuilder();
200 @SuppressWarnings("resource")
201 Scanner scan
= new Scanner(in
, "UTF-8");
202 scan
.useDelimiter("\\n");
203 boolean inChap
= false;
204 boolean prevLineEmpty
= false;
205 while (scan
.hasNext()) {
206 String line
= scan
.next();
208 if (detectChapter(line
, number
) != null) {
211 if (prevLineEmpty
&& detectChapter(line
) != null) {
215 builder
.append(line
);
216 builder
.append("\n");
220 prevLineEmpty
= line
.trim().isEmpty();
223 return builder
.toString();
227 protected boolean supports(URL url
) {
228 if ("file".equals(url
.getProtocol())) {
231 file
= new File(url
.toURI());
232 file
= new File(file
.getPath() + ".info");
233 } catch (URISyntaxException e
) {
238 return file
== null || !file
.exists();
245 * Check if the given line looks like a starting chapter in a supported
246 * language, and return the language if it does (or NULL if not).
251 * @return the language or NULL
253 private String
detectChapter(String line
) {
254 return detectChapter(line
, null);
258 * Check if the given line looks like the given starting chapter in a
259 * supported language, and return the language if it does (or NULL if not).
264 * @return the language or NULL
266 private String
detectChapter(String line
, Integer number
) {
267 line
= line
.toUpperCase();
268 for (String lang
: Instance
.getConfig().getString(Config
.CHAPTER
)
270 String chapter
= Instance
.getConfig().getStringX(Config
.CHAPTER
,
272 if (chapter
!= null && !chapter
.isEmpty()) {
273 chapter
= chapter
.toUpperCase() + " ";
274 if (line
.startsWith(chapter
)) {
275 if (number
!= null) {
276 // We want "[CHAPTER] [number]: [name]", with ": [name]"
278 String test
= line
.substring(chapter
.length()).trim();
279 if (test
.startsWith(Integer
.toString(number
))) {
280 test
= test
.substring(
281 Integer
.toString(number
).length()).trim();
282 if (test
.isEmpty() || test
.startsWith(":")) {