Excuse me for saying this, but the problem is not with the application, but with you. You should periodically clean your downloads folder, if not daily, and all the problems you are experiencing stem from not following this practice.
When you download the file called "fred.docx" and it is saved as "fred(1).docx", this happens because the operating system (in combination with the browser) detects a collision with an existing file and automatically adds (x) to the file name.
Obviously, if you do not rename the file and upload it, it is understandable that it creates a new file (since the name is not the same).
You have several options for this matter:
Add an extension in your browser that forces overwriting files if they already exist -> "Downloads Overwrite Already Existing Files" (Chrome Web Store) or "Automatic Save Folder" (Firefox)
Create an Action (and then link it with an automated task on creation) that prevents uploading files of the type xxxx(n).ext
The regular expression for validation would be something like "^(.+)\s*\d+(.[^.]+)?$" (which I think covers all cases).
I’m sending you the code of a class (created with AI, I haven’t tested it) that I think fits quite well with what you need.
Here documentation about how to create your own action:
https://docs.openkm.com/kcenter/view/ok ... ction.html
Below the sample:
Code: Select allpackage com.openkm.plugin.automation.action;
import com.openkm.db.bean.Automation;
import com.openkm.db.bean.AutomationRule.EnumEvents;
import com.openkm.plugin.BasePlugin;
import com.openkm.plugin.automation.Action;
import com.openkm.plugin.automation.AutomationException;
import com.openkm.plugin.automation.AutomationUtils;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* RejectBrowserDuplicateFilename
*
* Blocks document creation when the filename matches the browser-generated
* duplicate pattern, e.g. "report (1).pdf", "document(3).docx", etc.
*
* @author jllort
*/
@PluginImplementation
public class RejectBrowserDuplicateFilename extends BasePlugin implements Action {
private static final Logger log = LoggerFactory.getLogger(RejectBrowserDuplicateFilename.class);
// Matches: "filename (n).ext" or "filename(n).ext" or "filename (n)" (without extension)
private static final Pattern DUPLICATE_PATTERN =
Pattern.compile("^.+\\s*\\(\\d+\\)(\\.[^.]+)?$");
private static final ArrayList<EnumEvents> EVENTS_AT_PRE =
Stream.of(EnumEvents.EVENT_DOCUMENT_CREATE)
.collect(Collectors.toCollection(ArrayList::new));
private static final ArrayList<EnumEvents> EVENTS_AT_POST = new ArrayList<>();
@Autowired
private AutomationUtils automationUtils;
@Override
public void executePre(Map<String, Object> env, Object... params) throws AutomationException {
try {
String name = automationUtils.getName(env);
log.debug("RejectBrowserDuplicateFilename: checking filename '{}'", name);
if (name != null && DUPLICATE_PATTERN.matcher(name).matches()) {
String msg = String.format(
"The filename '%s' appears to be a browser-generated duplicate. " +
"Please rename the file before uploading.", name);
log.info("RejectBrowserDuplicateFilename: blocked upload of '{}'", name);
throw new AutomationException(msg);
}
} catch (AutomationException e) {
throw e;
} catch (Exception e) {
throw new AutomationException("RejectBrowserDuplicateFilename exception", e);
}
}
@Override
public void executePost(Map<String, Object> env, Object... params) throws AutomationException {
}
@Override
public String getName() {
return "RejectBrowserDuplicateFilename";
}
@Override
public String getParamType00() {
return Automation.PARAM_TYPE_EMPTY;
}
@Override
public String getParamSrc00() {
return Automation.PARAM_SOURCE_EMPTY;
}
@Override
public String getParamDesc00() {
return Automation.PARAM_DESCRIPTION_EMPTY;
}
@Override
public String getParamType01() {
return Automation.PARAM_TYPE_EMPTY;
}
@Override
public String getParamSrc01() {
return Automation.PARAM_SOURCE_EMPTY;
}
@Override
public String getParamDesc01() {
return Automation.PARAM_DESCRIPTION_EMPTY;
}
@Override
public String getParamType02() {
return Automation.PARAM_TYPE_EMPTY;
}
@Override
public String getParamSrc02() {
return Automation.PARAM_SOURCE_EMPTY;
}
@Override
public String getParamDesc02() {
return Automation.PARAM_DESCRIPTION_EMPTY;
}
@Override
public List<EnumEvents> getValidEventsAtPre() {
return EVENTS_AT_PRE;
}
@Override
public List<EnumEvents> getValidEventsAtPost() {
return EVENTS_AT_POST;
}
}