com.bdaum.zoom.net.communities.jobs.ExportToCommunityJob.java Source code

Java tutorial

Introduction

Here is the source code for com.bdaum.zoom.net.communities.jobs.ExportToCommunityJob.java

Source

/*
 * This file is part of the ZoRa project: http://www.photozora.org.
 *
 * ZoRa is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * ZoRa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZoRa; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * (c) 2009 Berthold Daum  
 */
package com.bdaum.zoom.net.communities.jobs;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.scohen.juploadr.app.ImageAttributes;
import org.scohen.juploadr.app.PhotoSet;
import org.scohen.juploadr.uploadapi.CommunicationException;
import org.scohen.juploadr.uploadapi.IErrorHandler;
import org.scohen.juploadr.uploadapi.ImageUploadApi;
import org.scohen.juploadr.uploadapi.InfoFailedException;
import org.scohen.juploadr.uploadapi.ProtocolException;
import org.scohen.juploadr.uploadapi.Session;

import com.bdaum.zoom.cat.model.asset.Asset;
import com.bdaum.zoom.cat.model.asset.TrackRecord;
import com.bdaum.zoom.cat.model.asset.TrackRecordImpl;
import com.bdaum.zoom.core.Assetbox;
import com.bdaum.zoom.core.Constants;
import com.bdaum.zoom.core.Core;
import com.bdaum.zoom.core.QueryField;
import com.bdaum.zoom.core.db.IDbManager;
import com.bdaum.zoom.image.recipe.UnsharpMask;
import com.bdaum.zoom.job.OperationJob;
import com.bdaum.zoom.net.communities.CommunitiesActivator;
import com.bdaum.zoom.net.communities.CommunityAccount;
import com.bdaum.zoom.net.communities.ui.AlbumDescriptor;
import com.bdaum.zoom.operations.internal.AddTrackRecordsOperation;
import com.bdaum.zoom.operations.jobs.AbstractExportJob;
import com.bdaum.zoom.ui.dialogs.AcousticMessageDialog;

@SuppressWarnings("restriction")
public class ExportToCommunityJob extends AbstractExportJob implements IErrorHandler {

    private static final class ExportRule implements ISchedulingRule {

        public boolean isConflicting(ISchedulingRule rule) {
            return rule instanceof ExportToCommunityJob.ExportRule;
        }

        public boolean contains(ISchedulingRule rule) {
            if (rule == this)
                return true;
            if (rule instanceof UploadJob.UploadRule
                    && ((UploadJob.UploadRule) rule).getParentJob().getRule() == this)
                return true;
            if (rule instanceof PostProcessingTask.PostProcessingRule
                    && ((PostProcessingTask.PostProcessingRule) rule).getParentJob().getRule() == this)
                return true;
            return false;
        }
    }

    private static int exportCounter = 0;
    private Session session;
    private String communityName;
    private List<ImageAttributes> imagesTransferred = new ArrayList<ImageAttributes>();
    private String exportId;
    private List<TrackRecord> track;
    private boolean uploadall;
    protected boolean skipall;
    private boolean skipalloversized;
    private boolean replaceall;
    private final boolean showDescription;
    private int uploadCounter;
    private final AlbumDescriptor[] associatedAlbums;
    private final String[] titles;
    private final String[] descriptions;
    private boolean uploadallunsafe;
    private boolean skipallunsafe;
    private MultiStatus status;
    private final int cropMode;

    public ExportToCommunityJob(IConfigurationElement config, List<Asset> assets,
            AlbumDescriptor[] associatedAlbums, String[] titles, String[] descriptions, int mode, int sizing,
            double scale, int maxSize, int cropMode, UnsharpMask umask, int jpegQuality, Session session,
            Set<QueryField> xmpFilter, boolean showDescription, boolean createWatermark, String copyright,
            IAdaptable adaptable) {
        super(NLS.bind("Export to {0}", config.getAttribute("name")), assets, //$NON-NLS-1$ //$NON-NLS-2$
                mode, sizing, scale, maxSize, umask, jpegQuality, xmpFilter, createWatermark, copyright,
                QueryField.SAFETY_RESTRICTED, adaptable);
        this.associatedAlbums = associatedAlbums;
        this.titles = titles;
        this.descriptions = descriptions;
        this.cropMode = cropMode;
        this.showDescription = showDescription;
        communityName = config.getAttribute("name"); //$NON-NLS-1$
        track = new ArrayList<TrackRecord>(assets.size());
        this.session = session;
        exportId = String.valueOf(++exportCounter);
        setRule(new ExportRule());
        if (session.getApi().getErrorHandler() == null)
            session.getApi().setErrorHandler(this);
    }

