1 package be
.nikiroo
.fanfix
.supported
;
3 import java
.awt
.image
.BufferedImage
;
5 import java
.io
.FileInputStream
;
6 import java
.io
.IOException
;
7 import java
.io
.InputStream
;
10 import java
.util
.Map
.Entry
;
11 import java
.util
.zip
.ZipEntry
;
12 import java
.util
.zip
.ZipInputStream
;
14 import javax
.imageio
.ImageIO
;
16 import be
.nikiroo
.fanfix
.Instance
;
17 import be
.nikiroo
.fanfix
.bundles
.Config
;
18 import be
.nikiroo
.utils
.IOUtils
;
19 import be
.nikiroo
.utils
.MarkableFileInputStream
;
22 * Support class for EPUB files created with this program (as we need some
23 * metadata available in those we create).
27 class Epub
extends BasicSupport
{
28 private InfoText base
;
29 private URL fakeSource
;
31 private File tmpCover
;
35 /** Only used by {@link Epub#getInput()} so it is always reset. */
36 private InputStream in
;
39 public String
getSourceName() {
44 protected boolean supports(URL url
) {
45 if (url
.getPath().toLowerCase().endsWith(".epub")) {
53 protected boolean isHtml() {
54 if (tmpInfo
.exists()) {
62 protected String
getTitle(URL source
, InputStream in
) throws IOException
{
63 if (tmpInfo
.exists()) {
64 return base
.getTitle(fakeSource
, getFakeInput());
67 return source
.toString();
71 protected String
getAuthor(URL source
, InputStream in
) throws IOException
{
72 if (tmpInfo
.exists()) {
73 return base
.getAuthor(fakeSource
, getFakeInput());
80 protected String
getDate(URL source
, InputStream in
) throws IOException
{
81 if (tmpInfo
.exists()) {
82 return base
.getDate(fakeSource
, getFakeInput());
89 protected String
getSubject(URL source
, InputStream in
) throws IOException
{
90 if (tmpInfo
.exists()) {
91 return base
.getSubject(fakeSource
, getFakeInput());
98 protected String
getDesc(URL source
, InputStream in
) throws IOException
{
99 if (tmpInfo
.exists()) {
100 return base
.getDesc(fakeSource
, getFakeInput());
107 protected URL
getCover(URL source
, InputStream in
) throws IOException
{
108 if (tmpCover
.exists()) {
109 return tmpCover
.toURI().toURL();
116 protected List
<Entry
<String
, URL
>> getChapters(URL source
, InputStream in
)
118 if (tmpInfo
.exists()) {
119 return base
.getChapters(fakeSource
, getFakeInput());
126 protected String
getChapterContent(URL source
, InputStream in
, int number
)
128 if (tmpInfo
.exists()) {
129 return base
.getChapterContent(fakeSource
, getFakeInput(), number
);
136 protected String
getLang(URL source
, InputStream in
) throws IOException
{
137 if (tmpInfo
.exists()) {
138 return base
.getLang(fakeSource
, getFakeInput());
141 return super.getLang(source
, in
);
145 protected String
getPublisher(URL source
, InputStream in
)
147 if (tmpInfo
.exists()) {
148 return base
.getPublisher(fakeSource
, getFakeInput());
151 return super.getPublisher(source
, in
);
155 protected List
<String
> getTags(URL source
, InputStream in
)
157 if (tmpInfo
.exists()) {
158 return base
.getTags(fakeSource
, getFakeInput());
161 return super.getTags(source
, in
);
165 protected String
getUuid(URL source
, InputStream in
) throws IOException
{
166 if (tmpInfo
.exists()) {
167 return base
.getUuid(fakeSource
, getFakeInput());
170 return super.getUuid(source
, in
);
174 protected String
getLuid(URL source
, InputStream in
) throws IOException
{
175 if (tmpInfo
.exists()) {
176 return base
.getLuid(fakeSource
, getFakeInput());
179 return super.getLuid(source
, in
);
183 protected void preprocess(InputStream in
) throws IOException
{
184 // Note: do NOT close this stream, as it would also close "in"
185 ZipInputStream zipIn
= new ZipInputStream(in
);
186 tmp
= File
.createTempFile("fanfic-reader-parser_", ".tmp");
187 tmpInfo
= new File(tmp
+ ".info");
188 tmpCover
= File
.createTempFile("fanfic-reader-parser_", ".tmp");
190 base
= new InfoText();
191 fakeSource
= tmp
.toURI().toURL();
193 for (ZipEntry entry
= zipIn
.getNextEntry(); entry
!= null; entry
= zipIn
195 if (!entry
.isDirectory()
196 && entry
.getName().startsWith(getDataPrefix())) {
197 String entryLName
= entry
.getName().toLowerCase();
198 boolean imageEntry
= false;
199 for (String ext
: getImageExt(false)) {
200 if (entryLName
.endsWith(ext
)) {
205 if (entry
.getName().equals(getDataPrefix() + "version")) {
206 // Nothing to do for now ("first"
208 } else if (entryLName
.endsWith(".info")) {
210 IOUtils
.write(zipIn
, tmpInfo
);
211 } else if (imageEntry
) {
215 BufferedImage image
= ImageIO
.read(zipIn
);
216 ImageIO
.write(image
, Instance
.getConfig()
217 .getString(Config
.IMAGE_FORMAT_COVER
)
218 .toLowerCase(), tmpCover
);
219 } catch (Exception e
) {
223 } else if (entry
.getName().equals(getDataPrefix() + "URL")) {
225 } else if (entry
.getName().equals(getDataPrefix() + "SUMMARY")) {
228 // Hopefully the data file
229 IOUtils
.write(zipIn
, tmp
);
234 if (requireInfo() && (!tmp
.exists() || !tmpInfo
.exists())) {
235 throw new IOException(
236 "file not supported (maybe not created with this program or corrupt)");
240 this.in
= new MarkableFileInputStream(new FileInputStream(tmp
));
245 protected void close() throws IOException
{
246 for (File file
: new File
[] { tmp
, tmpInfo
, tmpCover
}) {
247 if (file
!= null && file
.exists()) {
248 if (!file
.delete()) {
269 protected String
getDataPrefix() {
273 protected boolean requireInfo() {
277 protected boolean getCover() {
282 * Reset then return {@link Epub#in}.
284 * @return {@link Epub#in}
286 * @throws IOException
287 * in case of I/O error
289 private InputStream
getFakeInput() throws IOException
{