Skip to content

Commit e8ea12c

Browse files
committed
Add library from ZIP
1 parent 0efc024 commit e8ea12c

File tree

6 files changed

+212
-2
lines changed

6 files changed

+212
-2
lines changed

app/src/processing/app/Base.java

+22
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import processing.app.helpers.PreferencesMap;
3737
import processing.app.helpers.filefilters.OnlyDirs;
3838
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
39+
import processing.app.tools.ZipDeflater;
3940
import processing.core.*;
4041
import static processing.app.I18n._;
4142

@@ -2594,4 +2595,25 @@ static protected void listFiles(String basePath,
25942595
}
25952596
}
25962597
}
2598+
2599+
2600+
public void handleAddZipLibrary(Editor editor) {
2601+
String prompt = _("Select a zip file containing the library you'd like to add");
2602+
FileDialog fd = new FileDialog(editor, prompt, FileDialog.LOAD);
2603+
fd.setDirectory(System.getProperty("user.home"));
2604+
fd.setVisible(true);
2605+
2606+
String directory = fd.getDirectory();
2607+
String filename = fd.getFile();
2608+
if (filename == null) return;
2609+
2610+
File sourceFile = new File(directory, filename);
2611+
try {
2612+
ZipDeflater zipDeflater = new ZipDeflater(sourceFile, getSketchbookLibrariesFolder());
2613+
zipDeflater.deflate();
2614+
editor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu"));
2615+
} catch (IOException e) {
2616+
editor.statusError(e);
2617+
}
2618+
}
25972619
}

