mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
multiple categories (#1970), stricter categories, ignore temp folders
This commit is contained in:
@@ -41,7 +41,8 @@ class AvailableContribution extends Contribution {
|
||||
this.type = type;
|
||||
this.link = params.get("download");
|
||||
|
||||
category = ContributionListing.getCategory(params.get("category"));
|
||||
//category = ContributionListing.getCategory(params.get("category"));
|
||||
categories = parseCategories(params.get("category"));
|
||||
name = params.get("name");
|
||||
authorList = params.get("authorList");
|
||||
url = params.get("url");
|
||||
@@ -65,12 +66,11 @@ class AvailableContribution extends Contribution {
|
||||
// Unzip the file into the modes, tools, or libraries folder inside the
|
||||
// sketchbook. Unzipping to /tmp is problematic because it may be on
|
||||
// another file system, so move/rename operations will break.
|
||||
File sketchbookContribFolder = type.getSketchbookFolder();
|
||||
// File sketchbookContribFolder = type.getSketchbookFolder();
|
||||
File tempFolder = null;
|
||||
|
||||
try {
|
||||
tempFolder =
|
||||
Base.createTempFolder(type.toString(), "tmp", sketchbookContribFolder);
|
||||
tempFolder = type.createTempFolder();
|
||||
} catch (IOException e) {
|
||||
status.setErrorMessage("Could not create a temporary folder to install.");
|
||||
return null;
|
||||
@@ -183,7 +183,7 @@ class AvailableContribution extends Contribution {
|
||||
PrintWriter writer = PApplet.createWriter(propFile);
|
||||
|
||||
writer.println("name=" + getName());
|
||||
writer.println("category=" + getCategory());
|
||||
writer.println("category=" + getCategoryStr());
|
||||
writer.println("authorList=" + getAuthorList());
|
||||
writer.println("url=" + getUrl());
|
||||
writer.println("sentence=" + getSentence());
|
||||
|
||||
@@ -21,9 +21,21 @@
|
||||
*/
|
||||
package processing.app.contrib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import processing.core.PApplet;
|
||||
|
||||
|
||||
abstract public class Contribution {
|
||||
protected String category; // "Sound"
|
||||
static final List validCategories =
|
||||
Arrays.asList("3D", "Animation", "Data", "Geometry", "GUI", "Hardware",
|
||||
"I/O", "Math", "Simulation", "Sound", "Typography",
|
||||
"Utilities", "Video & Vision", "Other");
|
||||
|
||||
//protected String category; // "Sound"
|
||||
protected List<String> categories; // "Sound", "Typography"
|
||||
protected String name; // "pdf" or "PDF Export"
|
||||
protected String authorList; // Ben Fry
|
||||
protected String url; // http://processing.org
|
||||
@@ -34,8 +46,37 @@ abstract public class Contribution {
|
||||
|
||||
|
||||
// "Sound"
|
||||
public String getCategory() {
|
||||
return category;
|
||||
// public String getCategory() {
|
||||
// return category;
|
||||
// }
|
||||
|
||||
|
||||
// "Sound", "Utilities"... see valid list in ContributionListing
|
||||
protected List<String> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
|
||||
protected String getCategoryStr() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String category : categories) {
|
||||
sb.append(category);
|
||||
sb.append(',');
|
||||
}
|
||||
sb.deleteCharAt(sb.length()-1); // delete last comma
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
protected boolean hasCategory(String category) {
|
||||
if (category != null) {
|
||||
for (String c : categories) {
|
||||
if (category.equalsIgnoreCase(c)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,4 +146,26 @@ abstract public class Contribution {
|
||||
boolean isDeletionFlagged() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the list of categories that this contribution is part of
|
||||
* (e.g. "Typography / Geometry"). "Unknown" if the category null.
|
||||
*/
|
||||
static public List<String> parseCategories(String categoryStr) {
|
||||
List<String> outgoing = new ArrayList<String>();
|
||||
|
||||
if (categoryStr != null) {
|
||||
String[] listing = PApplet.trim(PApplet.split(categoryStr, ','));
|
||||
for (String category : listing) {
|
||||
if (validCategories.contains(category)) {
|
||||
outgoing.add(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outgoing.size() == 0) {
|
||||
outgoing.add("Unknown");
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,9 @@ import processing.core.PApplet;
|
||||
|
||||
|
||||
public class ContributionListing {
|
||||
// Stable URL that will redirect to wherever we're hosting the file
|
||||
static final String LISTING_URL =
|
||||
"http://processing.org/contrib_generate/contributions.txt";
|
||||
"http://download.processing.org/contributions.txt";
|
||||
|
||||
static ContributionListing singleInstance;
|
||||
|
||||
@@ -44,12 +45,6 @@ public class ContributionListing {
|
||||
boolean hasDownloadedLatestList;
|
||||
ReentrantLock downloadingListingLock;
|
||||
|
||||
static final String[] validCategories = {
|
||||
"3D", "Animation", "Compilations", "Data", "Geometry", "GUI",
|
||||
"Hardware", "I/O", "Math", "Simulation", "Sound", "Typography",
|
||||
"Utilities", "Video & Vision"
|
||||
};
|
||||
|
||||
|
||||
private ContributionListing() {
|
||||
listeners = new ArrayList<ContributionChangeListener>();
|
||||
@@ -103,53 +98,57 @@ public class ContributionListing {
|
||||
|
||||
|
||||
protected void replaceContribution(Contribution oldLib, Contribution newLib) {
|
||||
if (oldLib == null || newLib == null) {
|
||||
return;
|
||||
}
|
||||
if (oldLib != null && newLib != null) {
|
||||
for (String category : oldLib.getCategories()) {
|
||||
if (librariesByCategory.containsKey(category)) {
|
||||
List<Contribution> list = librariesByCategory.get(category);
|
||||
|
||||
if (librariesByCategory.containsKey(oldLib.getCategory())) {
|
||||
List<Contribution> list = librariesByCategory.get(oldLib.getCategory());
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i) == oldLib) {
|
||||
list.set(i, newLib);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i) == oldLib) {
|
||||
list.set(i, newLib);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < allContributions.size(); i++) {
|
||||
if (allContributions.get(i) == oldLib) {
|
||||
allContributions.set(i, newLib);
|
||||
for (int i = 0; i < allContributions.size(); i++) {
|
||||
if (allContributions.get(i) == oldLib) {
|
||||
allContributions.set(i, newLib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifyChange(oldLib, newLib);
|
||||
notifyChange(oldLib, newLib);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addContribution(Contribution contribution) {
|
||||
if (librariesByCategory.containsKey(contribution.getCategory())) {
|
||||
List<Contribution> list = librariesByCategory.get(contribution.getCategory());
|
||||
list.add(contribution);
|
||||
Collections.sort(list, nameComparator);
|
||||
for (String category : contribution.getCategories()) {
|
||||
if (librariesByCategory.containsKey(category)) {
|
||||
List<Contribution> list = librariesByCategory.get(category);
|
||||
list.add(contribution);
|
||||
Collections.sort(list, nameComparator);
|
||||
|
||||
} else {
|
||||
ArrayList<Contribution> list = new ArrayList<Contribution>();
|
||||
list.add(contribution);
|
||||
librariesByCategory.put(contribution.getCategory(), list);
|
||||
} else {
|
||||
ArrayList<Contribution> list = new ArrayList<Contribution>();
|
||||
list.add(contribution);
|
||||
librariesByCategory.put(category, list);
|
||||
}
|
||||
allContributions.add(contribution);
|
||||
notifyAdd(contribution);
|
||||
Collections.sort(allContributions, nameComparator);
|
||||
}
|
||||
allContributions.add(contribution);
|
||||
notifyAdd(contribution);
|
||||
Collections.sort(allContributions, nameComparator);
|
||||
}
|
||||
|
||||
|
||||
protected void removeContribution(Contribution info) {
|
||||
if (librariesByCategory.containsKey(info.getCategory())) {
|
||||
librariesByCategory.get(info.getCategory()).remove(info);
|
||||
protected void removeContribution(Contribution contribution) {
|
||||
for (String category : contribution.getCategories()) {
|
||||
if (librariesByCategory.containsKey(category)) {
|
||||
librariesByCategory.get(category).remove(contribution);
|
||||
}
|
||||
}
|
||||
allContributions.remove(info);
|
||||
notifyRemove(info);
|
||||
allContributions.remove(contribution);
|
||||
notifyRemove(contribution);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,12 +208,14 @@ public class ContributionListing {
|
||||
|
||||
|
||||
protected List<Contribution> getFilteredLibraryList(String category, List<String> filters) {
|
||||
ArrayList<Contribution> filteredList = new ArrayList<Contribution>(allContributions);
|
||||
ArrayList<Contribution> filteredList =
|
||||
new ArrayList<Contribution>(allContributions);
|
||||
|
||||
Iterator<Contribution> it = filteredList.iterator();
|
||||
while (it.hasNext()) {
|
||||
Contribution libInfo = it.next();
|
||||
if (category != null && !category.equals(libInfo.getCategory())) {
|
||||
//if (category != null && !category.equals(libInfo.getCategory())) {
|
||||
if (category != null && !libInfo.hasCategory(category)) {
|
||||
it.remove();
|
||||
} else {
|
||||
for (String filter : filters) {
|
||||
@@ -254,7 +255,7 @@ public class ContributionListing {
|
||||
return contrib.getAuthorList() != null && contrib.getAuthorList().toLowerCase().matches(filter)
|
||||
|| contrib.getSentence() != null && contrib.getSentence().toLowerCase().matches(filter)
|
||||
|| contrib.getParagraph() != null && contrib.getParagraph().toLowerCase().matches(filter)
|
||||
|| contrib.getCategory() != null && contrib.getCategory().toLowerCase().matches(filter)
|
||||
|| contrib.hasCategory(filter)
|
||||
|| contrib.getName() != null && contrib.getName().toLowerCase().matches(filter);
|
||||
}
|
||||
|
||||
@@ -396,39 +397,39 @@ public class ContributionListing {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return a lowercase string with all non-alphabetic characters removed
|
||||
*/
|
||||
static protected String normalize(String s) {
|
||||
return s.toLowerCase().replaceAll("^\\p{Lower}", "");
|
||||
}
|
||||
// /**
|
||||
// * @return a lowercase string with all non-alphabetic characters removed
|
||||
// */
|
||||
// static protected String normalize(String s) {
|
||||
// return s.toLowerCase().replaceAll("^\\p{Lower}", "");
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @return the proper, valid name of this category to be displayed in the UI
|
||||
* (e.g. "Typography / Geometry"). "Unknown" if the category null.
|
||||
*/
|
||||
static public String getCategory(String category) {
|
||||
if (category == null) {
|
||||
return "Unknown";
|
||||
}
|
||||
String normCatName = normalize(category);
|
||||
|
||||
for (String validCatName : validCategories) {
|
||||
String normValidCatName = normalize(validCatName);
|
||||
if (normValidCatName.equals(normCatName)) {
|
||||
return validCatName;
|
||||
}
|
||||
}
|
||||
return category;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return the proper, valid name of this category to be displayed in the UI
|
||||
// * (e.g. "Typography / Geometry"). "Unknown" if the category null.
|
||||
// */
|
||||
// static public String getCategory(String category) {
|
||||
// if (category == null) {
|
||||
// return "Unknown";
|
||||
// }
|
||||
// String normCatName = normalize(category);
|
||||
//
|
||||
// for (String validCatName : validCategories) {
|
||||
// String normValidCatName = normalize(validCatName);
|
||||
// if (normValidCatName.equals(normCatName)) {
|
||||
// return validCatName;
|
||||
// }
|
||||
// }
|
||||
// return category;
|
||||
// }
|
||||
|
||||
|
||||
ArrayList<AvailableContribution> parseContribList(File file) {
|
||||
ArrayList<AvailableContribution> outgoing = new ArrayList<AvailableContribution>();
|
||||
|
||||
if (file != null && file.exists()) {
|
||||
String lines[] = PApplet.loadStrings(file);
|
||||
String[] lines = PApplet.loadStrings(file);
|
||||
|
||||
int start = 0;
|
||||
while (start < lines.length) {
|
||||
|
||||
@@ -23,6 +23,7 @@ package processing.app.contrib;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import processing.app.Base;
|
||||
@@ -30,7 +31,6 @@ import processing.app.Editor;
|
||||
import processing.app.Library;
|
||||
|
||||
public enum ContributionType {
|
||||
// LIBRARY, LIBRARY_COMPILATION, TOOL, MODE;
|
||||
LIBRARY, TOOL, MODE;
|
||||
|
||||
|
||||
@@ -38,8 +38,6 @@ public enum ContributionType {
|
||||
switch (this) {
|
||||
case LIBRARY:
|
||||
return "library";
|
||||
// case LIBRARY_COMPILATION:
|
||||
// return "compilation";
|
||||
case TOOL:
|
||||
return "tool";
|
||||
case MODE:
|
||||
@@ -49,7 +47,10 @@ public enum ContributionType {
|
||||
};
|
||||
|
||||
|
||||
/** Return Mode for mode, Tool for tool, etc. */
|
||||
/**
|
||||
* Get this type name as a purtied up, capitalized version.
|
||||
* @return Mode for mode, Tool for tool, etc.
|
||||
*/
|
||||
public String getTitle() {
|
||||
String s = toString();
|
||||
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
||||
@@ -60,8 +61,6 @@ public enum ContributionType {
|
||||
switch (this) {
|
||||
case LIBRARY:
|
||||
return "libraries";
|
||||
// case LIBRARY_COMPILATION:
|
||||
// return "libraries";
|
||||
case TOOL:
|
||||
return "tools";
|
||||
case MODE:
|
||||
@@ -69,6 +68,26 @@ public enum ContributionType {
|
||||
}
|
||||
return null; // should be unreachable
|
||||
}
|
||||
|
||||
|
||||
public File createTempFolder() throws IOException {
|
||||
return Base.createTempFolder(toString(), "tmp", getSketchbookFolder());
|
||||
}
|
||||
|
||||
|
||||
public boolean isTempFolderName(String name) {
|
||||
return name.startsWith(toString()) && name.endsWith("tmp");
|
||||
}
|
||||
|
||||
|
||||
// public String getTempPrefix() {
|
||||
// return toString();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public String getTempSuffix() {
|
||||
// return "tmp";
|
||||
// }
|
||||
|
||||
|
||||
// public String getPropertiesName() {
|
||||
@@ -78,16 +97,13 @@ public enum ContributionType {
|
||||
|
||||
static public ContributionType fromName(String s) {
|
||||
if (s != null) {
|
||||
if ("library".equals(s.toLowerCase())) {
|
||||
if ("library".equalsIgnoreCase(s)) {
|
||||
return LIBRARY;
|
||||
}
|
||||
// if ("compilation".equals(s.toLowerCase())) {
|
||||
// return LIBRARY_COMPILATION;
|
||||
// }
|
||||
if ("tool".equals(s.toLowerCase())) {
|
||||
if ("tool".equalsIgnoreCase(s)) {
|
||||
return TOOL;
|
||||
}
|
||||
if ("mode".equals(s.toLowerCase())) {
|
||||
if ("mode".equalsIgnoreCase(s)) {
|
||||
return MODE;
|
||||
}
|
||||
}
|
||||
@@ -109,7 +125,9 @@ public enum ContributionType {
|
||||
|
||||
|
||||
boolean isCandidate(File potential) {
|
||||
return (potential.isDirectory() && new File(potential, toString()).exists());
|
||||
return (potential.isDirectory() &&
|
||||
new File(potential, toString()).exists() &&
|
||||
!isTempFolderName(potential.getName()));
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +166,8 @@ public enum ContributionType {
|
||||
LocalContribution load(Base base, File folder) {
|
||||
switch (this) {
|
||||
case LIBRARY:
|
||||
return new Library(folder);
|
||||
//return new Library(folder);
|
||||
return Library.load(folder);
|
||||
case TOOL:
|
||||
return ToolContribution.load(folder);
|
||||
case MODE:
|
||||
|
||||
@@ -57,7 +57,7 @@ public abstract class LocalContribution extends Contribution {
|
||||
|
||||
name = properties.get("name");
|
||||
id = properties.get("id");
|
||||
category = ContributionListing.getCategory(properties.get("category"));
|
||||
categories = parseCategories(properties.get("category"));
|
||||
if (name == null) {
|
||||
name = folder.getName();
|
||||
}
|
||||
@@ -71,7 +71,6 @@ public abstract class LocalContribution extends Contribution {
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("The version number for the “" + name + "” library is not set properly.");
|
||||
System.err.println("Please contact the library author to fix it according to the guidelines.");
|
||||
//e.printStackTrace();
|
||||
}
|
||||
prettyVersion = properties.get("prettyVersion");
|
||||
|
||||
@@ -185,8 +184,8 @@ public abstract class LocalContribution extends Contribution {
|
||||
|
||||
|
||||
LocalContribution copyAndLoad(Editor editor,
|
||||
boolean confirmReplace,
|
||||
StatusPanel status) {
|
||||
boolean confirmReplace,
|
||||
StatusPanel status) {
|
||||
ArrayList<LocalContribution> oldContribs =
|
||||
getType().listContributions(editor);
|
||||
|
||||
@@ -283,7 +282,7 @@ public abstract class LocalContribution extends Contribution {
|
||||
if (backupFolder != null) {
|
||||
String libFolderName = getFolder().getName();
|
||||
String prefix = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
||||
final String backupName = prefix + "_" + libFolderName;
|
||||
final String backupName = prefix + " " + libFolderName;
|
||||
File backupSubFolder = ContributionManager.getUniqueName(backupFolder, backupName);
|
||||
|
||||
if (deleteOriginal) {
|
||||
@@ -505,7 +504,7 @@ public abstract class LocalContribution extends Contribution {
|
||||
}
|
||||
|
||||
|
||||
class IgnorableException extends Exception {
|
||||
static protected class IgnorableException extends Exception {
|
||||
public IgnorableException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
@@ -94,13 +94,13 @@ public class ModeContribution extends LocalContribution {
|
||||
File[] potential = ContributionType.MODE.listCandidates(modesFolder);
|
||||
for (File folder : potential) {
|
||||
if (!existing.containsKey(folder)) {
|
||||
try {
|
||||
contribModes.add(new ModeContribution(base, folder, null));
|
||||
} catch (IgnorableException ig) {
|
||||
Base.log(ig.getMessage());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
contribModes.add(new ModeContribution(base, folder, null));
|
||||
} catch (IgnorableException ig) {
|
||||
Base.log(ig.getMessage());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user