package com.zestedesavoir.zestwriter.view.task; import com.fasterxml.jackson.databind.ObjectMapper; import com.zestedesavoir.zestwriter.MainApp; import com.zestedesavoir.zestwriter.model.Content; import com.zestedesavoir.zestwriter.model.MetadataContent; import com.zestedesavoir.zestwriter.utils.Configuration; import javafx.concurrent.Service; import javafx.concurrent.Task; import org.zeroturnaround.zip.ZipEntryCallback; import org.zeroturnaround.zip.ZipUtil; import org.zeroturnaround.zip.commons.IOUtils; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; import java.util.zip.ZipEntry; public class DownloadContentService extends Service<Map<Content, Map<String, List<Map<File,String>>>>>{ String typeContent; ObjectMapper mapper; public DownloadContentService(String typeContent) { this.typeContent = typeContent; mapper = new ObjectMapper(); } private Content getContentFromDir(String dirName) { File manifest = new File(dirName, "manifest.json"); Content content = null; try { content = mapper.readValue(manifest, Content.class); } catch (IOException e) { return null; } content.setRootContent(content, manifest.getParentFile().getAbsolutePath()); return content; } private static long getCrc(String filename) { try { CheckedInputStream cis = null; long fileSize = 0; try { cis = new CheckedInputStream(new FileInputStream(filename), new CRC32()); fileSize = new File(filename).length(); } catch(FileNotFoundException e) { e.printStackTrace(); } byte[] buf = new byte[128]; while (cis.read(buf) >= 0) { } return cis.getChecksum().getValue(); } catch (IOException e) { e.printStackTrace(); } return 0; } public Map<String, List<Map<File, String>>> compareOfflineAndOnline(String onlineZipPath, String offlineDirPath) { File existFolder = new File(offlineDirPath); if (!existFolder.exists()) { return null; } Map<String, List<Map<File,String>>> result = new HashMap<>(); result.put("update", new ArrayList<>()); result.put("add", new ArrayList<>()); ZipUtil.iterate(new File(onlineZipPath), new ZipEntryCallback() { @Override public void process(InputStream in, ZipEntry zipEntry) throws IOException { File fileOffline = new File(existFolder,zipEntry.getName()); if(fileOffline.exists()) { // file for merge if(zipEntry.getCrc() != getCrc(fileOffline.getAbsolutePath())) { result.get("update").add(inputToMapping(in, fileOffline)); } } else { // file for add result.get("add").add(inputToMapping(in, fileOffline)); } } }); return result; } private Map<File, String> inputToMapping(InputStream src, File dest) throws IOException { Map<File, String> mapping = new HashMap<>(); String text = IOUtils.toString(src, "UTF-8"); mapping.put(dest, text); return mapping; } @Override protected Task<Map<Content, Map<String, List<Map<File,String>>>>> createTask() { return new Task<Map<Content, Map<String, List<Map<File,String>>>>>() { @Override protected Map<Content, Map<String, List<Map<File,String>>>> call() throws Exception { Map<Content, Map<String, List<Map<File,String>>>> conflicts = new HashMap<>(); if (MainApp.getZdsutils().isAuthenticated()) { List<MetadataContent> workedList = MainApp.getZdsutils().getContentListOnline(); if(typeContent != null) { workedList = workedList.stream() .filter(c -> c.getType().equals(typeContent.toLowerCase())) .collect(Collectors.toList()); } int max = workedList.size(); int iterations = 0; for (MetadataContent meta : workedList) { updateMessage(Configuration.getBundle().getString("ui.task.download.label")+" : " + meta.getSlug()); updateProgress(iterations, max); MainApp.getZdsutils().downloaDraft(meta.getId(), meta.getType()); iterations++; } iterations = 0; for (MetadataContent meta : workedList) { updateMessage(Configuration.getBundle().getString("ui.task.unzip.label")+" : " + meta.getSlug()); updateProgress(iterations, max); Map<String, List<Map<File,String>>> conflict = compareOfflineAndOnline(MainApp.getZdsutils().getOnlineContentPathDir() + File.separator + meta.getSlug() + ".zip", MainApp.getZdsutils().getOfflineContentPathDir() + File.separator + meta.getSlug()); conflicts.put(getContentFromDir(MainApp.getZdsutils().getOfflineContentPathDir() + File.separator + meta.getSlug()), conflict); MainApp.getZdsutils().unzipOnlineContent(MainApp.getZdsutils().getOnlineContentPathDir() + File.separator + meta.getSlug() + ".zip"); iterations++; } updateMessage(Configuration.getBundle().getString("ui.task.end.label")); updateProgress(iterations, max); } return conflicts; } }; } }