    @Override
    public boolean belongsTo(Object family) {
        return Constants.OPERATIONJOBFAMILY == family || Constants.CRITICAL == family;
    }

    @Override
    protected IStatus doRun(IProgressMonitor monitor) {
        long startTime = System.currentTimeMillis();

        status = new MultiStatus(CommunitiesActivator.PLUGIN_ID, 0,
                NLS.bind(Messages.ExportToCommunityJob_export_to_report, communityName), null);
        int size = assets.size();
        monitor.beginTask(NLS.bind(Messages.ExportToCommunityJob_exporting_to, communityName), size + 1);
        SubMonitor progress = SubMonitor.convert(monitor, 1200 * (size + 1) + 100);
        File targetFolder;
        try {
            targetFolder = Core.createTempDirectory(communityName + "Transfer"); //$NON-NLS-1$
        } catch (IOException e) {
            status.add(new Status(IStatus.ERROR, CommunitiesActivator.PLUGIN_ID,
                    NLS.bind(Messages.ExportToCommunityJob_error_when_exporting, communityName), e));
            return status;
        }
        progress.worked(100);
        try (Assetbox box = new Assetbox(null, status, false)) {
            ImageUploadApi imageUploadApi = getImageUploadApi();
            imageUploadApi.preProcessAllUploads(assets, session, this);
            if (monitor.isCanceled())
                return status;
            for (int i = 0; i < size; i++) {
                Asset asset = assets.get(i);
                AlbumDescriptor album = (associatedAlbums == null) ? null : associatedAlbums[i];
                String title = (titles == null) ? null : titles[i];
                String description = (descriptions == null) ? null : descriptions[i];
                File file = box.obtainFile(asset);
                if (file != null) {
                    File outfile = makeUniqueTargetFile(targetFolder, box.getUri(), mode);
                    if (mode == Constants.FORMAT_ORIGINAL) {
                        ImageAttributes imageAttributes = new ImageAttributes(session, asset, album, file, false);
                        imageAttributes.setTitle(title);
                        if (showDescription)
                            imageAttributes.setDescription(description);
                        else
                            imageAttributes.setDescription(""); //$NON-NLS-1$
                        imagesTransferred.add(imageAttributes);
                        upload(imageAttributes, monitor, false);
                        if (monitor.isCanceled())
                            break;
                    } else {
                        if (downScaleImage(status, progress, asset, file, outfile, 1d, cropMode) != null) {
                            if (monitor.isCanceled())
                                break;
                            ImageAttributes imageAttributes = new ImageAttributes(session, asset, album, outfile,
                                    true);
                            imageAttributes.setTitle(title);
                            if (showDescription)
                                imageAttributes.setDescription(description);
                            else
                                imageAttributes.setDescription(""); //$NON-NLS-1$
                            imagesTransferred.add(imageAttributes);
                            upload(imageAttributes, monitor, true);
                            if (monitor.isCanceled())
                                break;
                        }
                        progress.worked(200);
                    }
                }
                if (monitor.isCanceled()) {
                    status.add(new Status(IStatus.WARNING, CommunitiesActivator.PLUGIN_ID,
                            NLS.bind(Messages.ExportToCommunityJob_export_was_canceled, communityName)));
                    return status;
                }
            }
            imageUploadApi.postProcessAllUploads(imagesTransferred, session, this);
            try {
                getJobManager().join(exportId, monitor);
                session.getAccount().save();
                if (!track.isEmpty())
                    OperationJob.executeOperation(new AddTrackRecordsOperation(track), adaptable);
                CommunitiesActivator.getDefault().getLog()
                        .log(new Status(IStatus.INFO, CommunitiesActivator.PLUGIN_ID, NLS.bind(
                                Messages.ExportToCommunityJob_n_images_transferred,
                                new Object[] { track.size(), communityName, session.getAccount().getName() })));
            } catch (OperationCanceledException e) {
                // do nothing
            } catch (InterruptedException e) {
                // do nothing
            }
        } finally {
            try {
                Job.getJobManager().join(Constants.UPLOADJOBFAMILY, monitor);
            } catch (InterruptedException e) {
                Job.getJobManager().cancel(Constants.UPLOADJOBFAMILY);
            }
            session.close();
            targetFolder.delete();
        }
        OperationJob.signalJobEnd(startTime);
        showCommunityWebPage();
        monitor.done();
        return status;
    }

