Skip to content
Snippets Groups Projects
Commit 012f60fe authored by gnaegi's avatar gnaegi
Browse files

OO-2533 implement better filter for meta files for macOS, centralized code and unit test

parent 5334af08
No related branches found
No related tags found
No related merge requests found
Showing
with 109 additions and 24 deletions
......@@ -45,6 +45,7 @@ import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.helpers.GUISettings;
import org.olat.core.helpers.Settings;
import org.olat.core.util.FileUtils;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
import org.olat.core.util.WebappHelper;
......@@ -318,10 +319,9 @@ public class LayoutAdminController extends FormBasicController {
return false;
}
// remove unwanted meta-dirs
if (name.equalsIgnoreCase("CVS")) return false;
if (name.equalsIgnoreCase(".DS_Store")) return false;
if (name.equalsIgnoreCase(".sass-cache")) return false;
if (name.equalsIgnoreCase(".hg")) return false;
if (FileUtils.isMetaFilename(name)) {
return false;
}
return true;
}
}
......
......@@ -26,7 +26,6 @@
package org.olat.core.commons.modules.bc.notifications;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
......@@ -51,6 +50,7 @@ import org.olat.core.id.Identity;
import org.olat.core.id.context.BusinessControlFactory;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils;
import org.olat.core.util.Util;
import org.olat.core.util.resource.OresHelper;
import org.olat.group.BusinessGroup;
......@@ -69,7 +69,6 @@ import org.olat.repository.RepositoryManager;
*/
public class FolderNotificationsHandler implements NotificationsHandler {
private static final OLog log = Tracing.createLoggerFor(FolderNotificationsHandler.class);
public static final List<String> EXCLUDE_PREFIXES = Arrays.asList(".DS_Store",".CVS",".nfs",".sass-cache",".hg");
/**
*
......@@ -113,7 +112,7 @@ public class FolderNotificationsHandler implements NotificationsHandler {
// don't show changes in meta-directories. first quick check
// for any dot files and then compare with our black list of
// known exclude prefixes
if (title != null && title.indexOf("/.") != -1 && EXCLUDE_PREFIXES.parallelStream().anyMatch(title::contains)) {
if (title != null && title.indexOf("/.") != -1 && FileUtils.isMetaFilename(title)) {
// skip this file, continue with next item in folder
continue;
}
......
......@@ -46,6 +46,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.text.Normalizer;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -78,7 +79,8 @@ public class FileUtils {
public static char[] FILE_NAME_FORBIDDEN_CHARS = { '/', '\n', '\r', '\t', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':', ',' };
//private static char[] FILE_NAME_ACCEPTED_CHARS = { 'ä', 'Ä', 'ü', 'Ü', 'ö', 'Ö', ' '};
public static char[] FILE_NAME_ACCEPTED_CHARS = { '\u0228', '\u0196', '\u0252', '\u0220', '\u0246', '\u0214', ' '};
// known metadata files
public static final List<String> META_FILENAMES = Arrays.asList(".DS_Store",".CVS",".nfs",".sass-cache",".hg");
/**
* @param sourceFile
......@@ -1010,6 +1012,31 @@ public class FileUtils {
}
}
/**
* Check if the given filename is a metadata filename generated by macOS or
* windows when browsing a directory or generated by one of the known
* repository systems.
*
* @param filename
* @return
*/
public static boolean isMetaFilename(String filename) {
boolean isMeta = false;
if (filename != null) {
// 1) check for various known filenames
isMeta = META_FILENAMES.parallelStream().anyMatch(filename::contains);
if (!isMeta) {
// 2) macOS meta files generated with WebDAV starts with ._
isMeta = filename.startsWith("._");
}
}
return isMeta;
}
public static String rename(File f) {
String filename = f.getName();
String newName = filename;
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.core.util.vfs.filters;
import org.olat.core.util.FileUtils;
import org.olat.core.util.vfs.VFSItem;
/**
* Initial date: 13.02.2017<br>
* @author gnaegi, gnaegi@frentix.com, http://www.frentix.com
*
* Check if the given filename is a metadata filename generated by macOS or
* windows when browsing a directory or generated by one of the known
* repository systems.
*/
public class VFSItemMetaFilter implements VFSItemFilter {
@Override
public boolean accept(VFSItem vfsItem) {
if (vfsItem == null) {
return false;
}
return !FileUtils.isMetaFilename(vfsItem.getName());
}
}
......@@ -29,6 +29,7 @@ import org.olat.core.commons.services.image.ImageService;
import org.olat.core.gui.components.htmlheader.jscss.CustomCSS;
import org.olat.core.helpers.GUISettings;
import org.olat.core.helpers.Settings;
import org.olat.core.util.FileUtils;
import org.olat.core.util.StringHelper;
import org.olat.core.util.UserSession;
import org.olat.core.util.WebappHelper;
......@@ -70,10 +71,7 @@ public class CourseLayoutHelper {
public boolean accept(VFSItem it) {
if (!(it instanceof VFSContainer)) return false;
// remove unwanted meta-dirs
else if (it.getName().equalsIgnoreCase("CVS")) return false;
else if (it.getName().equalsIgnoreCase(".DS_Store")) return false;
else if (it.getName().equalsIgnoreCase(".sass-cache")) return false;
else if (it.getName().equalsIgnoreCase(".hg")) return false;
else if (FileUtils.isMetaFilename(it.getName())) return false;
// last check is blacklist
return !(layoutBlacklist.contains(it.getName()));
}
......
......@@ -40,9 +40,8 @@ import org.olat.core.util.openxml.OpenXMLDocument.Style;
import org.olat.core.util.vfs.LocalFileImpl;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.filters.VFSItemExcludePrefixFilter;
import org.olat.core.util.vfs.filters.VFSItemMetaFilter;
import org.olat.modules.fo.archiver.MessageNode;
import org.olat.modules.fo.ui.MessageEditController;
/**
*
......@@ -52,7 +51,7 @@ import org.olat.modules.fo.ui.MessageEditController;
*/
public class ForumOpenXMLFormatter extends ForumFormatter {
private final VFSItemExcludePrefixFilter filter = new VFSItemExcludePrefixFilter(MessageEditController.ATTACHMENT_EXCLUDE_PREFIXES);
private final VFSItemMetaFilter filter = new VFSItemMetaFilter();
private boolean firstThread = true;
......
......@@ -34,7 +34,7 @@ import org.olat.core.gui.util.CSSHelper;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.filters.VFSItemExcludePrefixFilter;
import org.olat.core.util.vfs.filters.VFSItemMetaFilter;
import org.olat.portfolio.manager.EPFrontendManager;
import org.olat.portfolio.model.artefacts.AbstractArtefact;
......@@ -50,7 +50,6 @@ import org.olat.portfolio.model.artefacts.AbstractArtefact;
public class ForumArtefactDetailsController extends BasicController {
private final VelocityContainer vC;
protected static final String[] ATTACHMENT_EXCLUDE_PREFIXES = new String[]{".nfs", ".CVS", ".DS_Store"}; // see: MessageEditController.ATTACHMENT_EXCLUDE_PREFIXES
public ForumArtefactDetailsController(UserRequest ureq, WindowControl wControl, AbstractArtefact artefact) {
super(ureq, wControl);
......@@ -60,7 +59,7 @@ public class ForumArtefactDetailsController extends BasicController {
vC.contextPut("text", ePFMgr.getArtefactFullTextContent(fArtefact));
VFSContainer artContainer = ePFMgr.getArtefactContainer(artefact);
if (artContainer!=null && artContainer.getItems().size()!=0){
List<VFSItem> attachments = new ArrayList<VFSItem>(artContainer.getItems(new VFSItemExcludePrefixFilter(ATTACHMENT_EXCLUDE_PREFIXES)));
List<VFSItem> attachments = new ArrayList<VFSItem>(artContainer.getItems(new VFSItemMetaFilter()));
int i=1; //vc-shift!
for (VFSItem vfsItem : attachments) {
VFSLeaf file = (VFSLeaf) vfsItem;
......
......@@ -66,7 +66,7 @@ import org.olat.core.util.vfs.LocalFolderImpl;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.filters.VFSItemExcludePrefixFilter;
import org.olat.core.util.vfs.filters.VFSItemMetaFilter;
import org.olat.modules.fo.Forum;
import org.olat.modules.fo.ForumCallback;
import org.olat.modules.fo.ForumChangedEvent;
......@@ -99,7 +99,6 @@ public class MessageEditController extends FormBasicController {
// attached files anywhere at the time of deleting it
// likely to be resolved after user logs out, caches get cleared - and if not the server
// restart overnight definitely removes those .nfs files.
public static final String[] ATTACHMENT_EXCLUDE_PREFIXES = new String[]{".nfs", ".CVS", ".DS_Store"};
private static final String[] enableKeys = new String[]{ "on" };
private RichTextElement bodyEl;
......@@ -114,7 +113,7 @@ public class MessageEditController extends FormBasicController {
private VFSContainer tempUploadFolder;
private boolean userIsMsgCreator;
private boolean msgHasChildren;
private VFSItemExcludePrefixFilter exclFilter;
private VFSItemMetaFilter exclFilter;
private final Forum forum;
private final EditMode editMode;
......@@ -157,7 +156,7 @@ public class MessageEditController extends FormBasicController {
this.guestOnly = ureq.getUserSession().getRoles().isGuestOnly();
tempUploadFolder = new LocalFolderImpl(new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID()));
exclFilter = new VFSItemExcludePrefixFilter(ATTACHMENT_EXCLUDE_PREFIXES);
exclFilter = new VFSItemMetaFilter();
initForm(ureq);
}
......
......@@ -73,7 +73,7 @@ import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.VFSMediaResource;
import org.olat.core.util.vfs.filters.VFSItemExcludePrefixFilter;
import org.olat.core.util.vfs.filters.VFSItemMetaFilter;
import org.olat.modules.fo.Forum;
import org.olat.modules.fo.ForumCallback;
import org.olat.modules.fo.ForumChangedEvent;
......@@ -593,7 +593,7 @@ public class MessageListController extends BasicController implements GenericEve
// message attachments
VFSContainer msgContainer = forumManager.getMessageContainer(forum.getKey(), m.getKey());
messageView.setMessageContainer(msgContainer);
List<VFSItem> attachments = new ArrayList<VFSItem>(msgContainer.getItems(new VFSItemExcludePrefixFilter(MessageEditController.ATTACHMENT_EXCLUDE_PREFIXES)));
List<VFSItem> attachments = new ArrayList<VFSItem>(msgContainer.getItems(new VFSItemMetaFilter()));
messageView.setAttachments(attachments);
// number of children and modify/delete permissions
......
......@@ -46,4 +46,25 @@ public class FileUtilsTest {
String normalized = FileUtils.normalizeFilename(smorrebrod);
Assert.assertEquals(normalized, "Smorrebrod");
}
@Test
public void testMetaFiles() {
Assert.assertFalse(FileUtils.isMetaFilename(null));
Assert.assertFalse(FileUtils.isMetaFilename(""));
Assert.assertFalse(FileUtils.isMetaFilename("gugus"));
Assert.assertFalse(FileUtils.isMetaFilename(".Jüdelidü"));
Assert.assertFalse(FileUtils.isMetaFilename("./dings"));
Assert.assertTrue(FileUtils.isMetaFilename(".DS_Store"));
Assert.assertTrue(FileUtils.isMetaFilename(".CVS"));
Assert.assertTrue(FileUtils.isMetaFilename(".nfs"));
Assert.assertTrue(FileUtils.isMetaFilename(".sass-cache"));
Assert.assertTrue(FileUtils.isMetaFilename(".hg"));
Assert.assertTrue(FileUtils.isMetaFilename("._"));
Assert.assertTrue(FileUtils.isMetaFilename("._gugus"));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment