diff --git a/notes-service/src/main/java/org/exoplatform/wiki/model/NoteToExport.java b/notes-service/src/main/java/org/exoplatform/wiki/model/NoteToExport.java index 0431eba3da..44fcfd4c04 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/model/NoteToExport.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/model/NoteToExport.java @@ -22,6 +22,7 @@ import java.util.LinkedList; import java.util.List; +import io.meeds.notes.model.NotePageProperties; import lombok.Getter; import lombok.Setter; @@ -57,6 +58,8 @@ public class NoteToExport { private LinkedList ancestors; + private NotePageProperties properties; + public NoteToExport() { } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/ExportAction.java b/notes-service/src/main/java/org/exoplatform/wiki/service/ExportAction.java index 0ff188f1ed..0ea30bf040 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/ExportAction.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/ExportAction.java @@ -22,22 +22,40 @@ @Data public class ExportAction { - public static final String GETTING_NOTES = "GETTING_NOTES"; - public static final String UPDATING_NOTES_PARENTS = "UPDATING_NOTES_PARENTS"; - public static final String CREATING_CONTENT_DATA = "CREATING_CONTENT_DATA"; - public static final String UPDATING_IMAGES_URLS = "UPDATING_IMAGES_URLS"; - public static final String CREATING_ZIP_FILE = "CREATING_ZIP_FILE"; - public static final String CLEANING_TEMP_FILE = "CLEANING_TEMP_FILE"; - public static final String EXPORT_DATA_CREATED = "EXPORT_DATA_CREATED"; - - private boolean started = false; - private boolean notesGetted = false; - private boolean notesPrepared = false; - private boolean jsonCreated = false; - private boolean imageUrlsUpdated = false; - private boolean zipCreated = false; - private boolean tempCleaned = false; - private boolean dataCreated = false; - private String action = ""; + public static final String GETTING_NOTES = "GETTING_NOTES"; + + public static final String UPDATING_NOTES_PARENTS = "UPDATING_NOTES_PARENTS"; + + public static final String CREATING_CONTENT_DATA = "CREATING_CONTENT_DATA"; + + public static final String UPDATING_IMAGES_URLS = "UPDATING_IMAGES_URLS"; + + public static final String CREATING_ZIP_FILE = "CREATING_ZIP_FILE"; + + public static final String CLEANING_TEMP_FILE = "CLEANING_TEMP_FILE"; + + public static final String EXPORT_DATA_CREATED = "EXPORT_DATA_CREATED"; + + public static final String PROCESS_FEATURED_IMAGES = "PROCESS_FEATURED_IMAGES"; + + private boolean started = false; + + private boolean notesGetted = false; + + private boolean notesPrepared = false; + + private boolean jsonCreated = false; + + private boolean imageUrlsUpdated = false; + + private boolean featuredImagesProcessed = false; + + private boolean zipCreated = false; + + private boolean tempCleaned = false; + + private boolean dataCreated = false; + + private String action = ""; } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/ExportThread.java b/notes-service/src/main/java/org/exoplatform/wiki/service/ExportThread.java index 8c977ee17b..1047f7f8b6 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/ExportThread.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/ExportThread.java @@ -29,6 +29,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.text.SimpleDateFormat; @@ -42,14 +43,21 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.util.MimeTypeUtils; import com.fasterxml.jackson.databind.ObjectMapper; +import org.exoplatform.commons.file.model.FileInfo; +import org.exoplatform.commons.file.model.FileItem; +import org.exoplatform.commons.file.services.FileService; import org.exoplatform.container.PortalContainer; import org.exoplatform.container.component.RequestLifeCycle; import org.exoplatform.services.log.ExoLogger; @@ -61,10 +69,12 @@ import org.exoplatform.wiki.model.ExportList; import org.exoplatform.wiki.model.NoteToExport; import org.exoplatform.wiki.model.Page; -import org.exoplatform.wiki.model.Wiki; import org.exoplatform.wiki.model.WikiType; -public class ExportThread implements Runnable { +import io.meeds.notes.model.NoteFeaturedImage; +import io.meeds.notes.model.NotePageProperties; + + public class ExportThread implements Runnable { private static final Log log = ExoLogger.getLogger(ExportThread.class); @@ -77,6 +87,8 @@ public class ExportThread implements Runnable { private static final String EXPORT_ZIP_PREFIX = "exportzip"; private static final String TEMP_DIRECTORY_PATH = "java.io.tmpdir"; + + private static final String FEATURED_IMAGES_DIRECTORY = "featuredImages"; private final NoteService noteService; @@ -88,52 +100,46 @@ public class ExportThread implements Runnable { private final ExportData exportData; + private final FileService fileService; + public ExportThread(NoteService noteService, WikiService wikiService, NotesExportService notesExportService, HTMLUploadImageProcessor htmlUploadImageProcessor, - ExportData exportData) { + ExportData exportData, + FileService fileService) { this.noteService = noteService; this.wikiService = wikiService; this.notesExportService = notesExportService; this.htmlUploadImageProcessor = htmlUploadImageProcessor; this.exportData = exportData; + this.fileService = fileService; } - public static void cleanUp(File file) throws IOException { - if (Files.exists(file.toPath())) { - Files.delete(file.toPath()); + public static void cleanUp(List files) throws IOException { + for (File file : files) { + if (Files.exists(file.toPath())) { + Files.delete(file.toPath()); + } } } public static File zipFiles(String zipFileName, - List addToZip, + List> addToZip, NotesExportService notesExportService, int exportId) throws IOException { String zipPath = System.getProperty(TEMP_DIRECTORY_PATH) + File.separator + zipFileName; FileOutputStream fos = new FileOutputStream(zipPath); + List files = addToZip.getFirst(); + List featuredImages = addToZip.getLast(); try (ZipOutputStream zipOut = new ZipOutputStream(fos)) { - for (File fileToZip : addToZip) { - ExportResource exportResource = notesExportService.getExportRessourceById(exportId); - if (exportResource.getStatus().equals(ExportStatus.CANCELLED.name())) { - return null; - } - try (FileInputStream fis = new FileInputStream(fileToZip)) { - ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); - zipOut.putNextEntry(zipEntry); - byte[] bytes = new byte[1024]; - int length; - while ((length = fis.read(bytes)) >= 0) { - zipOut.write(bytes, 0, length); - } - fis.close(); - } catch (IOException e) { - log.warn("cannot add the file: {} to the zip", fileToZip.getName()); - } - } + addFilesToZip(zipOut, files, exportId, null, notesExportService); + addFilesToZip(zipOut, featuredImages, exportId, FEATURED_IMAGES_DIRECTORY, notesExportService); zipOut.close(); fos.close(); + } catch (InterruptedIOException e) { + return null; } catch (IOException e) { log.warn("cannot zip files"); } @@ -152,23 +158,25 @@ public void run() { exportData.getNotesToExportIds(), exportData.isExportAll(), exportData.getIdentity()); - } catch (IOException e) { + } catch (Exception e) { log.error("cannot Export Notes", e); } finally { RequestLifeCycle.end(); } } - public void processExport(int exportId, String[] notesToExportIds, boolean exportAll, Identity identity) throws IOException { + public void processExport(int exportId, String[] notesToExportIds, boolean exportAll, Identity identity) throws Exception { File zipFile = null; + List> listFiles = new ArrayList<>(); + List featuredImages = new ArrayList<>(); ExportResource exportResource = notesExportService.getExportRessourceById(exportId); if (exportResource != null) { exportResource.setStatus(ExportStatus.IN_PROGRESS.name()); exportResource.getAction().setStarted(true); exportResource.getAction().setAction(ExportAction.GETTING_NOTES); Page note_ = null; - List noteToExportList = new ArrayList(); + List noteToExportList = new ArrayList<>(); if (exportAll) { for (String noteId : notesToExportIds) { try { @@ -228,6 +236,7 @@ public void processExport(int exportId, String[] notesToExportIds, boolean expor note.getWikiId(), note.getWikiType(), note.getWikiOwner()); + noteToExport.setProperties(note.getProperties()); noteToExport.setContent(processImagesForExport(note)); noteToExport.setContent(processNotesLinkForExport(noteToExport)); LinkedList ancestors = getNoteAncestorsIds(noteToExport.getId()); @@ -306,6 +315,7 @@ public void processExport(int exportId, String[] notesToExportIds, boolean expor String fileName = ""; String filePath = ""; exportResource.getAction().setJsonCreated(true); + processNoteFeaturedImages(exportResource, notesExport.getNotes(), featuredImages); exportResource.getAction().setAction(ExportAction.UPDATING_IMAGES_URLS); while (contentUpdated.contains(IMAGE_URL_REPLACEMENT_PREFIX)) { fileName = contentUpdated.split(IMAGE_URL_REPLACEMENT_PREFIX)[1].split(IMAGE_URL_REPLACEMENT_SUFFIX)[0]; @@ -313,11 +323,12 @@ public void processExport(int exportId, String[] notesToExportIds, boolean expor files.add(new File(filePath)); contentUpdated = contentUpdated.replace(IMAGE_URL_REPLACEMENT_PREFIX + fileName + IMAGE_URL_REPLACEMENT_SUFFIX, ""); } + listFiles.add(files); + listFiles.add(featuredImages); exportResource = notesExportService.getExportRessourceById(exportId); if (exportResource.getStatus().equals(ExportStatus.CANCELLED.name())) { - for (File file : files) { - cleanUp(file); - } + cleanUp(files); + cleanUp(featuredImages); notesExportService.removeExportResource(exportId); return; } @@ -328,24 +339,22 @@ public void processExport(int exportId, String[] notesToExportIds, boolean expor files.add(temp); exportResource = notesExportService.getExportRessourceById(exportId); if (exportResource.getStatus().equals(ExportStatus.CANCELLED.name())) { - for (File file : files) { - cleanUp(file); - } + cleanUp(files); + cleanUp(featuredImages); notesExportService.removeExportResource(exportId); return; } exportResource.getAction().setAction(ExportAction.CREATING_ZIP_FILE); String zipName = EXPORT_ZIP_PREFIX + exportId + EXPORT_ZIP_EXTENSION; exportResource.setZipFile(zipFile); - zipFile = zipFiles(zipName, files, notesExportService, exportId); + zipFile = zipFiles(zipName, listFiles, notesExportService, exportId); exportResource.setZipFile(zipFile); exportResource = notesExportService.getExportRessourceById(exportId); if (exportResource.getStatus().equals(ExportStatus.CANCELLED.name())) { - for (File file : files) { - cleanUp(file); - } + cleanUp(files); + cleanUp(featuredImages); if (zipFile != null) { - cleanUp(zipFile); + cleanUp(List.of(zipFile)); } notesExportService.removeExportResource(exportId); return; @@ -366,9 +375,8 @@ public void processExport(int exportId, String[] notesToExportIds, boolean expor exportResource.setStatus(ExportStatus.ZIP_CREATED.name()); exportResource.getAction().setZipCreated(true); exportResource.getAction().setAction(ExportAction.CLEANING_TEMP_FILE); - for (File file : files) { - cleanUp(file); - } + cleanUp(files); + cleanUp(featuredImages); exportResource.getAction().setAction(ExportAction.EXPORT_DATA_CREATED); } } @@ -411,8 +419,13 @@ private NoteToExport getParentOfNoteFromExistingNotes(LinkedList ancesto public NoteToExport getNoteToExport(NoteToExport note, int exportId) throws WikiException, IOException, InterruptedException { + try { - note.setContent(processImagesForExport(noteService.getNoteById(note.getId()))); + Page page = noteService.getNoteById(note.getId()); + if (page != null) { + note.setProperties(page.getProperties()); + note.setContent(processImagesForExport(page)); + } } catch (Exception e) { log.warn("Cannot process images for note {}", note.getId()); } @@ -442,12 +455,20 @@ public NoteToExport getNoteToExport(NoteToExport note, int exportId) throws Wiki public String processNotesLinkForExport(NoteToExport note) throws WikiException { String content = note.getContent(); - String noteLinkprefix = "class=\"noteLink\" href=\""; + String noteLinkprefix = "class=\"noteLink\" href=\"(?:.*?/|)(\\d+)"; String contentUpdated = content; Map urlToReplaces = new HashMap<>(); - while (contentUpdated.contains("noteLink")) { - String checkContent = contentUpdated; - String noteId = contentUpdated.split(noteLinkprefix)[1].split("\"")[0]; + Pattern pattern = Pattern.compile(noteLinkprefix); + Matcher matcher = pattern.matcher(contentUpdated); + while (matcher.find()) { + String matchedLink = matcher.group(0); + String noteId; + if (matcher.group(1) != null) { + noteId = matcher.group(1); + } else { + noteId = matcher.group(2); + } + Page linkedNote = null; try { linkedNote = noteService.getNoteById(noteId); @@ -459,11 +480,7 @@ public String processNotesLinkForExport(NoteToExport note) throws WikiException String noteParams = IMAGE_URL_REPLACEMENT_PREFIX + linkedNote.getWikiType() + IMAGE_URL_REPLACEMENT_SUFFIX + IMAGE_URL_REPLACEMENT_PREFIX + linkedNote.getWikiOwner() + IMAGE_URL_REPLACEMENT_SUFFIX + IMAGE_URL_REPLACEMENT_PREFIX + linkedNote.getName() + IMAGE_URL_REPLACEMENT_SUFFIX; - urlToReplaces.put(noteLinkprefix + linkedNote.getId() + "\"", noteLinkprefix + noteParams + "\""); - } - contentUpdated = contentUpdated.replace(noteLinkprefix + noteId + "\"", ""); - if (contentUpdated.equals(checkContent)) { - break; + urlToReplaces.put(matchedLink + "\"", "class=\"noteLink\" href=\"" + noteParams + "\""); } } if (!urlToReplaces.isEmpty()) { @@ -523,38 +540,6 @@ public String processImagesForExport(Page note) throws WikiException, IOExceptio return htmlUploadImageProcessor.processImagesForExport(content); } - private void replaceIncludedPages(Page note, Wiki wiki) throws WikiException { - Page note_ = noteService.getNoteOfNoteBookByName(wiki.getType(), wiki.getOwner(), note.getName()); - if (note_ != null) { - String content = note_.getContent(); - if (content.contains("class=\"noteLink\" href=\"//-")) { - while (content.contains("class=\"noteLink\" href=\"//-")) { - String linkedParams = content.split("class=\"noteLink\" href=\"//-")[1].split("-//\"")[0]; - String NoteName = linkedParams.split("-////-")[2]; - Page linkedNote = null; - linkedNote = noteService.getNoteOfNoteBookByName(wiki.getType(), wiki.getOwner(), NoteName); - if (linkedNote != null) { - content = content.replace("\"noteLink\" href=\"//-" + linkedParams + "-//", - "\"noteLink\" href=\"" + linkedNote.getId()); - } else { - content = content.replace("\"noteLink\" href=\"//-" + linkedParams + "-//", "\"noteLink\" href=\"" + NoteName); - } - if (content.equals(note_.getContent())) - break; - } - if (!content.equals(note_.getContent())) { - note_.setContent(content); - noteService.updateNote(note_); - } - } - } - if (note.getChildren() != null) { - for (Page child : note.getChildren()) { - replaceIncludedPages(child, wiki); - } - } - } - private String replaceUrl(String body, Map urlToReplaces) { for (String url : urlToReplaces.keySet()) { while (body.contains(url)) { @@ -586,4 +571,61 @@ private LinkedList getNoteAncestorsIds(LinkedList ancestorsIds, return ancestorsIds; } + private void processNoteFeaturedImages(ExportResource exportResource, + List notesToExport, + List files) throws Exception { + exportResource.getAction().setAction(ExportAction.PROCESS_FEATURED_IMAGES); + if (notesToExport != null) { + for (NoteToExport noteToExport : notesToExport) { + if (noteToExport != null) { + if (noteToExport.getProperties() != null) { + NotePageProperties properties = noteToExport.getProperties(); + NoteFeaturedImage featuredImage = properties.getFeaturedImage(); + if (featuredImage != null) { + FileItem imageFile = fileService.getFile(featuredImage.getId()); + if (imageFile != null && imageFile.getFileInfo() != null) { + FileInfo fileInfo = imageFile.getFileInfo(); + String extension = "." + MimeTypeUtils.parseMimeType(fileInfo.getMimetype()).getSubtype(); + String filePath = System.getProperty(TEMP_DIRECTORY_PATH) + File.separator + featuredImage.getId() + extension; + File file = new File(filePath); + FileUtils.copyInputStreamToFile(imageFile.getAsStream(), file); + files.add(file); + } + } + } + processNoteFeaturedImages(exportResource, noteToExport.getChildren(), files); + } + } + } + exportResource.getAction().setFeaturedImagesProcessed(true); + } + + private static void addFilesToZip(ZipOutputStream zipOut, + List files, + int exportId, + String parentDirectory, + NotesExportService notesExportService) throws IOException { + if (parentDirectory != null) { + ZipEntry directoryEntry = new ZipEntry(parentDirectory + File.separator); + zipOut.putNextEntry(directoryEntry); + } + for (File fileToZip : files) { + ExportResource exportResource = notesExportService.getExportRessourceById(exportId); + if (exportResource.getStatus().equals(ExportStatus.CANCELLED.name())) { + throw new InterruptedIOException(); + } + try (FileInputStream fis = new FileInputStream(fileToZip)) { + String name = parentDirectory != null ? parentDirectory + File.separator + fileToZip.getName() : fileToZip.getName(); + ZipEntry zipEntry = new ZipEntry(name); + zipOut.putNextEntry(zipEntry); + byte[] bytes = new byte[1024]; + int length; + while ((length = fis.read(bytes)) >= 0) { + zipOut.write(bytes, 0, length); + } + } catch (IOException e) { + log.warn("cannot add the file: {} to the zip", fileToZip.getName()); + } + } + } } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java b/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java index c284b095cb..2d90695617 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/NoteService.java @@ -22,10 +22,7 @@ import java.io.IOException; import java.util.List; -import java.util.Map; -import io.meeds.notes.model.NoteFeaturedImage; -import io.meeds.notes.model.NotePageProperties; import org.gatein.api.EntityNotFoundException; import org.exoplatform.commons.utils.PageList; @@ -41,6 +38,9 @@ import org.exoplatform.wiki.service.search.SearchResult; import org.exoplatform.wiki.service.search.WikiSearchData; +import io.meeds.notes.model.NoteFeaturedImage; +import io.meeds.notes.model.NotePageProperties; + /** * Provides functions for processing database with notes, including: adding, * editing, removing and searching for data. @@ -72,6 +72,22 @@ public interface NoteService { */ Page createNote(Wiki noteBook, String parentNoteName, Page note, Identity userIdentity) throws WikiException, IllegalAccessException; + + /** + * Create a new note in the given notebook, under the given parent note. + * + * @param noteBook Notebook object. + * @param parentNoteName parent note name. + * @param note the note object to create. + * @param userIdentity user Identity. + * @param importMode true if the creation is without timestamp for import mode. + * @return The new note. + * @throws WikiException if an error occured + * @throws IllegalAccessException if the user don't have edit rights to the + * parent note + */ + Page createNote(Wiki noteBook, String parentNoteName, Page note, Identity userIdentity, boolean importMode) throws WikiException, + IllegalAccessException; /** * Deletes a note. diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java b/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java index faf0b861c9..3faea9a2b2 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/NotesExportService.java @@ -27,6 +27,7 @@ import java.util.concurrent.Executors; import org.apache.commons.io.FileUtils; +import org.exoplatform.commons.file.services.FileService; import org.picocontainer.Startable; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -44,13 +45,20 @@ public class NotesExportService implements Startable { private final HTMLUploadImageProcessor htmlUploadImageProcessor; - private final ExecutorService exportThreadPool; + private final ExecutorService exportThreadPool; - public NotesExportService(NoteService noteService, WikiService wikiService, HTMLUploadImageProcessor htmlUploadImageProcessor) { + private final FileService fileService; + + public NotesExportService(NoteService noteService, + WikiService wikiService, + HTMLUploadImageProcessor htmlUploadImageProcessor, + FileService fileService) { this.noteService = noteService; this.wikiService = wikiService; this.htmlUploadImageProcessor = htmlUploadImageProcessor; - this.exportThreadPool = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Notes-Export-File-%d").build()); + this.fileService = fileService; + this.exportThreadPool = + Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Notes-Export-File-%d").build()); } @Override @@ -82,7 +90,8 @@ public void startExportNotes(int exportId, String[] notesToExportIds, boolean ex wikiService, this, htmlUploadImageProcessor, - new ExportData(exportId, notesToExportIds, exportAll, identity)), + new ExportData(exportId, notesToExportIds, exportAll, identity), + fileService), exportThreadPool); } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java b/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java index 3188ff908c..6780642feb 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/impl/NoteServiceImpl.java @@ -20,7 +20,10 @@ package org.exoplatform.wiki.service.impl; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; @@ -40,7 +43,6 @@ import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; -import org.exoplatform.wiki.jpa.entity.DraftPageEntity; import org.gatein.api.EntityNotFoundException; import com.fasterxml.jackson.core.type.TypeReference; @@ -50,7 +52,6 @@ import org.exoplatform.commons.file.model.FileInfo; import org.exoplatform.commons.file.model.FileItem; import org.exoplatform.commons.file.services.FileService; -import org.exoplatform.commons.utils.CommonsUtils; import org.exoplatform.commons.utils.ObjectPageList; import org.exoplatform.commons.utils.PageList; import org.exoplatform.services.cache.CacheService; @@ -60,6 +61,7 @@ import org.exoplatform.services.log.Log; import org.exoplatform.services.security.Identity; import org.exoplatform.services.security.IdentityConstants; +import org.exoplatform.services.thumbnail.ImageThumbnailService; import org.exoplatform.social.common.service.HTMLUploadImageProcessor; import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider; import org.exoplatform.social.core.manager.IdentityManager; @@ -70,7 +72,6 @@ import org.exoplatform.social.metadata.model.MetadataKey; import org.exoplatform.social.metadata.model.MetadataObject; import org.exoplatform.social.metadata.model.MetadataType; -import org.exoplatform.services.thumbnail.ImageThumbnailService; import org.exoplatform.upload.UploadResource; import org.exoplatform.upload.UploadService; import org.exoplatform.wiki.WikiException; @@ -104,6 +105,7 @@ import io.meeds.notes.model.NotePageProperties; import io.meeds.notes.service.NotePageViewService; import io.meeds.social.cms.service.CMSService; +import lombok.Getter; import lombok.SneakyThrows; public class NoteServiceImpl implements NoteService { @@ -115,6 +117,8 @@ public class NoteServiceImpl implements NoteService { private static final String UNTITLED_PREFIX = "Untitled_"; private static final String TEMP_DIRECTORY_PATH = "java.io.tmpdir"; + + private static final String FEATURED_IMAGE_FOLDER = "featuredImages"; private static final String FILE_NAME_SPACE = "wiki"; @@ -147,10 +151,12 @@ public class NoteServiceImpl implements NoteService { private final DataStorage dataStorage; + @Getter private final ExoCache renderingCache; private final ExoCache attachmentCountCache; + @Getter private final Map> pageLinksMap = new ConcurrentHashMap<>(); private final IdentityManager identityManager; @@ -223,22 +229,22 @@ public NoteServiceImpl(DataStorage dataStorage, this.imageThumbnailService = imageThumbnailService; this.htmlUploadImageProcessor = htmlUploadImageProcessor; } - + /** * {@inheritDoc} */ @Override - public Page createNote(Wiki noteBook, String parentNoteName, Page note, Identity userIdentity) throws WikiException, + public Page createNote(Wiki noteBook, String parentNoteName, Page note, Identity userIdentity, boolean importMode) throws WikiException, IllegalAccessException { - - String pageName = TitleResolver.getId(note.getName(), false); - if (pageName == null) { - pageName = TitleResolver.getId(note.getTitle(), false); + if (importMode) { + String pageName = TitleResolver.getId(note.getName(), false); + if (pageName == null) { + pageName = TitleResolver.getId(note.getTitle(), false); + } + note.setName(pageName); } - note.setName(pageName); - - if (isExisting(noteBook.getType(), noteBook.getOwner(), pageName)) { - throw new WikiException("Page " + noteBook.getType() + ":" + noteBook.getOwner() + ":" + pageName + if (isExisting(noteBook.getType(), noteBook.getOwner(), note.getName())) { + throw new WikiException("Page " + noteBook.getType() + ":" + noteBook.getOwner() + ":" + note.getName() + " already exists, cannot create it."); } @@ -273,6 +279,15 @@ public Page createNote(Wiki noteBook, String parentNoteName, Page note, Identity } } + /** + * {@inheritDoc} + */ + @Override + public Page createNote(Wiki noteBook, String parentNoteName, Page note, Identity userIdentity) throws WikiException, + IllegalAccessException { + return createNote(noteBook, parentNoteName, note, userIdentity, true); + } + /** * {@inheritDoc} */ @@ -412,40 +427,34 @@ public boolean deleteNote(String noteType, String noteOwner, String noteName, Id throw new EntityNotFoundException("Note to delete not found"); } Space space = spaceService.getSpaceByGroupId(note.getWikiOwner()); - if (note != null) { - if (!Utils.canManageNotes(userIdentity.getUserId(), space, note)) { - log.error("Can't delete note '" + noteName + "'. does not have edit permission on it."); - throw new IllegalAccessException("User does not have edit permissions on the note."); - } - - invalidateCachesOfPageTree(note); - invalidateAttachmentCache(note); - - // Store all children to launch post deletion listeners - List allChrildrenPages = new ArrayList<>(); - Queue queue = new LinkedList<>(); - queue.add(note); - Page tempPage; - while (!queue.isEmpty()) { - tempPage = queue.poll(); - List childrenPages = getChildrenNoteOf(tempPage, false, false); - for (Page childPage : childrenPages) { - queue.add(childPage); - allChrildrenPages.add(childPage); - } - } + if (!Utils.canManageNotes(userIdentity.getUserId(), space, note)) { + log.error("Can't delete note '" + noteName + "'. does not have edit permission on it."); + throw new IllegalAccessException("User does not have edit permissions on the note."); + } - deleteNote(noteType, noteOwner, noteName); - postDeletePage(noteType, noteOwner, noteName, note); + invalidateCachesOfPageTree(note); + invalidateAttachmentCache(note); - // Post delete activity for all children pages - for (Page childNote : allChrildrenPages) { - postDeletePage(childNote.getWikiType(), childNote.getWikiOwner(), childNote.getName(), childNote); + // Store all children to launch post deletion listeners + List allChrildrenPages = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(note); + Page tempPage; + while (!queue.isEmpty()) { + tempPage = queue.poll(); + List childrenPages = getChildrenNoteOf(tempPage, false, false); + for (Page childPage : childrenPages) { + queue.add(childPage); + allChrildrenPages.add(childPage); } + } - } else { - log.error("Can't delete note '" + noteName + "'. This note does not exist."); - return false; + deleteNote(noteType, noteOwner, noteName); + postDeletePage(noteType, noteOwner, noteName, note); + + // Post delete activity for all children pages + for (Page childNote : allChrildrenPages) { + postDeletePage(childNote.getWikiType(), childNote.getWikiOwner(), childNote.getName(), childNote); } } catch (WikiException e) { log.error("Can't delete note '" + noteName + "' ", e); @@ -1286,9 +1295,7 @@ public String getNoteRenderedContent(Page note) { * {@inheritDoc} */ @Override - public void importNotes(String zipLocation, Page parent, String conflict, Identity userIdentity) throws WikiException, - IllegalAccessException, - IOException, Exception { + public void importNotes(String zipLocation, Page parent, String conflict, Identity userIdentity) throws Exception { List files = Utils.unzip(zipLocation, System.getProperty(TEMP_DIRECTORY_PATH)); importNotes(files, parent, conflict, userIdentity); } @@ -1301,16 +1308,18 @@ public void importNotes(List files, Page parent, String conflict, Identi IllegalAccessException, IOException, Exception { + Map featuredImages = new HashMap<>(); String notesFilePath = ""; for (String file : files) { if (file.contains("notesExport_")) { - { notesFilePath = file; - break; - } + } + if (file.contains("/" + FEATURED_IMAGE_FOLDER + "/")) { + String imageId = file.substring(file.lastIndexOf("/") + 1); + featuredImages.put(imageId, file); } } - if (!notesFilePath.equals("")) { + if (!notesFilePath.isEmpty()) { ObjectMapper mapper = new ObjectMapper(); File notesFile = new File(notesFilePath); ImportList notes = mapper.readValue(notesFile, new TypeReference() { @@ -1331,12 +1340,13 @@ public void importNotes(List files, Page parent, String conflict, Identi for (Page note : notes.getNotes()) { importNote(note, parent, + featuredImages, wikiService.getWikiByTypeAndOwner(parent.getWikiType(), parent.getWikiOwner()), conflict, userIdentity); } for (Page note : notes.getNotes()) { - replaceIncludedPages(note, wiki); + replaceIncludedPages(note, wiki, userIdentity); } cleanUp(notesFile); } @@ -1502,26 +1512,6 @@ public void deleteVersionsByNoteIdAndLang(Long noteId, String lang) throws Excep } postDeletePageVersionLanguage(noteId + "-" + lang); } - - private void deleteNoteMetadataProperties(Page note, String lang, String objectType) throws Exception { - MetadataItem draftNoteMetadataItem = getNoteMetadataItem(note, lang, objectType); - if (draftNoteMetadataItem != null) { - Map properties = draftNoteMetadataItem.getProperties(); - if (properties != null && properties.getOrDefault(FEATURED_IMAGE_ID, null) != null) { - String featuredImageId = properties.get(FEATURED_IMAGE_ID); - if (note.isDraftPage() && ((DraftPage) note).getTargetPageId() != null) { - removeNoteFeaturedImage(Long.parseLong(note.getId()), - Long.parseLong(featuredImageId), - lang, - true, - Long.parseLong(identityManager.getOrCreateUserIdentity(note.getOwner()).getId())); - } else { - fileService.deleteFile(Long.parseLong(featuredImageId)); - } - } - metadataService.deleteMetadataItem(draftNoteMetadataItem.getId(), false); - } - } /** * {@inheritDoc} @@ -1531,7 +1521,6 @@ public void deleteVersionsByNoteIdAndLang(Long noteId, String userName, String l deleteVersionsByNoteIdAndLang(noteId, lang); } - /** * {@inheritDoc} */ @@ -1540,12 +1529,220 @@ public List getDraftsOfWiki(String wikiOwner, String wikiType, String return dataStorage.getDraftsOfWiki(wikiOwner, wikiType, wikiHome); } - public ExoCache getRenderingCache() { - return renderingCache; + public void removeOrphanDraftPagesByParentPage(long parentPageId) { + dataStorage.deleteOrphanDraftPagesByParentPage(parentPageId); + } + + /** + * {@inheritDoc} + */ + @Override + public Long saveNoteFeaturedImage(Page note, NoteFeaturedImage featuredImage) throws Exception { + if (featuredImage == null) { + return null; + } + long featuredImageId = featuredImage.getId() != null ? featuredImage.getId() : 0L; + String uploadId = featuredImage.getUploadId(); + if (uploadId != null) { + + UploadResource uploadResource = uploadService.getUploadResource(uploadId); + if (uploadResource != null) { + String fileDiskLocation = uploadResource.getStoreLocation(); + try (InputStream inputStream = new FileInputStream(fileDiskLocation);) { + FileItem fileItem = new FileItem(featuredImageId, + note.getName(), + featuredImage.getMimeType(), + FILE_NAME_SPACE, + inputStream.available(), + new Date(), + null, + false, + inputStream); + if (featuredImageId == 0) { + fileItem = fileService.writeFile(fileItem); + } else { + fileItem = fileService.updateFile(fileItem); + } + if (fileItem != null && fileItem.getFileInfo() != null) { + return fileItem.getFileInfo().getId(); + } + } catch (Exception e) { + log.error("Error while saving note featured image", e); + } finally { + uploadService.removeUploadResource(uploadId); + } + } + } + return featuredImageId; + } + + /** + * {@inheritDoc} + */ + @Override + public NoteFeaturedImage getNoteFeaturedImageInfo(Long noteId, + String lang, + boolean isDraft, + String thumbnailSize, + long userIdentityId) throws Exception { + if (noteId == null) { + throw new IllegalArgumentException("note id is mandatory"); + } + Page note; + org.exoplatform.social.core.identity.model.Identity identity = identityManager.getIdentity(String.valueOf(userIdentityId)); + if (isDraft) { + note = getDraftNoteById(String.valueOf(noteId), identity.getRemoteId()); + } else { + note = getNoteByIdAndLang(noteId, lang); + } + if (note == null) { + throw new ObjectNotFoundException("Note with id: " + noteId + " and lang: " + lang + " not found"); + } + + MetadataItem metadataItem = getNoteMetadataItem(note, + lang, + isDraft ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE + : NOTE_METADATA_PAGE_OBJECT_TYPE); + if (metadataItem != null && !MapUtils.isEmpty(metadataItem.getProperties())) { + String featuredImageIdProp = metadataItem.getProperties().get(FEATURED_IMAGE_ID); + long noteFeaturedImageId = featuredImageIdProp != null + && !featuredImageIdProp.equals("null") ? Long.parseLong(featuredImageIdProp) : 0L; + FileItem fileItem = fileService.getFile(noteFeaturedImageId); + if (fileItem != null && fileItem.getFileInfo() != null) { + FileInfo fileInfo = fileItem.getFileInfo(); + if (thumbnailSize != null) { + int[] dimension = org.exoplatform.social.common.Utils.parseDimension(thumbnailSize); + fileItem = imageThumbnailService.getOrCreateThumbnail(fileItem, dimension[0], dimension[1]); + } + return new NoteFeaturedImage(fileInfo.getId(), + fileInfo.getName(), + fileInfo.getMimetype(), + fileInfo.getSize(), + fileInfo.getUpdatedDate().getTime(), + fileItem.getAsStream()); + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public void removeNoteFeaturedImage(Long noteId, + Long featuredImageId, + String lang, + boolean isDraft, + Long userIdentityId) throws Exception { + boolean removeFeaturedImageFile = true; + Page note; + if (isDraft) { + DraftPage draftPage = getDraftNoteById(String.valueOf(noteId), + identityManager.getIdentity(String.valueOf(userIdentityId)).getRemoteId()); + if (draftPage != null && draftPage.getTargetPageId() != null + && isOriginalFeaturedImage(draftPage, getNoteByIdAndLang(Long.valueOf(draftPage.getTargetPageId()), lang))) { + removeFeaturedImageFile = false; + } + note = draftPage; + } else { + note = getNoteByIdAndLang(noteId, lang); + } + if (note == null) { + throw new ObjectNotFoundException("note not found"); + } + if (removeFeaturedImageFile && featuredImageId != null && featuredImageId > 0) { + fileService.deleteFile(featuredImageId); + } + MetadataItem metadataItem = getNoteMetadataItem(note, + lang, + isDraft ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE + : NOTE_METADATA_PAGE_OBJECT_TYPE); + if (metadataItem != null) { + Map properties = metadataItem.getProperties(); + properties.remove(FEATURED_IMAGE_ID); + properties.remove(FEATURED_IMAGE_UPDATED_DATE); + properties.remove(FEATURED_IMAGE_ALT_TEXT); + metadataItem.setProperties(properties); + metadataService.updateMetadataItem(metadataItem, userIdentityId, false); + } + } + + /** + * {@inheritDoc} + */ + @Override + public NotePageProperties saveNoteMetadata(NotePageProperties notePageProperties, + String lang, + Long userIdentityId) throws Exception { + if (notePageProperties == null) { + return null; + } + Page note; + Long featuredImageId = null; + NoteFeaturedImage featuredImage = notePageProperties.getFeaturedImage(); + if (notePageProperties.isDraft()) { + note = getDraftNoteById(String.valueOf(notePageProperties.getNoteId()), + identityManager.getIdentity(String.valueOf(userIdentityId)).getRemoteId()); + } else { + note = getNoteByIdAndLang(notePageProperties.getNoteId(), lang); + } + if (note == null) { + throw new ObjectNotFoundException("note not found"); + } + + if (featuredImage != null && featuredImage.isToDelete()) { + removeNoteFeaturedImage(Long.valueOf(note.getId()), + featuredImage.getId(), + lang, + notePageProperties.isDraft(), + userIdentityId); + } else { + featuredImageId = saveNoteFeaturedImage(note, featuredImage); + } + NoteMetadataObject noteMetadataObject = + buildNoteMetadataObject(note, + lang, + notePageProperties.isDraft() ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE + : NOTE_METADATA_PAGE_OBJECT_TYPE); + MetadataItem metadataItem = getNoteMetadataItem(note, + lang, + notePageProperties.isDraft() ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE + : NOTE_METADATA_PAGE_OBJECT_TYPE); + + Map properties = new HashMap<>(); + if (metadataItem != null && metadataItem.getProperties() != null) { + properties = metadataItem.getProperties(); + } + properties.put(SUMMARY_PROP, notePageProperties.getSummary()); + if (featuredImageId != null) { + properties.put(FEATURED_IMAGE_ID, String.valueOf(featuredImageId)); + properties.put(FEATURED_IMAGE_UPDATED_DATE, String.valueOf(new Date().getTime())); + properties.put(FEATURED_IMAGE_ALT_TEXT, notePageProperties.getFeaturedImage().getAltText()); + } + if (metadataItem == null) { + metadataService.createMetadataItem(noteMetadataObject, NOTES_METADATA_KEY, properties, userIdentityId, false); + } else { + metadataItem.setProperties(properties); + metadataService.updateMetadataItem(metadataItem, userIdentityId, false); + } + if (featuredImage != null) { + featuredImage.setId(featuredImageId); + featuredImage.setLastUpdated(Long.valueOf(properties.getOrDefault(FEATURED_IMAGE_UPDATED_DATE, "0"))); + featuredImage.setUploadId(null); + notePageProperties.setFeaturedImage(featuredImage); + } + return notePageProperties; } - public Map> getPageLinksMap() { - return pageLinksMap; + /** + * {@inheritDoc} + */ + @Override + public PageVersion getPageVersionById(Long versionId) { + if (versionId == null) { + throw new IllegalArgumentException("version id is mandatory"); + } + return dataStorage.getPageVersionById(versionId); } // ******* Listeners *******/ @@ -1713,10 +1910,35 @@ protected void invalidateAttachmentCache(Page note) { } /******* Private methods *******/ - - private void importNote(Page note, Page parent, Wiki wiki, String conflict, Identity userIdentity) throws WikiException, - IllegalAccessException, Exception { + private void deleteNoteMetadataProperties(Page note, String lang, String objectType) throws Exception { + MetadataItem draftNoteMetadataItem = getNoteMetadataItem(note, lang, objectType); + if (draftNoteMetadataItem != null) { + Map properties = draftNoteMetadataItem.getProperties(); + if (properties != null && properties.getOrDefault(FEATURED_IMAGE_ID, null) != null) { + String featuredImageId = properties.get(FEATURED_IMAGE_ID); + if (note.isDraftPage() && ((DraftPage) note).getTargetPageId() != null) { + removeNoteFeaturedImage(Long.parseLong(note.getId()), + Long.parseLong(featuredImageId), + lang, + true, + Long.parseLong(identityManager.getOrCreateUserIdentity(note.getOwner()).getId())); + } else { + fileService.deleteFile(Long.parseLong(featuredImageId)); + } + } + metadataService.deleteMetadataItem(draftNoteMetadataItem.getId(), false); + } + } + + private void importNote(Page note, + Page parent, + Map featuredImages, + Wiki wiki, + String conflict, + Identity userIdentity) throws Exception { + + File featuredImageFile = extractNoteFeaturedImageFileToImport(note, featuredImages); Page parent_ = getNoteOfNoteBookByName(wiki.getType(), wiki.getOwner(), parent.getName()); if (parent_ == null) { parent_ = wiki.getWikiHome(); @@ -1731,7 +1953,7 @@ private void importNote(Page note, Page parent, Wiki wiki, String conflict, Iden wiki.getOwner(), imagesSubLocationPath); note.setContent(processedContent); - note_ = createNote(wiki, parent_.getName(), note, userIdentity); + note_ = createNote(wiki, parent_.getName(), note, userIdentity, false); } else { if (StringUtils.isNotEmpty(conflict)) { if (conflict.equals("overwrite") || conflict.equals("replaceAll")) { @@ -1740,25 +1962,10 @@ private void importNote(Page note, Page parent, Wiki wiki, String conflict, Iden wiki.getOwner(), imagesSubLocationPath); note.setContent(processedContent); - note_ = createNote(wiki, parent_.getName(), note, userIdentity); + note_ = createNote(wiki, parent_.getName(), note, userIdentity, false); } if (conflict.equals("duplicate")) { - String title = note.getTitle(); - int i; - try { - i = title.lastIndexOf("_") != -1 ? Integer.valueOf(title.substring(title.lastIndexOf("_") + 1)) + 1 : 1; - } catch (NumberFormatException e) { - i = 1; - } - String newTitle = note.getTitle() + "_" + i; - while (getNoteOfNoteBookByName(wiki.getType(), wiki.getOwner(), newTitle) != null - || isExisting(wiki.getType(), wiki.getOwner(), TitleResolver.getId(newTitle, false))) { - i++; - newTitle = note.getTitle() + "_" + i; - } - note.setName(newTitle); - note.setTitle(newTitle); String processedContent = htmlUploadImageProcessor.processSpaceImages(note.getContent(), wiki.getOwner(), imagesSubLocationPath); @@ -1793,9 +2000,14 @@ private void importNote(Page note, Page parent, Wiki wiki, String conflict, Iden } } } + if (featuredImageFile != null) { + saveImportedFeaturedImage(featuredImageFile, + note, + Long.parseLong(identityManager.getOrCreateUserIdentity(userIdentity.getUserId()).getId())); + } if (note.getChildren() != null) { for (Page child : note.getChildren()) { - importNote(child, note_, wiki, conflict, userIdentity); + importNote(child, note_, featuredImages, wiki, conflict, userIdentity); } } } @@ -1909,47 +2121,23 @@ private String getNoteTitleWithTraduction(Page note, Identity userIdentity, Stri return note.getTitle(); } - private LinkedList getNoteAncestorsIds(String noteId) throws WikiException { - return getNoteAncestorsIds(null, noteId); - } - - private LinkedList getNoteAncestorsIds(LinkedList ancestorsIds, String noteId) throws WikiException { - if (ancestorsIds == null) { - ancestorsIds = new LinkedList<>(); - } - if (noteId == null) { - return ancestorsIds; - } - Page note = getNoteById(noteId); - String parentId = note.getParentPageId(); - - if (parentId != null) { - ancestorsIds.push(parentId); - getNoteAncestorsIds(ancestorsIds, parentId); - } - - return ancestorsIds; - } - private String getDraftNameSuffix(long clientTime) { return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date(clientTime)); } - private void replaceIncludedPages(Page note, Wiki wiki) throws WikiException { + private void replaceIncludedPages(Page note, Wiki wiki, Identity userIdentity) throws WikiException { Page note_ = getNoteOfNoteBookByName(wiki.getType(), wiki.getOwner(), note.getName()); if (note_ != null) { String content = note_.getContent(); if (content.contains("class=\"noteLink\" href=\"//-")) { while (content.contains("class=\"noteLink\" href=\"//-")) { String linkedParams = content.split("class=\"noteLink\" href=\"//-")[1].split("-//\"")[0]; - String noteBookType = linkedParams.split("-////-")[0]; - String noteBookOwner = linkedParams.split("-////-")[1]; String NoteName = linkedParams.split("-////-")[2]; Page linkedNote = null; linkedNote = getNoteOfNoteBookByName(wiki.getType(), wiki.getOwner(), NoteName); if (linkedNote != null) { content = content.replace("\"noteLink\" href=\"//-" + linkedParams + "-//", - "\"noteLink\" href=\"" + linkedNote.getId()); + "\"noteLink\" href=\"" + linkedNote.getUrl()); } else { content = content.replace("\"noteLink\" href=\"//-" + linkedParams + "-//", "\"noteLink\" href=\"" + NoteName); } @@ -1959,25 +2147,17 @@ private void replaceIncludedPages(Page note, Wiki wiki) throws WikiException { if (!content.equals(note_.getContent())) { note_.setContent(content); updateNote(note_); + createVersionOfNote(note_, userIdentity.getUserId()); } } } if (note.getChildren() != null) { for (Page child : note.getChildren()) { - replaceIncludedPages(child, wiki); + replaceIncludedPages(child, wiki, userIdentity); } } } - private String replaceUrl(String body, Map urlToReplaces) { - for (String url : urlToReplaces.keySet()) { - while (body.contains(url)) { - body = body.replace(url, urlToReplaces.get(url)); - } - } - return body; - } - private void addAllNodes(Page note, List listOfNotes) throws WikiException { if (note != null) { listOfNotes.add(note); @@ -2009,102 +2189,6 @@ private Map> retrieveMetadataItems(String noteId, Str return metadata; } - /** - * {@inheritDoc} - */ - @Override - public void removeOrphanDraftPagesByParentPage(long parentPageId) { - dataStorage.deleteOrphanDraftPagesByParentPage(parentPageId); - } - - /** - * {@inheritDoc} - */ - @Override - public Long saveNoteFeaturedImage(Page note, NoteFeaturedImage featuredImage) throws Exception { - if (featuredImage == null) { - return null; - } - long featuredImageId = featuredImage.getId() != null ? featuredImage.getId(): 0L; - String uploadId = featuredImage.getUploadId(); - if (uploadId != null) { - - UploadResource uploadResource = uploadService.getUploadResource(uploadId); - if (uploadResource != null) { - String fileDiskLocation = uploadResource.getStoreLocation(); - try (InputStream inputStream = new FileInputStream(fileDiskLocation);) { - FileItem fileItem = new FileItem(featuredImageId, - note.getName(), - featuredImage.getMimeType(), - FILE_NAME_SPACE, - inputStream.available(), - new Date(), - null, - false, - inputStream); - if (featuredImageId == 0) { - fileItem = fileService.writeFile(fileItem); - } else { - fileItem = fileService.updateFile(fileItem); - } - if (fileItem != null && fileItem.getFileInfo() != null) { - return fileItem.getFileInfo().getId(); - } - } catch (Exception e) { - log.error("Error while saving note featured image", e); - } finally { - uploadService.removeUploadResource(uploadId); - } - } - } - return featuredImageId; - } - - /** - * {@inheritDoc} - */ - @Override - public NoteFeaturedImage getNoteFeaturedImageInfo(Long noteId, String lang, boolean isDraft, String thumbnailSize, long userIdentityId) throws Exception { - if (noteId == null) { - throw new IllegalArgumentException("note id is mandatory"); - } - Page note; - org.exoplatform.social.core.identity.model.Identity identity = identityManager.getIdentity(String.valueOf(userIdentityId)); - if (isDraft) { - note = getDraftNoteById(String.valueOf(noteId), identity.getRemoteId()); - } else { - note = getNoteByIdAndLang(noteId, lang); - } - if (note == null) { - throw new ObjectNotFoundException("Note with id: " + noteId + " and lang: " + lang + " not found"); - } - - MetadataItem metadataItem = getNoteMetadataItem(note, - lang, - isDraft ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE - : NOTE_METADATA_PAGE_OBJECT_TYPE); - if (metadataItem != null && !MapUtils.isEmpty(metadataItem.getProperties())) { - String featuredImageIdProp = metadataItem.getProperties().get(FEATURED_IMAGE_ID); - long noteFeaturedImageId = featuredImageIdProp != null - && !featuredImageIdProp.equals("null") ? Long.parseLong(featuredImageIdProp) : 0L; - FileItem fileItem = fileService.getFile(noteFeaturedImageId); - if (fileItem != null && fileItem.getFileInfo() != null) { - FileInfo fileInfo = fileItem.getFileInfo(); - if (thumbnailSize != null) { - int[] dimension = org.exoplatform.social.common.Utils.parseDimension(thumbnailSize); - fileItem = imageThumbnailService.getOrCreateThumbnail(fileItem, dimension[0], dimension[1]); - } - return new NoteFeaturedImage(fileInfo.getId(), - fileInfo.getName(), - fileInfo.getMimetype(), - fileInfo.getSize(), - fileInfo.getUpdatedDate().getTime(), - fileItem.getAsStream()); - } - } - return null; - } - private NoteMetadataObject buildNoteMetadataObject(Page note, String lang, String objectType) { Space space = spaceService.getSpaceByGroupId(note.getWikiOwner()); long spaceId = space != null ? Long.parseLong(space.getId()) : 0L; @@ -2156,7 +2240,7 @@ private void copyNotePageProperties(Page oldNote, } } } - + private boolean isOriginalFeaturedImage(Page draftPage, Page targetPage) { if (draftPage == null || targetPage == null) { return false; @@ -2169,122 +2253,53 @@ private boolean isOriginalFeaturedImage(Page draftPage, Page targetPage) { return draftFeaturedImage != null && targetFeaturedImage != null && targetFeaturedImage.getId().equals(draftFeaturedImage.getId()); } - - /** - * {@inheritDoc} - */ - @Override - public void removeNoteFeaturedImage(Long noteId, - Long featuredImageId, - String lang, - boolean isDraft, - Long userIdentityId) throws Exception { - boolean removeFeaturedImageFile = true; - Page note; - if (isDraft) { - DraftPage draftPage = getDraftNoteById(String.valueOf(noteId), - identityManager.getIdentity(String.valueOf(userIdentityId)).getRemoteId()); - if (draftPage != null && draftPage.getTargetPageId() != null - && isOriginalFeaturedImage(draftPage, getNoteByIdAndLang(Long.valueOf(draftPage.getTargetPageId()), lang))) { - removeFeaturedImageFile = false; - } - note = draftPage; - } else { - note = getNoteByIdAndLang(noteId, lang); - } - if (note == null) { - throw new ObjectNotFoundException("note not found"); - } - if (removeFeaturedImageFile && featuredImageId != null && featuredImageId > 0) { - fileService.deleteFile(featuredImageId); - } - MetadataItem metadataItem = getNoteMetadataItem(note, - lang, - isDraft ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE - : NOTE_METADATA_PAGE_OBJECT_TYPE); - if (metadataItem != null && metadataItem.getProperties() != null) { - Map properties = metadataItem.getProperties(); - properties.remove(FEATURED_IMAGE_ID); - properties.remove(FEATURED_IMAGE_UPDATED_DATE); - properties.remove(FEATURED_IMAGE_ALT_TEXT); - metadataItem.setProperties(properties); - metadataService.updateMetadataItem(metadataItem, userIdentityId, false); - } - } - /** - * {@inheritDoc} - */ - @Override - public NotePageProperties saveNoteMetadata(NotePageProperties notePageProperties, String lang, Long userIdentityId) throws Exception { - if (notePageProperties == null) { - return null; - } - Page note; - Long featuredImageId = null; - NoteFeaturedImage featuredImage = notePageProperties.getFeaturedImage(); - if (notePageProperties.isDraft()) { - note = getDraftNoteById(String.valueOf(notePageProperties.getNoteId()), - identityManager.getIdentity(String.valueOf(userIdentityId)).getRemoteId()); - } else { - note = getNoteByIdAndLang(notePageProperties.getNoteId(), lang); - } - if (note == null) { - throw new ObjectNotFoundException("note not found"); - } - - if (featuredImage != null && featuredImage.isToDelete()) { - removeNoteFeaturedImage(Long.valueOf(note.getId()), - featuredImage.getId(), - lang, - notePageProperties.isDraft(), - userIdentityId); - } else { - featuredImageId = saveNoteFeaturedImage(note, featuredImage); - } - NoteMetadataObject noteMetadataObject = - buildNoteMetadataObject(note, - lang, - notePageProperties.isDraft() ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE - : NOTE_METADATA_PAGE_OBJECT_TYPE); - MetadataItem metadataItem = getNoteMetadataItem(note, - lang, - notePageProperties.isDraft() ? NOTE_METADATA_DRAFT_PAGE_OBJECT_TYPE - : NOTE_METADATA_PAGE_OBJECT_TYPE); - - Map properties = new HashMap<>(); - if (metadataItem != null && metadataItem.getProperties() != null) { - properties = metadataItem.getProperties(); - } - properties.put(SUMMARY_PROP, notePageProperties.getSummary()); - if (featuredImageId != null) { - properties.put(FEATURED_IMAGE_ID, String.valueOf(featuredImageId)); - properties.put(FEATURED_IMAGE_UPDATED_DATE, String.valueOf(new Date().getTime())); - properties.put(FEATURED_IMAGE_ALT_TEXT, notePageProperties.getFeaturedImage().getAltText()); - } - if (metadataItem == null) { - metadataService.createMetadataItem(noteMetadataObject, NOTES_METADATA_KEY, properties, userIdentityId, false); - } else { - metadataItem.setProperties(properties); - metadataService.updateMetadataItem(metadataItem, userIdentityId, false); - } - if (featuredImage != null) { - featuredImage.setId(featuredImageId); - featuredImage.setLastUpdated(Long.valueOf(properties.getOrDefault(FEATURED_IMAGE_UPDATED_DATE, "0"))); - featuredImage.setUploadId(null); - notePageProperties.setFeaturedImage(featuredImage); + private File extractNoteFeaturedImageFileToImport(Page note, Map featuredImages) { + File featuredImageFile = null; + NotePageProperties properties = note.getProperties(); + if (properties != null && properties.getFeaturedImage() != null) { + NoteFeaturedImage featuredImage = properties.getFeaturedImage(); + String path = featuredImages.getOrDefault(String.valueOf(featuredImage.getId()), null); + if (path != null) { + featuredImageFile = new File(path); + } } - return notePageProperties; - } - - /** - * {@inheritDoc} - */ - @Override - public PageVersion getPageVersionById(Long versionId) { - if (versionId == null) { - throw new IllegalArgumentException("version id is mandatory"); + return featuredImageFile; + } + + private void saveImportedFeaturedImage(File featuredImage, Page note, long userIdentityId) { + try (InputStream inputStream = new FileInputStream(featuredImage)) { + String mimeType = Files.probeContentType(featuredImage.toPath()); + FileItem fileItem = new FileItem(0L, + note.getName(), + mimeType, + FILE_NAME_SPACE, + featuredImage.length(), + new Date(), + null, + false, + inputStream); + fileItem = fileService.writeFile(fileItem); + NoteMetadataObject noteMetadataObject = buildNoteMetadataObject(note, note.getLang(), NOTE_METADATA_PAGE_OBJECT_TYPE); + MetadataItem metadataItem = getNoteMetadataItem(note, note.getLang(), NOTE_METADATA_PAGE_OBJECT_TYPE); + Map properties = new HashMap<>(); + if (metadataItem != null && metadataItem.getProperties() != null) { + properties = metadataItem.getProperties(); + } + if (fileItem != null && fileItem.getFileInfo() != null) { + FileInfo fileInfo = fileItem.getFileInfo(); + properties.put(FEATURED_IMAGE_ID, String.valueOf(fileInfo.getId())); + properties.put(FEATURED_IMAGE_UPDATED_DATE, String.valueOf(new Date().getTime())); + properties.put(FEATURED_IMAGE_ALT_TEXT, note.getProperties().getFeaturedImage().getAltText()); + } + if (metadataItem == null) { + metadataService.createMetadataItem(noteMetadataObject, NOTES_METADATA_KEY, properties, userIdentityId); + } else { + metadataItem.setProperties(properties); + metadataService.updateMetadataItem(metadataItem, userIdentityId); + } + } catch (Exception e) { + log.error("Error while saving imported featured image"); } - return dataStorage.getPageVersionById(versionId); } } diff --git a/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java b/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java index 14ce12386b..10f9630f41 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/service/rest/NotesRestService.java @@ -23,7 +23,18 @@ import java.io.InputStream; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.Deque; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.Set; import java.util.stream.Collectors; import javax.annotation.security.RolesAllowed; @@ -46,13 +57,12 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; -import org.exoplatform.commons.comparators.NaturalComparator; -import org.exoplatform.wiki.tree.PageTreeNode; import org.gatein.api.EntityNotFoundException; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.exoplatform.common.http.HTTPStatus; +import org.exoplatform.commons.comparators.NaturalComparator; import org.exoplatform.commons.exception.ObjectNotFoundException; import org.exoplatform.commons.utils.CommonsUtils; import org.exoplatform.commons.utils.HTMLSanitizer; @@ -93,6 +103,7 @@ import org.exoplatform.wiki.service.search.TitleSearchResult; import org.exoplatform.wiki.service.search.WikiSearchData; import org.exoplatform.wiki.tree.JsonNodeData; +import org.exoplatform.wiki.tree.PageTreeNode; import org.exoplatform.wiki.tree.TreeNode; import org.exoplatform.wiki.tree.TreeNode.TREETYPE; import org.exoplatform.wiki.tree.WikiTreeNode; @@ -1365,7 +1376,6 @@ public Response getAvailableLanguages(@Context @GET @Path( "/illustration/{noteId}") - @RolesAllowed("users") @Operation( summary = "Gets a note featured image illustration by note Id", description = "Gets a note featured image illustration by note Id", diff --git a/notes-service/src/main/java/org/exoplatform/wiki/utils/Utils.java b/notes-service/src/main/java/org/exoplatform/wiki/utils/Utils.java index fcd03dea79..de21262969 100644 --- a/notes-service/src/main/java/org/exoplatform/wiki/utils/Utils.java +++ b/notes-service/src/main/java/org/exoplatform/wiki/utils/Utils.java @@ -25,6 +25,9 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -685,32 +688,54 @@ public static String getWikiAppNameInSpace(String spaceGroupId) { public static List unzip(String zipFilePath, String folderPath) throws IOException { - List files = new ArrayList<>(); - File destDir = new File(folderPath); - if (!destDir.exists()) { - destDir.mkdir(); - } - try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))){ - ZipEntry entry = zipIn.getNextEntry(); - while (entry != null) { - String filePath = folderPath + File.separator + entry.getName(); - if (!entry.isDirectory()) { - extractFile(zipIn, filePath); - files.add(filePath); + Path destDirPath = Paths.get(folderPath).toAbsolutePath().normalize(); + if (!Files.exists(destDirPath)) { + Files.createDirectories(destDirPath); + } + + List extractedFiles = new ArrayList<>(); + + try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) { + ZipEntry entry; + + while ((entry = zipIn.getNextEntry()) != null) { + Path entryPath = Paths.get(entry.getName()).normalize(); + Path targetPath = destDirPath.resolve(entryPath); + + if (!targetPath.toAbsolutePath().startsWith(destDirPath)) { + throw new IOException("Potential Zip Slip detected: " + entry.getName()); + } + + if (entry.isDirectory()) { + Files.createDirectories(targetPath); } else { - File dir = new File(filePath); - dir.mkdirs(); + Path parentDir = targetPath.getParent(); + if (parentDir != null && !Files.exists(parentDir)) { + Files.createDirectories(parentDir); + } + + extractFile(zipIn, targetPath.toFile()); + extractedFiles.add(targetPath.toString()); } + zipIn.closeEntry(); - entry = zipIn.getNextEntry(); } } - return files; + return extractedFiles; } + private static void extractFile(ZipInputStream zipIn, File targetFile) throws IOException { + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile))) { + byte[] buffer = new byte[1024]; + int len; + while ((len = zipIn.read(buffer)) > 0) { + bos.write(buffer, 0, len); + } + } + } public static void extractFile(ZipInputStream zipIn, String filePath) throws IOException { - try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));) { + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));) { byte[] bytesIn = new byte[4096]; int read = 0; while ((read = zipIn.read(bytesIn)) != -1) { diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ar.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ar.properties index 9e31a17d09..d7f9f9470c 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ar.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ar.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=تأكيد popup.msg.confirmation=تأكيد diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_aro.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_aro.properties index 768b59c733..ab1300855c 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_aro.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_aro.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=تأكيد popup.msg.confirmation=تأكيد diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_az.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_az.properties index 8b61a2e120..3508f3eb57 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_az.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_az.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Təsdiqlə popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ca.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ca.properties index 14eb07d803..077269b26f 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ca.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ca.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirma popup.msg.confirmation=Confirmació diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ceb.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ceb.properties index 96648a4a21..cf3ac96d64 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ceb.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ceb.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Ang pagkompirma diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_co.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_co.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_co.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_co.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_cs.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_cs.properties index 8775bf3e0a..56575c03bb 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_cs.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_cs.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Potvrdit popup.msg.confirmation=Potvrzení diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_de.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_de.properties index 06ad10d6b6..0b4d828744 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_de.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_de.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Fehler beim Speichern der Notizeigenschaften notes.featuredImage.remove.error.message=Fehler beim Entfernen des Bildes notes.featuredImage.remove.success.message=Bild erfolgreich entfernt notes.featuredImage.size.error.message=Empfohlene Bildgröße sollte kleiner oder gleich 20MB sein -notes.metadata.close.drawer=Seitenfenster schließen popup.confirm=Bestätigen popup.msg.confirmation=Bestätigung diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_el.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_el.properties index 4cf6fb5541..b6032d5a34 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_el.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_el.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Επιβεβαίωση popup.msg.confirmation=Επιβεβαίωση diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties index abaa30ab0a..fad91ccbef 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_en.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation @@ -92,6 +91,7 @@ notes.export.status.label.preparingNotes=Preparing notes to export notes.export.status.label.updatingNoteParents=Updating notes parents notes.export.status.label.creatingJson=Creating notes content notes.export.status.label.updatingImages=Updating images urls +notes.export.status.label.processingFeaturedImages=Processing featured images notes.export.status.label.creatingZip=Creating zip file notes.export.status.label.cleaningTemps=Cleaning temp files notes.export.status.label.done=Export done diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_es_ES.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_es_ES.properties index 25f3168167..640d0f1f7f 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_es_ES.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_es_ES.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirmar popup.msg.confirmation=Confirmación diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_eu.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_eu.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_eu.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_eu.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fa.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fa.properties index 8816065c22..736035cbc9 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fa.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fa.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=تایید popup.msg.confirmation=تاییدیه diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fi.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fi.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fi.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fi.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fil.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fil.properties index 10c5e1f3cb..7023ba4342 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fil.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fil.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Kumpirmahin popup.msg.confirmation=Ang Kumpirmasyon diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties index 29461e254b..cb0a238b47 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_fr.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Erreur lors de l'enregistrement des propriét notes.featuredImage.remove.error.message=Erreur lors de la suppression de l'illustration notes.featuredImage.remove.success.message=Illustration supprimée avec succès notes.featuredImage.size.error.message=La taille de l'illustration doit être inférieure ou égale à 20Mo -notes.metadata.close.drawer=Fermer le panneau popup.confirm=Confirmer popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hi.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hi.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hi.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hi.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hu.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hu.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hu.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_hu.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_id.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_id.properties index 9df5eba69b..43ad6fbb01 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_id.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_id.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Konfirmasi popup.msg.confirmation=Konfirmasi diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_it.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_it.properties index 5df38a338e..8cc54c4a03 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_it.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_it.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confermare popup.msg.confirmation=Conferma diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ja.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ja.properties index d363145451..d09a32ce69 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ja.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ja.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=確認 popup.msg.confirmation=確認 diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ko.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ko.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ko.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ko.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_lt.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_lt.properties index 9872b182ba..81dbca5b56 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_lt.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_lt.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Patvirtinti popup.msg.confirmation=Patvirtinimas diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ms.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ms.properties index 65c969343d..8c9532efbc 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ms.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ms.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Mengesahkan popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_nl.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_nl.properties index 34f60f3fab..bbe0439258 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_nl.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_nl.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Bevestig popup.msg.confirmation=Bevestiging diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_no.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_no.properties index a0886856d7..a41e86f1d3 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_no.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_no.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Bekreft popup.msg.confirmation=Bekreftelse diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pcm.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pcm.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pcm.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pcm.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pl.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pl.properties index b65a056f1a..a30f113e1b 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pl.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pl.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Potwierdź popup.msg.confirmation=Potwierdź diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_BR.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_BR.properties index e0d8a8c355..bc1dcd1034 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_BR.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_BR.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirmar popup.msg.confirmation=Confirmação diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_PT.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_PT.properties index 4b456d6077..be3d642aaf 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_PT.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_pt_PT.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirmar popup.msg.confirmation=Confirmação diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ro.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ro.properties index 90bd3aaf16..b79cd7ef80 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ro.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ro.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirmă popup.msg.confirmation=Confirmare diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ru.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ru.properties index c0e179b196..2eb770ec85 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ru.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ru.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Подтвердить popup.msg.confirmation=Подтверждение diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sk.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sk.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sk.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sk.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sl.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sl.properties index 023d2d4e79..73f3feb300 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sl.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sl.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Potrdi popup.msg.confirmation=Potrditev diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sq.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sq.properties index 04443fc167..fc66d2780d 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sq.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sq.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=crwdns90792:0crwdne90792:0 notes.featuredImage.remove.error.message=crwdns90794:0crwdne90794:0 notes.featuredImage.remove.success.message=crwdns90796:0crwdne90796:0 notes.featuredImage.size.error.message=crwdns90798:0crwdne90798:0 -notes.metadata.close.drawer=crwdns90800:0crwdne90800:0 popup.confirm=crwdns44690:0crwdne44690:0 popup.msg.confirmation=crwdns44692:0crwdne44692:0 diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sv_SE.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sv_SE.properties index bc28e2a248..f1622bcb29 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sv_SE.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_sv_SE.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Bekräfta popup.msg.confirmation=Bekräfta diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_th.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_th.properties index abaa30ab0a..0345abbb74 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_th.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_th.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Confirm popup.msg.confirmation=Confirmation diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tl.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tl.properties index af6c78dfc6..23cee31e4d 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tl.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tl.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Kumpirmahin popup.msg.confirmation=Ang kumpermasyon diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tr.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tr.properties index 7c4044a96e..6af9c77858 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tr.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_tr.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Onayla popup.msg.confirmation=Onay diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_uk.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_uk.properties index 83d240d8f6..b30b758123 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_uk.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_uk.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Підтвердити popup.msg.confirmation=Повторіть пароль diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ur_IN.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ur_IN.properties index 3b3fe69d82..63adfdda62 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ur_IN.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_ur_IN.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=تصدیق کریں popup.msg.confirmation=تصدیق diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_vi.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_vi.properties index 44b4410bfa..837e1f9abb 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_vi.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_vi.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=Xác nhận popup.msg.confirmation=Xác nhận diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_CN.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_CN.properties index 0eff4b89f7..c9b428b69c 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_CN.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_CN.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=确认 popup.msg.confirmation=确认 diff --git a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_TW.properties b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_TW.properties index 871099662c..4305026041 100644 --- a/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_TW.properties +++ b/notes-webapp/src/main/resources/locale/portlet/notes/notesPortlet_zh_TW.properties @@ -63,7 +63,6 @@ notes.metadata.saved.success.error=Error while saving note properties notes.featuredImage.remove.error.message=Error while removing featured image notes.featuredImage.remove.success.message=Featured image removed successfully notes.featuredImage.size.error.message=Featured image size should be less or equals to 20MB -notes.metadata.close.drawer=Close the drawer popup.confirm=確認 popup.msg.confirmation=確認 diff --git a/notes-webapp/src/main/webapp/WEB-INF/conf/wiki/notification-configuration.xml b/notes-webapp/src/main/webapp/WEB-INF/conf/wiki/notification-configuration.xml index 9b211431a0..fb9ed83b4b 100644 --- a/notes-webapp/src/main/webapp/WEB-INF/conf/wiki/notification-configuration.xml +++ b/notes-webapp/src/main/webapp/WEB-INF/conf/wiki/notification-configuration.xml @@ -23,7 +23,7 @@ UINotification.label.note - 120 + 300 diff --git a/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml b/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml index 521ad8296d..41917e491b 100644 --- a/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml +++ b/notes-webapp/src/main/webapp/WEB-INF/gatein-resources.xml @@ -31,6 +31,7 @@ NotesEditor Enterprise Notes + ImageCropper diff --git a/notes-webapp/src/main/webapp/skin/less/notes/notes.less b/notes-webapp/src/main/webapp/skin/less/notes/notes.less index 8eca2b4159..65d9f1a229 100644 --- a/notes-webapp/src/main/webapp/skin/less/notes/notes.less +++ b/notes-webapp/src/main/webapp/skin/less/notes/notes.less @@ -218,12 +218,6 @@ background-color: @primaryBackground !important; } - .image-pre-upload { - .v-image__image { - filter: blur(2px); - } - } - .cke_bottom { height: auto; opacity: 0.4; diff --git a/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue b/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue index 8ad41f48ee..287b8986cb 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes-editor/components/NotesEditorDashboard.vue @@ -139,7 +139,7 @@ export default { && !this.propertiesModified && !this.draftNote) || this.savingDraft; }, noteNotModified() { - return this.note?.title === this.originalNote?.title && this.note?.content === this.originalNote?.content; + return this.note?.title === this.originalNote?.title && this.$noteUtils.isSameContent(this.note?.content, this.originalNote?.content); }, propertiesModified() { return JSON.stringify(this.note?.properties) !== JSON.stringify(this.originalNote?.properties); @@ -370,6 +370,10 @@ export default { return; } + if (!this.note?.title?.length && !this.note?.content?.length) { + return; + } + // if the Note is not updated, no need to autosave anymore if ((this.note?.title === this.actualNote.title) && (this.note?.content === this.actualNote.content) && (JSON.stringify(this.note?.properties) === JSON.stringify(this.actualNote?.properties))) { @@ -411,9 +415,8 @@ export default { this.displayDraftMessage(); }, this.autoSaveDelay / 2); this.initActualNoteDone = true; - } else { - this.draftNote = latestDraft; } + this.draftNote = latestDraft; } else { return this.$notesService.getNoteById(id, lang) .then(data => { @@ -546,7 +549,7 @@ export default { } if (draftNote.properties) { draftNote.properties.draft = true; - if (this.newTranslation) { + if (this.newTranslation && !this.featuredImageUpdated) { draftNote.properties.featuredImage = null; } } diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorFeaturedImageDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorFeaturedImageDrawer.vue index b77daf75f3..4751c535c9 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorFeaturedImageDrawer.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorFeaturedImageDrawer.vue @@ -26,6 +26,7 @@ :src="featuredImageLink" :max-file-size="maxFileSize" :crop-options="cropOptions" + use-format alt @input="uploadId = $event" @data="imageData = $event" @@ -38,7 +39,6 @@ export default { return { uploadId: null, maxFileSize: 20971520, - format: 'landscape', imageData: null, featuredImageAltText: null, hasFeaturedImageValue: false, diff --git a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue index f9576dacb9..970319b5bb 100644 --- a/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue +++ b/notes-webapp/src/main/webapp/vue-app/notes-rich-editor/components/NoteEditorMetadataDrawer.vue @@ -43,12 +43,6 @@

{{ $t('notes.metadata.featuredImage.label') }}

-