    private void showCommunityWebPage() {
        try {
            if (uploadCounter > 0 && session.getAccount().getVisit() != null
                    && !session.getAccount().getVisit().isEmpty()) {
                Shell shell = adaptable.getAdapter(Shell.class);
                if (shell != null && !shell.isDisposed()) {
                    shell.getDisplay().asyncExec(() -> {
                        if (!shell.isDisposed())
                            session.getAccount().testVisit();
                    });
                }
            }
        } catch (Exception e) {
            // do notbhing
        }
    }

    @SuppressWarnings("fallthrough")
    private void upload(ImageAttributes imageAttributes, final IProgressMonitor monitor,
            boolean deleteAfterTransfer) {
        boolean replace = false;
        final Shell shell = adaptable.getAdapter(Shell.class);
        String name = imageAttributes.getAsset().getName();
        boolean single = assets.size() <= 1;
        String imagePath = imageAttributes.getImagePath();
        File imageFile = new File(imagePath);
        long filesize = imageFile.length();
        if (filesize > session.getAccount().getMaxFilesize()) {
            if (skipalloversized)
                return;
            String[] buttons = single ? new String[] { IDialogConstants.CANCEL_LABEL }
                    : new String[] { Messages.ExportToCommunityJob_skip_all, IDialogConstants.SKIP_LABEL,
                            IDialogConstants.CANCEL_LABEL };
            final AcousticMessageDialog dialog = new AcousticMessageDialog(shell,
                    Messages.ExportToCommunityJob_image_too_large, null,
                    NLS.bind(Messages.ExportToCommunityJob_image_is_larger_than, name,
                            session.getAccount().getMaxFilesize() / (1024 * 1024)),
                    MessageDialog.QUESTION, buttons, 1);
            shell.getDisplay().syncExec(() -> dialog.open());
            int ret = dialog.getReturnCode();
            if (single) {
                monitor.setCanceled(true);
                return;
            }
            switch (ret) {
            case 0:
                skipalloversized = true;
            case 1:
                return;
            case 2:
                monitor.setCanceled(true);
                return;
            }
        } else if (filesize > (session.getAccount().getTrafficLimit()
                - session.getAccount().getCurrentUploadUsed())) {
            shell.getDisplay().syncExec(new Runnable() {

                public void run() {
                    AcousticMessageDialog.openWarning(shell, Messages.ExportToCommunityJob_traffic_limit_exceeded,
                            NLS.bind(Messages.ExportToCommunityJob_the_traffic_limit_of,
                                    new Object[] { session.getAccount().getTrafficLimit() / (1024 * 1024),
                                            communityName, session.getAccount().getName() }));
                }
            });
            monitor.setCanceled(true);
        } else {
            if (!uploadall) {
                final Date date = getUploadDate(imageAttributes);
                if (date != null) {
                    if (skipall)
                        return;
                    if (replaceall)
                        replace = true;
                    else {
                        String[] buttons = session.getAccount().isCanReplace() ? (single
                                ? new String[] { Messages.ExportToCommunityJob_replace,
                                        Messages.ExportToCommunityJob_upload, Messages.ExportToCommunityJob_cancel }
                                : new String[] { Messages.ExportToCommunityJob_replace_all,
                                        Messages.ExportToCommunityJob_replace,
                                        Messages.ExportToCommunityJob_upload_all,
                                        Messages.ExportToCommunityJob_upload,
                                        Messages.ExportToCommunityJob_skip_all, Messages.ExportToCommunityJob_skp,
                                        Messages.ExportToCommunityJob_cancel })
                                : (single
                                        ? new String[] { Messages.ExportToCommunityJob_upload,
                                                Messages.ExportToCommunityJob_cancel }
                                        : new String[] { Messages.ExportToCommunityJob_upload_all,
                                                Messages.ExportToCommunityJob_upload,
                                                Messages.ExportToCommunityJob_skip_all,
                                                Messages.ExportToCommunityJob_skp,
                                                Messages.ExportToCommunityJob_cancel });
                        SimpleDateFormat df = new SimpleDateFormat(
                                Messages.ExportToCommunityJob_tracik_date_format);
                        final AcousticMessageDialog dialog = new AcousticMessageDialog(shell,
                                Messages.ExportToCommunityJob_image_already_uploaded, null,
                                NLS.bind(Messages.ExportToCommunityJob_image_uploaded_at,
                                        new Object[] { name, df.format(date), communityName,
                                                session.getAccount().getName() }),
                                MessageDialog.QUESTION, buttons, 1);
                        shell.getDisplay().syncExec(new Runnable() {

                            public void run() {
                                dialog.open();
                            }
                        });
                        int ret = dialog.getReturnCode();
                        if (session.getAccount().isCanReplace()) {
                            if (single) {
                                switch (ret) {
                                case 0:
                                    replace = true;
                                    break;
                                case 2:
                                    monitor.setCanceled(true);
                                    return;
                                }
                            } else {
                                switch (ret) {
                                case 0:
                                    replaceall = true;
                                    break;
                                case 1:
                                    replace = true;
                                    break;
                                case 2:
                                    uploadall = true;
                                    break;
                                case 4:
                                    skipall = true;
                                case 5:
                                    return;
                                case 6:
                                    monitor.setCanceled(true);
                                    return;
                                }
                            }
                        } else {
                            if (single) {
                                switch (ret) {
                                case 1:
                                    monitor.setCanceled(true);
                                    return;
                                }
                            } else {
                                switch (ret) {
                                case 0:
                                    uploadall = true;
                                    break;
                                case 2:
                                    skipall = true;
                                case 3:
                                    return;
                                case 4:
                                    monitor.setCanceled(true);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            if (!replace && !uploadallunsafe) {
                PhotoSet photoset = session.matchAlbum(imageAttributes);
                if (photoset != null && photoset.isUnsafe(imageAttributes)) {
                    if (skipallunsafe)
                        return;
                    String[] buttons = (single
                            ? new String[] { Messages.ExportToCommunityJob_upload,
                                    Messages.ExportToCommunityJob_cancel }
                            : new String[] { Messages.ExportToCommunityJob_upload_all,
                                    Messages.ExportToCommunityJob_upload, Messages.ExportToCommunityJob_skip_all,
                                    Messages.ExportToCommunityJob_skp, Messages.ExportToCommunityJob_cancel });
                    final AcousticMessageDialog dialog = new AcousticMessageDialog(shell,
                            Messages.ExportToCommunityJob_privacy_violated, null,
                            NLS.bind(Messages.ExportToCommunityJob_image_classified_as_unsafe, new Object[] { name,
                                    photoset.getTitle(), communityName, session.getAccount().getName() }),
                            MessageDialog.QUESTION, buttons, 1);
                    shell.getDisplay().syncExec(new Runnable() {
                        public void run() {
                            dialog.open();
                        }
                    });
                    int ret = dialog.getReturnCode();
                    if (single) {
                        switch (ret) {
                        case 1:
                            monitor.setCanceled(true);
                            return;
                        }
                    } else {
                        switch (ret) {
                        case 0:
                            uploadallunsafe = true;
                            break;
                        case 2:
                            skipallunsafe = true;
                        case 3:
                            return;
                        case 4:
                            monitor.setCanceled(true);
                            return;
                        }
                    }
                }
            }
            new UploadJob(this, imageAttributes, replace, deleteAfterTransfer).schedule();
        }
    }

    private Date getUploadDate(ImageAttributes imageAttributes) {
        IDbManager dbManager = Core.getCore().getDbManager();
        String[] imageTrack = imageAttributes.getAsset().getTrack();
        if (imageTrack != null) {
            ImageUploadApi imageUploadApi = getImageUploadApi();
            for (String id : imageTrack) {
                TrackRecordImpl record = dbManager.obtainById(TrackRecordImpl.class, id);
                if (record != null)
                    try {
                        if (imageUploadApi.getImageInfo(session, record.getDerivative()) != null)
                            return record.getExportDate();
                    } catch (InfoFailedException e) {
                        // ignore
                    } catch (CommunicationException e) {
                        // ignore
                    } catch (ProtocolException e) {
                        // ignore
                    }
            }
        }
        return null;
    }

    public ImageUploadApi getImageUploadApi() {
        ImageUploadApi api = (ImageUploadApi) session.getApi();
        api.setStatus(status);
        return api;
    }

    public Set<QueryField> getFilter() {
        return xmpFilter;
    }

    public String getExportId() {
        return exportId;
    }

    public void addTrackRecord(TrackRecord record) {
        track.add(record);
    }

    public CommunityAccount getAccount() {
        return session.getAccount();
    }

    public String getCommunityName() {
        return communityName;
    }

    public void incrementCounter() {
        ++uploadCounter;
    }

    public Session getSession() {
        return session;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Object getAdapter(Class adapter) {
        Object obj = adaptable.getAdapter(adapter);
        return obj != null ? obj : super.getAdapter(adapter);
    }

    public void handleError(Object source, Exception e) {
        status.add(new Status(IStatus.ERROR, CommunitiesActivator.PLUGIN_ID,
                NLS.bind(Messages.ExportToCommunityJob_communication_error, session.getApi().getSiteName()), e));
    }

    public MultiStatus getStatus() {
        return status;
    }

}