package com.seafile.seadroid2.data; import android.util.Log; import com.seafile.seadroid2.R; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Seafile event entity */ public class SeafEvent implements SeafItem { public static final String DEBUG_TAG = SeafItem.class.getSimpleName(); public static final String EVENT_TYPE_REPO_CREATE = "repo-create"; public static final String EVENT_TYPE_REPO_DELETE = "repo-delete"; // true for events like a file upload by unregistered user from a // uploadable link private boolean anonymous; private String repo_id; private String author; private String nick; private long time; private String etype; private String repo_name; private String desc; private String commit_id; private String date; private String name; private String time_relative; private String converted_cmmt_desc; private String avatar; private boolean repo_encrypted; private boolean more_files; public static SeafEvent fromJson(JSONObject obj) { SeafEvent event = new SeafEvent(); try { event.author = obj.optString("author"); if (event.author.isEmpty()) { event.author = "anonymous"; event.anonymous = true; } else { event.anonymous = false; } event.repo_id = obj.optString("repo_id"); event.nick = obj.optString("nick"); if (event.nick.isEmpty()) { event.nick = "anonymous"; } event.etype = obj.optString("etype"); event.repo_name = obj.optString("repo_name"); event.time = obj.getLong("time"); event.avatar = obj.optString("avatar"); event.commit_id = obj.optString("commit_id"); event.date = obj.optString("date"); event.name = obj.optString("name"); event.time_relative = obj.optString("time_relative"); event.converted_cmmt_desc = obj.optString("converted_cmmt_desc"); event.repo_encrypted = obj.getBoolean("repo_encrypted"); event.more_files = obj.getBoolean("more_files"); event.desc = obj.optString("desc"); if (event.etype.equals(EVENT_TYPE_REPO_CREATE)) { event.desc = String.format("Created library \"%s\"", event.repo_name); } else if (event.etype.equals(EVENT_TYPE_REPO_DELETE)) { event.desc = String.format("Deleted library \"%s\"", event.repo_name); } event.desc = translateCommitDesc(event.desc); return event; } catch (JSONException e) { Log.d(DEBUG_TAG, e.getMessage()); return null; } } private static Matcher fullMatch(Pattern pattern, String str) { Matcher matcher = pattern.matcher(str); return matcher.matches() ? matcher : null; } public static String translateCommitDesc(String value) { if (value.startsWith("Reverted repo")) { value.replace("repo", "library"); } if (value.startsWith("Reverted library")) { return value.replace("Reverted library to status at", "Reverted library to status at"); } else if (value.startsWith("Reverted file")) { String regex = "Reverted file \"(.*)\" to status at (.*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher; if ((matcher = fullMatch(pattern, value)) != null) { String name = matcher.group(1); String time = matcher.group(2); return String.format("Reverted file \"%s\" to status at %s.", name, time); } } else if (value.startsWith("Recovered deleted directory")) { return value.replace("Recovered deleted directory", "Recovered deleted directory"); } else if (value.startsWith("Changed library")) { return value.replace("Changed library name or description", "Changed library name or description"); } else if (value.startsWith("Merged") || value.startsWith("Auto merge")) { return "Auto merge by seafile system"; } final String[] lines = value.split("\n"); StringBuilder out = new StringBuilder(); for (int i = 0; i < lines.length; i++) { final String translateLine = translateLine(lines[i]); out.append(translateLine); // should avoid append for the last item if (i < lines.length - 1) out.append("\n"); } return out.toString(); } private static String translateLine(String line) { // String regex = String.format("(%s) \"(.*)\"\\s?(and ([0-9]+) more (files|directories))?", getOperations()); // String regex = String.format("(%s).* ".*\..*"\s+(and ([0-9]+) more (files|directories))?", getOperations()); String regex = String.format("(%s).* \"\\S+\\.\\S+\"\\s+(and ([0-9]+) more (files|directories))?", getOperations()); Pattern pattern = Pattern.compile(regex); Matcher matcher; if ((matcher = fullMatch(pattern, line)) == null) { return line; } String op = matcher.group(1); String file_name = matcher.group(2); String has_more = matcher.group(3); String n_more = matcher.group(4); String more_type = matcher.group(5); String op_trans = (getVerbsMap().get(op) == null ? op : getVerbsMap().get(op)); String type, ret; // has more may be null caused a crash if (has_more.length() > 0) { if (more_type.equals("files")) { type = "files"; } else { type = "directories"; } String more = String.format("and %s more", n_more); ret = String.format("%s \"%s\" %s %s.", op_trans, file_name, more, type); } else { ret = String.format("%s \"%s\".", op_trans, file_name); } return ret; } private static HashMap<String, String> verbsMap = null; private static HashMap<String, String> getVerbsMap() { if (verbsMap == null) { verbsMap = new HashMap<>(); verbsMap.put("Added", "Added"); verbsMap.put("Deleted", "Deleted"); verbsMap.put("Removed", "Removed"); verbsMap.put("Modified", "Modified"); verbsMap.put("Renamed", "Renamed"); verbsMap.put("Moved", "Moved"); verbsMap.put("Added directory", "Added directory"); verbsMap.put("Removed directory", "Removed directory"); verbsMap.put("Renamed directory", "Renamed directory"); verbsMap.put("Moved directory", "Moved directory"); } return verbsMap; } private static String getOperations() { return "Added|Deleted|Removed|Modified|Renamed|Moved|Added directory|Removed directory|Renamed directory|Moved directory"; } public boolean isAnonymous() { return anonymous; } public void setAnonymous(boolean anonymous) { this.anonymous = anonymous; } public void setRepo_id(String repo_id) { this.repo_id = repo_id; } public void setAuthor(String author) { this.author = author; } public void setNick(String nick) { this.nick = nick; } public void setTime(int time) { this.time = time; } public void setEtype(String etype) { this.etype = etype; } public void setRepo_name(String repo_name) { this.repo_name = repo_name; } public void setDesc(String desc) { this.desc = desc; } public String getRepo_id() { return repo_id; } public String getAuthor() { return author; } public String getNick() { return nick; } public long getTime() { return time; } public String getEtype() { return etype; } public String getRepo_name() { return repo_name; } public String getDesc() { return desc; } @Override public String getTitle() { return desc; } @Override public String getSubtitle() { return nick; } @Override public int getIcon() { return R.drawable.repo; } public void setTime(long time) { this.time = time; } public String getCommit_id() { return commit_id; } public void setCommit_id(String commit_id) { this.commit_id = commit_id; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTime_relative() { return time_relative; } public void setTime_relative(String time_relative) { this.time_relative = time_relative; } public String getConverted_cmmt_desc() { return converted_cmmt_desc; } public void setConverted_cmmt_desc(String converted_cmmt_desc) { this.converted_cmmt_desc = converted_cmmt_desc; } public String getAvatar() { return avatar; } public void setAvatar(String avatar) { this.avatar = avatar; } public boolean isRepo_encrypted() { return repo_encrypted; } public void setRepo_encrypted(boolean repo_encrypted) { this.repo_encrypted = repo_encrypted; } public boolean isMore_files() { return more_files; } public void setMore_files(boolean more_files) { this.more_files = more_files; } }