org.tinymediamanager.core.MediaEntityImageFetcherTask.java Source code

Java tutorial

Introduction

Here is the source code for org.tinymediamanager.core.MediaEntityImageFetcherTask.java

Source

/*
 * Copyright 2012 - 2016 Manuel Laggner
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.tinymediamanager.core;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinymediamanager.core.Message.MessageLevel;
import org.tinymediamanager.core.entities.MediaEntity;
import org.tinymediamanager.scraper.entities.MediaArtwork.MediaArtworkType;
import org.tinymediamanager.scraper.http.Url;

/**
 * The Class MediaEntityImageFetcherTask.
 * 
 * @author Manuel Laggner
 */
public class MediaEntityImageFetcherTask implements Runnable {
    private final static Logger LOGGER = LoggerFactory.getLogger(MediaEntityImageFetcherTask.class);

    private MediaEntity entity;
    private String url;
    private MediaArtworkType type;
    private String filename;
    private boolean firstImage;

    public MediaEntityImageFetcherTask(MediaEntity entity, String url, MediaArtworkType type, String filename,
            boolean firstImage) {
        this.entity = entity;
        this.url = url;
        this.type = type;
        this.filename = filename;
        this.firstImage = firstImage;
    }

    @Override
    public void run() {
        long timestamp = System.currentTimeMillis(); // multi episode same file
        try {
            if (StringUtils.isBlank(filename)) {
                return;
            }

            // don't write jpeg -> write jpg
            if (FilenameUtils.getExtension(filename).equalsIgnoreCase("JPEG")) {
                filename = FilenameUtils.getBaseName(filename) + ".jpg";
            }

            String oldFilename = null;
            try {
                // store old filename at the first image
                if (firstImage) {
                    switch (type) {
                    case POSTER:
                    case BACKGROUND:
                    case BANNER:
                    case THUMB:
                    case CLEARART:
                    case DISC:
                    case LOGO:
                    case CLEARLOGO:
                        oldFilename = entity.getArtworkFilename(MediaFileType.getMediaFileType(type));
                        entity.removeAllMediaFiles(MediaFileType.getMediaFileType(type));
                        break;

                    default:
                        return;
                    }
                }

                // debug message
                LOGGER.debug("writing " + type + " " + filename);
                Path destFile = entity.getPathNIO().resolve(filename);
                Path tempFile = entity.getPathNIO().resolve(filename + "." + timestamp + ".part"); // multi episode same file

                // check if old and new file are the same (possible if you select it in the imagechooser)
                boolean sameFile = false;
                if (url.startsWith("file:")) {
                    String newUrl = url.replace("file:/", "");
                    Path file = Paths.get(newUrl);
                    if (file.equals(destFile)) {
                        sameFile = true;
                    }
                }

                // fetch and store images
                if (!sameFile) {
                    Url url1 = new Url(url);
                    FileOutputStream outputStream = new FileOutputStream(tempFile.toFile());
                    InputStream is = url1.getInputStream();
                    IOUtils.copy(is, outputStream);
                    outputStream.flush();
                    try {
                        outputStream.getFD().sync(); // wait until file has been completely written
                        // give it a few milliseconds
                        Thread.sleep(150);
                    } catch (Exception e) {
                        // empty here -> just not let the thread crash
                    }
                    outputStream.close();
                    is.close();

                    // check if the file has been downloaded
                    if (!Files.exists(tempFile) || Files.size(tempFile) == 0) {
                        throw new Exception("0byte file downloaded: " + filename);
                    }

                    // delete the old one if exisiting
                    if (StringUtils.isNotBlank(oldFilename)) {
                        Path oldFile = entity.getPathNIO().resolve(oldFilename);
                        Utils.deleteFileSafely(oldFile);
                    }

                    // delete new destination if existing
                    Utils.deleteFileSafely(destFile);

                    // move the temp file to the expected filename
                    if (!Utils.moveFileSafe(tempFile, destFile)) {
                        throw new Exception("renaming temp file failed: " + filename);
                    }
                }

                // has tmm been shut down?
                if (Thread.interrupted()) {
                    return;
                }

                // set the new image if its the first image
                if (firstImage) {
                    LOGGER.debug("set " + type + " " + FilenameUtils.getName(filename));
                    ImageCache.invalidateCachedImage(entity.getPathNIO().resolve(filename));
                    switch (type) {
                    case POSTER:
                    case BACKGROUND:
                    case BANNER:
                    case THUMB:
                    case CLEARART:
                    case DISC:
                    case LOGO:
                    case CLEARLOGO:
                        entity.setArtwork(destFile, MediaFileType.getMediaFileType(type));
                        entity.callbackForWrittenArtwork(type);
                        entity.saveToDb();
                        break;

                    default:
                        return;
                    }
                }
            }

            catch (Exception e) {
                if (e instanceof InterruptedException) {
                    // only warning
                    LOGGER.warn("interrupted image download");
                } else {
                    LOGGER.error("fetch image", e);
                }

                // remove temp file
                Path tempFile = entity.getPathNIO().resolve(filename + "." + timestamp + ".part"); // multi episode same file
                if (Files.exists(tempFile)) {
                    Utils.deleteFileSafely(tempFile);
                }

                // fallback
                if (firstImage && StringUtils.isNotBlank(oldFilename)) {
                    switch (type) {
                    case POSTER:
                    case BACKGROUND:
                    case BANNER:
                    case THUMB:
                    case CLEARART:
                    case DISC:
                    case LOGO:
                    case CLEARLOGO:
                        entity.setArtwork(Paths.get(oldFilename), MediaFileType.getMediaFileType(type));
                        entity.callbackForWrittenArtwork(type);
                        entity.saveToDb();
                        break;

                    default:
                        return;
                    }
                }

                MessageManager.instance.pushMessage(new Message(MessageLevel.ERROR, "ArtworkDownload",
                        "message.artwork.threadcrashed", new String[] { ":", e.getLocalizedMessage() }));
            }

        } catch (Exception e) {
            LOGGER.error("crashed thread: ", e);
        }
    }
}