From ad5bdbe22d8b9c0eacc3b28761828731fe00c557 Mon Sep 17 00:00:00 2001 From: bancika Date: Mon, 31 Oct 2016 17:53:56 +0100 Subject: [PATCH] manage cloud uploads --- .../src/org/diylc/common/ComponentType.java | 1 - .../org/diylc/core/measures/Resistance.java | 2 + .../plugins/cloud/model/IServiceAPI.java | 3 +- .../cloud/presenter/CloudPresenter.java | 26 ++- .../src/org/diylc/images/IconLoader.java | 9 +- .../src/org/diylc/images/cloud_edit.png | Bin 0 -> 1056 bytes .../org/diylc/swing/gui/DialogFactory.java | 16 +- .../swing/plugins/cloud/CloudPlugIn.java | 9 +- .../plugins/cloud/view/UploadDialog.java | 4 +- .../view/browser/ResultsScrollPanel.java | 173 +++++++++++++++--- .../view/browser/UploadManagerFrame.java | 4 +- diylc/diylc-swing/update.xml | 4 + 12 files changed, 204 insertions(+), 47 deletions(-) create mode 100644 diylc/diylc-swing/src/org/diylc/images/cloud_edit.png diff --git a/diylc/diylc-core/src/org/diylc/common/ComponentType.java b/diylc/diylc-core/src/org/diylc/common/ComponentType.java index 211406d0..2c89f6e6 100644 --- a/diylc/diylc-core/src/org/diylc/common/ComponentType.java +++ b/diylc/diylc-core/src/org/diylc/common/ComponentType.java @@ -5,7 +5,6 @@ import javax.swing.Icon; import org.diylc.core.CreationMethod; import org.diylc.core.IDIYComponent; import org.diylc.core.annotations.BomPolicy; -import org.diylc.core.annotations.IAutoCreator; import org.diylc.core.annotations.KeywordPolicy; /** diff --git a/diylc/diylc-core/src/org/diylc/core/measures/Resistance.java b/diylc/diylc-core/src/org/diylc/core/measures/Resistance.java index 38e38f40..15df3a5e 100644 --- a/diylc/diylc-core/src/org/diylc/core/measures/Resistance.java +++ b/diylc/diylc-core/src/org/diylc/core/measures/Resistance.java @@ -50,6 +50,8 @@ public class Resistance extends AbstractMeasure { bands = new Color[] {}; } } else { + if (getValue() == null || getUnit() == null) + return new Color[] {}; double base = getValue() * getUnit().getFactor(); int multiplier = 0; while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) { diff --git a/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java b/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java index 9b2f86ae..2f7614ed 100644 --- a/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java +++ b/diylc/diylc-core/src/org/diylc/plugins/cloud/model/IServiceAPI.java @@ -98,12 +98,13 @@ public interface IServiceAPI { * @param itemsPerPage * @param sort * @param username + * @param projectId optional parameter used when we want to fetch a particular project * @return string with error message if the error occurred or a list of {@link ProjectEntity} * objects. */ Object search(@ParamName("criteria") String criteria, @ParamName("category") String category, @ParamName("page") Integer page, @ParamName("itemsPerPage") Integer itemsPerPage, @ParamName("sort") String sort, - @ParamName("username") String username); + @ParamName("username") String username, @ParamName("projectId") Integer projectId); /** * Uploads a project using token to authenticate. When projectI is specified, it updates the diff --git a/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java b/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java index b87c3515..ce9019a2 100644 --- a/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java +++ b/diylc/diylc-core/src/org/diylc/plugins/cloud/presenter/CloudPresenter.java @@ -135,7 +135,7 @@ public class CloudPresenter { } public void uploadProject(String projectName, String category, String description, String keywords, - String diylcVersion, File thumbnail, File project) throws IOException, CloudException { + String diylcVersion, File thumbnail, File project, Integer projectId) throws IOException, CloudException { String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null); String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null); @@ -145,7 +145,23 @@ public class CloudPresenter { try { String res = getService().uploadProject(username, token, getMachineId(), projectName, category, description, diylcVersion, - keywords, thumbnail, project, null); + keywords, thumbnail, project, projectId); + if (!res.equals(SUCCESS)) + throw new CloudException(res); + } catch (Exception e) { + throw new CloudException(e); + } + } + + public void deleteProject(int projectId) throws CloudException { + String username = ConfigurationManager.getInstance().readString(USERNAME_KEY, null); + String token = ConfigurationManager.getInstance().readString(TOKEN_KEY, null); + + if (username == null || token == null) + throw new CloudException("Login failed. Please try to login again."); + + try { + String res = getService().deleteProject(username, token, getMachineId(), projectId); if (!res.equals(SUCCESS)) throw new CloudException(res); } catch (Exception e) { @@ -234,7 +250,7 @@ public class CloudPresenter { throws CloudException { LOG.info(String.format("search(%1$s,%2$s,%3$s,%4$d,%5$d)", criteria, category, sortOrder, pageNumber, itemsPerPage)); try { - Object res = getService().search(criteria, category, pageNumber, itemsPerPage, sortOrder, null); + Object res = getService().search(criteria, category, pageNumber, itemsPerPage, sortOrder, null, null); return processResults(res); } catch (CloudException ce) { throw ce; @@ -243,10 +259,10 @@ public class CloudPresenter { } } - public List fetchUserUploads() throws CloudException { + public List fetchUserUploads(Integer projectId) throws CloudException { UserEntity user = getUserDetails(); try { - Object res = getService().search("", "", 1, Integer.MAX_VALUE, getSortings()[0], user.getUsername()); + Object res = getService().search("", "", 1, Integer.MAX_VALUE, getSortings()[0], user.getUsername(), projectId); return processResults(res); } catch (CloudException ce) { throw ce; diff --git a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java index 172f5d6a..52d6030d 100644 --- a/diylc/diylc-swing/src/org/diylc/images/IconLoader.java +++ b/diylc/diylc-swing/src/org/diylc/images/IconLoader.java @@ -32,10 +32,11 @@ public enum IconLoader { "briefcase_into.png"), RotateCW("rotate_cw.png"), RotateCCW("rotate_ccw.png"), ElementInto("element_into.png"), Arrow( "arrow.png"), Cloud("cloud.png"), CloudUp("cloud_up.png"), CloudGear("cloud_gear.png"), IdCardEdit( "id_card_edit.png"), KeyEdit("key_edit.png"), Find("find.png"), Dashboard("dashboard.png"), DataFind( - "data_find.png"), CloudDownload("cloud_download.png"), CloudDelete("cloud_delete.png"), CloudUpload( - "cloud_upload.png"), NavLeftBlue("nav_left_blue.png"), NavRightBlue("nav_right_blue.png"), MissingImage( - "missing_image.png"), CloudBg("cloud_bg.png"), CloudBig("cloud_big.png"), CloudWait("cloud_wait.png"), Spinning( - "spinning.gif"), Megaphone("megaphone.png"), Download("download.png"), Eye("eye.png"), Messages("messages.png"); + "data_find.png"), CloudDownload("cloud_download.png"), CloudDelete("cloud_delete.png"), CloudEdit( + "cloud_edit.png"), CloudUpload("cloud_upload.png"), NavLeftBlue("nav_left_blue.png"), NavRightBlue( + "nav_right_blue.png"), MissingImage("missing_image.png"), CloudBg("cloud_bg.png"), CloudBig("cloud_big.png"), CloudWait( + "cloud_wait.png"), Spinning("spinning.gif"), Megaphone("megaphone.png"), Download("download.png"), Eye("eye.png"), Messages( + "messages.png"); protected String name; diff --git a/diylc/diylc-swing/src/org/diylc/images/cloud_edit.png b/diylc/diylc-swing/src/org/diylc/images/cloud_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..5fb64d3348d256cd93dcc095d4044094322ac579 GIT binary patch literal 1056 zcmV+*1mF9KP)N2bZe?^J zG%heMF)~90YwQ331D#1kK~z{r)t1SNR96(n+tzlBL!1_xAP)V8``&AX77XY{Bv}Y? z=(Z(_x(HchVK&)B6dX_#9MFxsD2f9n-AT7CS!d%vAS7rzAx3cF6o?{mDu3VWI>qbq zRdv~P34ZXSs_wmYzjMz$@7~w&F>4&Gf&*|C&cjjI1k<5znh5*g2^1>uKb(YFFsxbx zw;|6ok4Nwo3`s4p2Y!aV&<5F6--jKbabuwgJlG0-VB?gHFQH~Ng7)$a*d*n2!X&69 z1#=i|`~#Q?HEA1U&C2-$MnWw*2KGNKYEX@W$Dlv_3tz(&P_?W58O#RLXHc!;wKe~M z=F|T*e^t!~i};8dGFl8j^?yw@1IEAzsFsm~U~?`}Lp6N|Hu#bnDoCr=<0xYbK%aTq z3^wO~@GazOBV-HjAxwjEsrW{Nigg00;AC!;YXv+9n^zw48Xy^I&o$sR?1E3AT-sA1 za|NMHj4Tui4FXjPLP75a&8>l|2h~*=BZ(3<&A#g+Jhv#;>Yf|ABV3#_q@DgScPjoI;u<3 zWnvw9sn=xsvzbdxwt6oPJNzX4+jD+rkhp>$g@-)nmZzfzN`-4aXVhTY4%ShrN)?zg zU>c(UWX{U3265PL9*3vADEuo(f-j2WvdTVXI`B$TieG>_^r-0I8BC)|dk3rS^P-?f z<^*w0!Gv+RvN$HIc6bW%(ETt6252W(bmA)XKv$6;p`_+0_=f%NBLf%Hl_%~(5W8!9 zDtL|6eIYc*b;!=GjK3r8?S8OFrJP?O6(;Lsj$yiTWgrbE30D_~$T)8f&8;UP?@=vD zNA7933ok(jhxi4|{JI|nz5N9j{LY@=B<*X|UzCD1Q_XP)PQXGKy8M=?UFNoO_Ph)8 z8}pjyZ7B|^pMofAWAy{f70d$XZ=hReMEw**L7N{3w@CM;H0^QtTmPQBb#&|HRHvj# zXT|V}O79k_dE&ZLbDn>?>`2!AV5(YRLsb*2zen18m3GY6(`I*qUNV#g`);4vLu+Vi zZEYRT!E(7dib8%iV%$px>?*Y@S!R<#C#Aid4*KR(lY%%{n-*N+{wy}h&@>(_0A1&H zR9AaDdOvwBZW-nqoO4r)O_Bv6Lwy(80$tVF0P89lWnaTAkPj-Q-h!x0<=3JQzUpCC aL&IDA)gP=|PbTUB0000" + project.getName() + ""); + final JLabel thumbnailLabel = new JLabel(loadImage(project.getThumbnailUrl())); + final JLabel nameLabel = new JLabel("" + project.getName() + ""); nameLabel.setFont(nameLabel.getFont().deriveFont(12f)); - JTextArea descriptionArea = new JTextArea(project.getDescription().replace("
", "\n")); + final JTextArea descriptionArea = new JTextArea(project.getDescription().replace("
", "\n")); descriptionArea.setEditable(false); descriptionArea.setFont(thumbnailLabel.getFont()); descriptionArea.setLineWrap(true); @@ -188,7 +189,7 @@ public class ResultsScrollPanel extends JScrollPane { caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); descriptionArea.setEnabled(false); - JLabel commentLabel = + final JLabel commentLabel = new JLabel(Integer.toString(project.getCommentCount()), IconLoader.Messages.getIcon(), SwingConstants.LEFT); commentLabel.setToolTipText("Click to see and add public comments"); commentLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); @@ -218,27 +219,26 @@ public class ResultsScrollPanel extends JScrollPane { } }); - JLabel viewLabel = + final JLabel viewLabel = new JLabel(Integer.toString(project.getViewCount()), IconLoader.Eye.getIcon(), SwingConstants.LEFT); viewLabel.setToolTipText("View count"); - JLabel downloadLabel = + final JLabel downloadLabel = new JLabel(Integer.toString(project.getDownloadCount()), IconLoader.Download.getIcon(), SwingConstants.LEFT); downloadLabel.setToolTipText("Download count"); - JLabel categoryLabel = new JLabel("Category: " + project.getCategory() + ""); - JLabel authorLabel = new JLabel("Author: " + project.getOwner() + ""); - JLabel updatedLabel = new JLabel("Last updated: " + project.getUpdated() + ""); - JButton downloadButton = new JButton(IconLoader.CloudDownload.getIcon()); + final JLabel categoryLabel = new JLabel("Category: " + project.getCategory() + ""); + final JLabel authorLabel = new JLabel("Author: " + project.getOwner() + ""); + final JLabel updatedLabel = new JLabel("Last updated: " + project.getUpdated() + ""); - downloadButton.setBorderPainted(false); - downloadButton.setContentAreaFilled(false); + final JLabel downloadButton = new JLabel(IconLoader.CloudDownload.getIcon()); + downloadButton.setFocusable(true); downloadButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); downloadButton.setToolTipText("Download to local drive"); - downloadButton.addActionListener(new ActionListener() { + downloadButton.addMouseListener(new MouseAdapter() { @Override - public void actionPerformed(ActionEvent e) { + public void mouseClicked(MouseEvent e) { final File file = DialogFactory.getInstance().showSaveDialog((JFrame) cloudUI, FileFilterEnum.DIY.getFilter(), new File(project.getName() + ".diy"), FileFilterEnum.DIY.getExtensions()[0], null); @@ -297,21 +297,144 @@ public class ResultsScrollPanel extends JScrollPane { } }); - JButton reuploadButton = new JButton(IconLoader.CloudUpload.getIcon()); - reuploadButton.setContentAreaFilled(false); + final JLabel spacerLabel = new JLabel(); + final JSeparator separator = new JSeparator(); + + final JPanel buttonPanel = new JPanel(new FlowLayout()); + + final JLabel editButton = new JLabel(IconLoader.CloudEdit.getIcon()); + editButton.setFocusable(true); + editButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + editButton.setToolTipText("Edit details without changing the project file"); + + final JLabel reuploadButton = new JLabel(IconLoader.CloudUpload.getIcon()); + reuploadButton.setFocusable(true); reuploadButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); reuploadButton.setToolTipText("Re-upload to the cloud"); + reuploadButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + final Presenter thumbnailPresenter = new Presenter(new DummyView()); + final File file = + DialogFactory.getInstance().showOpenDialog(FileFilterEnum.DIY.getFilter(), null, + FileFilterEnum.DIY.getExtensions()[0], null, cloudUI.getOwnerFrame()); + if (file != null) { + LOG.info("Preparing re-upload of project " + project.getName() + "(" + project.getId() + ")"); + cloudUI.executeBackgroundTask(new ITask() { - JButton deleteButton = new JButton(IconLoader.CloudDelete.getIcon()); - deleteButton.setContentAreaFilled(false); + @Override + public String[] doInBackground() throws Exception { + LOG.debug("Uploading from " + file.getAbsolutePath()); + thumbnailPresenter.loadProjectFromFile(file.getAbsolutePath()); + return cloudPresenter.getCategories(); + } + + @Override + public void complete(final String[] result) { + final UploadDialog dialog = + DialogFactory.getInstance().createUploadDialog(cloudUI.getOwnerFrame(), thumbnailPresenter, result, true); + dialog.setVisible(true); + if (ButtonDialog.OK.equals(dialog.getSelectedButtonCaption())) { + try { + final File thumbnailFile = File.createTempFile("upload-thumbnail", ".png"); + if (ImageIO.write(dialog.getThumbnail(), "png", thumbnailFile)) { + cloudUI.executeBackgroundTask(new ITask() { + + @Override + public ProjectEntity doInBackground() throws Exception { + cloudPresenter.uploadProject(dialog.getName(), dialog.getCategory(), dialog.getDescription(), + dialog.getKeywords(), plugInPort.getCurrentVersionNumber().toString(), thumbnailFile, file, + project.getId()); + return cloudPresenter.fetchUserUploads(project.getId()).get(0); + } + + @Override + public void failed(Exception e) { + cloudUI.showMessage(e.getMessage(), "Upload Error", IView.ERROR_MESSAGE); + } + + @Override + public void complete(ProjectEntity result) { + nameLabel.setText("" + project.getName() + ""); + categoryLabel.setText(result.getCategory()); + descriptionArea.setText(result.getDescription().replace("
", "\n")); + categoryLabel.setText("Category: " + result.getCategory() + ""); + updatedLabel.setText("Last updated: " + result.getUpdated() + ""); + thumbnailLabel.setIcon(new ImageIcon(dialog.getThumbnail())); + cloudUI + .showMessage( + "The project has been uploaded to the cloud successfully. Thank you for your contribution!", + "Upload Success", IView.INFORMATION_MESSAGE); + } + }); + } else { + cloudUI.showMessage("Could not prepare temporary files to be uploaded to the cloud.", + "Upload Error", IView.ERROR_MESSAGE); + } + } catch (Exception e) { + cloudUI.showMessage(e.getMessage(), "Upload Error", IView.ERROR_MESSAGE); + } + } + } + + @Override + public void failed(Exception e) { + cloudUI.showMessage("Could not open file. " + e.getMessage(), "Error", ISwingUI.ERROR_MESSAGE); + } + }); + } + } + }); + + final JLabel deleteButton = new JLabel(IconLoader.CloudDelete.getIcon()); + deleteButton.setFocusable(true); deleteButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); deleteButton.setToolTipText("Delete from the cloud"); + deleteButton.addMouseListener(new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + if (cloudUI.showConfirmDialog("Are you sure you want to permanently delete project " + project.getName() + + " from the cloud?", "Delete Project", IView.YES_NO_OPTION, IView.QUESTION_MESSAGE) == IView.YES_OPTION) { + LOG.info("Deleting project " + project.getName() + "(" + project.getId() + ")"); + cloudUI.executeBackgroundTask(new ITask() { + + @Override + public Void doInBackground() throws Exception { + cloudPresenter.deleteProject(project.getId()); + return null; + } + + @Override + public void failed(Exception e) { + cloudUI.showMessage("Could not delete the project. Detailed message is in the logs.", "Error", + ISwingUI.ERROR_MESSAGE); + } + + @Override + public void complete(Void result) { + getResultsPanel().remove(thumbnailLabel); + getResultsPanel().remove(nameLabel); + getResultsPanel().remove(spacerLabel); + getResultsPanel().remove(commentLabel); + getResultsPanel().remove(viewLabel); + getResultsPanel().remove(downloadLabel); + getResultsPanel().remove(descriptionArea); + getResultsPanel().remove(categoryLabel); + getResultsPanel().remove(buttonPanel); + getResultsPanel().remove(authorLabel); + getResultsPanel().remove(updatedLabel); + getResultsPanel().remove(separator); + } + }); + } + } + }); - JPanel buttonPanel = new JPanel(new FlowLayout()); buttonPanel.setBackground(Color.white); - // buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); buttonPanel.add(downloadButton); if (showEditControls) { + buttonPanel.add(editButton); buttonPanel.add(reuploadButton); buttonPanel.add(deleteButton); } @@ -334,7 +457,7 @@ public class ResultsScrollPanel extends JScrollPane { gbc.gridx++; gbc.weightx = 0.1; - getResultsPanel().add(new JLabel(), gbc); + getResultsPanel().add(spacerLabel, gbc); gbc.gridx++; gbc.weightx = 0; @@ -388,7 +511,7 @@ public class ResultsScrollPanel extends JScrollPane { gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; gbc.insets = new Insets(2, 2, 2, 2); - getResultsPanel().add(new JSeparator(), gbc); + getResultsPanel().add(separator, gbc); return nameLabel; } diff --git a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java index 18b2fde6..7058d5b9 100644 --- a/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java +++ b/diylc/diylc-swing/src/org/diylc/swing/plugins/cloud/view/browser/UploadManagerFrame.java @@ -62,7 +62,7 @@ public class UploadManagerFrame extends JFrame implements ISimpleView { @Override public List doInBackground() throws Exception { - return cloudPresenter.fetchUserUploads(); + return cloudPresenter.fetchUserUploads(null); } @Override @@ -73,7 +73,7 @@ public class UploadManagerFrame extends JFrame implements ISimpleView { @Override public void complete(List result) { - setTitle(TITLE + " - " + result.size() + " Uploads Found"); +// setTitle(TITLE + " - " + result.size() + " Uploads Found"); getResultsScrollPane().startSearch(result); } }); diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index 797da6cf..fffaeba0 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1365,6 +1365,10 @@ BUG_FIX Solder pad component should not allow negative size + + + BUG_FIX + Fixed silent error when having a resistor without a valid value (e.g. missing units) https://github.com/bancika/diy-layout-creator/releases