app/src/processing/app/Editor.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public void windowActivated(WindowEvent e) {
178178
// re-add the sub-menus that are shared by all windows
179179
fileMenu.insert(sketchbookMenu, 2);
180180
fileMenu.insert(examplesMenu, 3);
181-
sketchMenu.insert(importMenu, 4);
181+
//sketchMenu.insert(importMenu, 4);
182182
toolsMenu.insert(boardsMenu, numTools);
183183
toolsMenu.insert(cpuTypeMenu, numTools + 1);
184184
toolsMenu.insert(serialMenu, numTools + 2);
@@ -190,7 +190,7 @@ public void windowDeactivated(WindowEvent e) {
190190
// System.err.println("deactivate"); // not coming through
191191
fileMenu.remove(sketchbookMenu);
192192
fileMenu.remove(examplesMenu);
193-
sketchMenu.remove(importMenu);
193+
//sketchMenu.remove(importMenu);
194194
toolsMenu.remove(boardsMenu);
195195
toolsMenu.remove(cpuTypeMenu);
196196
toolsMenu.remove(serialMenu);
@@ -634,6 +634,16 @@ public void actionPerformed(ActionEvent e) {
634634
}
635635
sketchMenu.add(importMenu);
636636

637+
item = new JMenuItem(_("Add Library from ZIP"));
638+
item.addActionListener(new ActionListener() {
639+
public void actionPerformed(ActionEvent e) {
640+
base.handleAddZipLibrary(Editor.this);
641+
base.onBoardOrPortChange();
642+
base.rebuildImportMenu(Editor.importMenu);
643+
}
644+
});
645+
sketchMenu.add(item);
646+
637647
item = newJMenuItem(_("Show Sketch Folder"), 'K');
638648
item.addActionListener(new ActionListener() {
639649
public void actionPerformed(ActionEvent e) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package processing.app.tools;
2+
3+
import java.io.File;
4+
import java.io.FileOutputStream;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.util.Enumeration;
8+
import java.util.Random;
9+
import java.util.zip.ZipEntry;
10+
import java.util.zip.ZipException;
11+
import java.util.zip.ZipFile;
12+
13+
public class ZipDeflater {
14+
15+
private final ZipFile zipFile;
16+
private final File destFolder;
17+
18+
public ZipDeflater(File file, File destFolder) throws ZipException, IOException {
19+
this.destFolder = destFolder;
20+
this.zipFile = new ZipFile(file);
21+
}
22+
23+
public void deflate() throws IOException {
24+
String folderName = tempFolderNameFromZip();
25+
26+
File folder = new File(destFolder, folderName);
27+
28+
if (!folder.mkdir()) {
29+
throw new IOException("Unable to create folder " + folderName);
30+
}
31+
32+
Enumeration<? extends ZipEntry> entries = zipFile.entries();
33+
while (entries.hasMoreElements()) {
34+
ZipEntry entry = entries.nextElement();
35+
ensureFoldersOfEntryExist(folder, entry);
36+
File entryFile = new File(folder, entry.getName());
37+
if (entry.isDirectory()) {
38+
entryFile.mkdir();
39+
} else {
40+
FileOutputStream fos = null;
41+
InputStream zipInputStream = null;
42+
try {
43+
fos = new FileOutputStream(entryFile);
44+
zipInputStream = zipFile.getInputStream(entry);
45+
byte[] buffer = new byte[1024 * 4];
46+
int len = -1;
47+
while ((len = zipInputStream.read(buffer)) != -1) {
48+
fos.write(buffer, 0, len);
49+
}
50+
} finally {
51+
if (fos != null) {
52+
fos.close();
53+
}
54+
if (zipInputStream != null) {
55+
zipInputStream.close();
56+
}
57+
}
58+
}
59+
}
60+
61+
// Test.zip may or may not contain Test folder. We use zip name to create libraries folder. Therefore, a contained Test folder is useless and must be removed
62+
ensureOneLevelFolder(folder);
63+
}
64+
65+
private void ensureFoldersOfEntryExist(File folder, ZipEntry entry) {
66+
String[] parts = entry.getName().split("/");
67+
File current = folder;
68+
for (int i = 0; i < parts.length - 1; i++) {
69+
current = new File(current, parts[i]);
70+
current.mkdir();
71+
}
72+
}
73+
74+
private void ensureOneLevelFolder(File folder) {
75+
File[] files = folder.listFiles();
76+
if (files.length == 1 && files[0].isDirectory()) {
77+
File tempFile = new File(files[0].getPath() + new Random().nextInt(1000));
78+
files[0].renameTo(tempFile);
79+
for (File file : tempFile.listFiles()) {
80+
file.renameTo(new File(folder, file.getName()));
81+
}
82+
tempFile.delete();
83+
}
84+
}
85+
86+
private String tempFolderNameFromZip() {
87+
String folderName = zipFile.getName();
88+
if (folderName.lastIndexOf(".") != -1) {
89+
folderName = folderName.substring(0, folderName.lastIndexOf("."));
90+
}
91+
if (folderName.lastIndexOf(File.separator) != -1) {
92+
folderName = folderName.substring(folderName.lastIndexOf(File.separator) + 1);
93+
}
94+
return folderName;
95+
}
96+
97+
}

app/test/Test.zip

3.04 KB
Binary file not shown.

app/test/Test2.zip

2.94 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package processing.app.tools;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.io.File;
6+
import java.util.Arrays;
7+
import java.util.Random;
8+
9+
import org.junit.After;
10+
import org.junit.Before;
11+
import org.junit.Test;
12+
13+
import processing.app.tools.ZipDeflater;
14+
15+
public class ZipDeflaterTest {
16+
17+
private File destFolder;
18+
19+
@Before
20+
public void makeTempFolder() {
21+
destFolder = new File(System.getProperty("java.io.tmpdir") + File.separator + "arduino_zip_test_" + new Random().nextInt(100000));
22+
destFolder.mkdir();
23+
}
24+
25+
@Test
26+
public void shouldDeflateZip() throws Exception {
27+
File file = new File(ZipDeflater.class.getResource("/Test2.zip").getFile());
28+
new ZipDeflater(file, destFolder).deflate();
29+
30+
String[] files = destFolder.list();
31+
assertEquals(1, files.length);
32+
assertEquals("Test2", files[0]);
33+
34+
file = destFolder.listFiles()[0];
35+
files = file.list();
36+
assertEquals(5, files.length);
37+
Arrays.sort(files);
38+
assertEquals("Test.cpp", files[0]);
39+
assertEquals("Test.h", files[1]);
40+
assertEquals("examples", files[2]);
41+
assertEquals("keywords.txt", files[3]);
42+
assertEquals("readme.txt", files[4]);
43+
}
44+
45+
@Test
46+
public void shouldDeflateZipAndMoveContentsToParentFolder() throws Exception {
47+
File file = new File(ZipDeflater.class.getResource("/Test.zip").getFile());
48+
new ZipDeflater(file, destFolder).deflate();
49+
50+
String[] files = destFolder.list();
51+
assertEquals(1, files.length);
52+
assertEquals("Test", files[0]);
53+
54+
file = destFolder.listFiles()[0];
55+
files = file.list();
56+
assertEquals(5, files.length);
57+
Arrays.sort(files);
58+
assertEquals("Test.cpp", files[0]);
59+
assertEquals("Test.h", files[1]);
60+
assertEquals("examples", files[2]);
61+
assertEquals("keywords.txt", files[3]);
62+
assertEquals("readme.txt", files[4]);
63+
}
64+
65+
@After
66+
public void deleteTempFolder() {
67+
recursiveDelete(destFolder);
68+
}
69+
70+
private void recursiveDelete(File folder) {
71+
for (File file : folder.listFiles()) {
72+
if (file.isDirectory()) {
73+
recursiveDelete(file);
74+
} else {
75+
file.delete();
76+
}
77+
}
78+
folder.delete();
79+
}
80+
81+
}

0 commit comments

Comments
 (0)