Merge lp:~mcuelenaere/syncany/trunk into lp:~syncany-team/syncany/trunk

Proposed by Maurus Cuelenaere on 2012-02-11
Status: Needs review
Proposed branch: lp:~mcuelenaere/syncany/trunk
Merge into: lp:~syncany-team/syncany/trunk
Diff against target: 632 lines (+522/-1)
9 files modified
syncany/README (+4/-0)
syncany/build.xml (+5/-1)
syncany/nbproject/project.properties (+8/-0)
syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.form (+42/-0)
syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.java (+126/-0)
syncany/src/org/syncany/connection/plugins/dropbox/DropboxConnection.java (+121/-0)
syncany/src/org/syncany/connection/plugins/dropbox/DropboxPluginInfo.java (+57/-0)
syncany/src/org/syncany/connection/plugins/dropbox/DropboxTransferManager.java (+145/-0)
syncany/src/org/syncany/i18n/I18n_en_US.properties (+14/-0)
To merge this branch: bzr merge lp:~mcuelenaere/syncany/trunk
Reviewer Review Type Date Requested Status
Syncany Team 2012-02-11 Pending
Review via email: mp+92642@code.launchpad.net

Description of the change

Adds some minor fixes + Dropbox plugin

To post a comment you must log in.

Unmerged revisions

63. By Maurus Cuelenaere on 2012-02-11

Add Dropbox plugin

62. By Maurus Cuelenaere on 2012-02-11

Fix project.properties

61. By Maurus Cuelenaere on 2012-02-11

Fix Linux run target

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'syncany/README'
2--- syncany/README 2011-06-10 18:44:48 +0000
3+++ syncany/README 2012-02-11 23:28:18 +0000
4@@ -62,3 +62,7 @@
5 - The Syncany Rackspace plugin uses the java-cloudfiles library provided by
6 Rackspace (https://github.com/rackspace/java-cloudfiles). It is distributed
7 under the GPL-compatible MIT License.
8+
9+- The Dropbox plugin uses the SDK provided by Dropbox
10+ (https://www.dropbox.com/developers/reference/sdk). It is distributed under
11+ the GPL-compatible MIT License.
12
13=== modified file 'syncany/build.xml'
14--- syncany/build.xml 2011-06-05 20:06:20 +0000
15+++ syncany/build.xml 2012-02-11 23:28:18 +0000
16@@ -163,7 +163,11 @@
17 </fileset>
18 </copy>
19 </target>
20-
21+
22+ <target name="run" depends="compile" if="isLinux">
23+ <exec dir="bin" executable="./syncany.sh" />
24+ </target>
25+
26 <!--
27
28 There exist several targets which are by default empty and which can be
29
30=== added directory 'syncany/lib/plugins/dropbox'
31=== added file 'syncany/lib/plugins/dropbox/dropbox-java-sdk-1.2.3.jar'
32Binary files syncany/lib/plugins/dropbox/dropbox-java-sdk-1.2.3.jar 1970-01-01 00:00:00 +0000 and syncany/lib/plugins/dropbox/dropbox-java-sdk-1.2.3.jar 2012-02-11 23:28:18 +0000 differ
33=== added file 'syncany/lib/plugins/dropbox/httpmime-4.0.3.jar'
34Binary files syncany/lib/plugins/dropbox/httpmime-4.0.3.jar 1970-01-01 00:00:00 +0000 and syncany/lib/plugins/dropbox/httpmime-4.0.3.jar 2012-02-11 23:28:18 +0000 differ
35=== added file 'syncany/lib/plugins/dropbox/json_simple-1.1.jar'
36Binary files syncany/lib/plugins/dropbox/json_simple-1.1.jar 1970-01-01 00:00:00 +0000 and syncany/lib/plugins/dropbox/json_simple-1.1.jar 2012-02-11 23:28:18 +0000 differ
37=== modified file 'syncany/nbproject/project.properties'
38--- syncany/nbproject/project.properties 2011-06-05 21:47:40 +0000
39+++ syncany/nbproject/project.properties 2012-02-11 23:28:18 +0000
40@@ -34,6 +34,7 @@
41 excludes=
42 file.reference.AbsoluteLayout.jar=lib/AbsoluteLayout.jar
43 file.reference.AppFramework-1.03.jar=lib/AppFramework-1.03.jar
44+file.reference.bcprov-jdk16-146.jar=lib/bcprov-jdk16-146.jar
45 file.reference.box4j-1.4.0.jar=lib/plugins/box/box4j-1.4.0.jar
46 file.reference.commons-cli-1.2.jar=lib/commons-cli-1.2.jar
47 file.reference.commons-codec-1.4.jar=lib/commons-codec-1.4.jar
48@@ -45,6 +46,7 @@
49 file.reference.commons-vfs-1.0.jar=lib/commons-vfs-1.0.jar
50 file.reference.derby-10.8.1.2.jar=lib/derby-10.8.1.2.jar
51 file.reference.dom4j-1.6.1.jar=lib/dom4j-1.6.1.jar
52+file.reference.dropbox-java-sdk-1.2.3.jar=lib/plugins/dropbox/dropbox-java-sdk-1.2.3.jar
53 file.reference.eclipselink-2.2.0.jar=lib/eclipselink-2.2.0.jar
54 file.reference.eclipselink-javax.persistence-2.0.jar=lib/eclipselink-javax.persistence-2.0.jar
55 file.reference.gdata-client-1.0.jar=lib/plugins/picasa/gdata-client-1.0.jar
56@@ -55,6 +57,7 @@
57 file.reference.guava-r09.jar=lib/plugins/picasa/guava-r09.jar
58 file.reference.httpclient-4.0.3.jar=lib/httpclient-4.0.3.jar
59 file.reference.httpcore-4.1.jar=lib/httpcore-4.1.jar
60+file.reference.httpmime-4.0.3.jar=lib/plugins/dropbox/httpmime-4.0.3.jar
61 file.reference.inotify-java-recursive-source=../inotify-java-recursive/source
62 file.reference.j2ssh-core-0.2.9.jar=lib/plugins/sftp/j2ssh-core-0.2.9.jar
63 file.reference.java-cloudfiles.jar=lib/plugins/rackspace/java-cloudfiles.jar
64@@ -66,6 +69,7 @@
65 file.reference.jets3t-0.8.1.jar-1=lib/plugins/shared/jets3t-0.8.1.jar
66 file.reference.jpathwatch-0-94-libs-only.jar=lib/jpathwatch-0-94-libs-only.jar
67 file.reference.jsch-0.1.44.jar=lib/jsch-0.1.44.jar
68+file.reference.json_simple-1.1.jar=lib/plugins/dropbox/json_simple-1.1.jar
69 file.reference.log4j-1.2.jar=lib/log4j-1.2.jar
70 file.reference.mx4j-3.0.2.jar=lib/mx4j-3.0.2.jar
71 file.reference.mysql-connector-java-5.1.13-bin.jar=lib/mysql-connector-java-5.1.13-bin.jar
72@@ -73,6 +77,7 @@
73 file.reference.rabin-hash-function-2.0.jar=lib/rabin-hash-function-2.0.jar
74 file.reference.sardine.jar=lib/plugins/webdav/sardine.jar
75 file.reference.source-java=../inotify-java-recursive/source/java
76+file.reference.SSHTools-j2ssh-ext-0.1.0.jar=lib/plugins/sftp/SSHTools-j2ssh-ext-0.1.0.jar
77 file.reference.swing-layout-1.0.4.jar=lib/swing-layout-1.0.4.jar
78 file.reference.swing-worker-1.1.jar=lib/swing-worker-1.1.jar
79 includes=**
80@@ -120,8 +125,11 @@
81 ${file.reference.rabin-hash-function-2.0.jar}:\
82 ${file.reference.swing-layout-1.0.4.jar}:\
83 ${file.reference.swing-worker-1.1.jar}:\
84+ ${file.reference.dropbox-java-sdk-1.2.3.jar}:\
85 ${file.reference.bcprov-jdk16-146.jar}:\
86 ${file.reference.SSHTools-j2ssh-ext-0.1.0.jar}:\
87+ ${file.reference.httpmime-4.0.3.jar}:\
88+ ${file.reference.json_simple-1.1.jar}:\
89 ${file.reference.jsch-0.1.44.jar}
90 # Space-separated list of extra javac options
91 javac.compilerargs=
92
93=== added directory 'syncany/src/org/syncany/connection/plugins/dropbox'
94=== added file 'syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.form'
95--- syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.form 1970-01-01 00:00:00 +0000
96+++ syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.form 2012-02-11 23:28:18 +0000
97@@ -0,0 +1,42 @@
98+<?xml version="1.0" encoding="UTF-8" ?>
99+
100+<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
101+ <AuxValues>
102+ <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
103+ <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
104+ <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
105+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
106+ <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
107+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
108+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
109+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
110+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
111+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,56,0,0,0,-34"/>
112+ </AuxValues>
113+
114+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout">
115+ <Property name="axis" type="int" value="1"/>
116+ </Layout>
117+ <SubComponents>
118+ <Component class="javax.swing.JLabel" name="lblStatus">
119+ <Properties>
120+ <Property name="horizontalAlignment" type="int" value="2"/>
121+ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
122+ <Connection code="resourceBundle.getString(&quot;dropbox_begin_auth&quot;)" type="code"/>
123+ </Property>
124+ <Property name="name" type="java.lang.String" value="lblStatus" noResource="true"/>
125+ </Properties>
126+ </Component>
127+ <Component class="javax.swing.JButton" name="btnAuthenticate">
128+ <Properties>
129+ <Property name="text" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
130+ <Connection code="resourceBundle.getString(&quot;dropbox_btn_authenticate&quot;)" type="code"/>
131+ </Property>
132+ <Property name="name" type="java.lang.String" value="btnAuthenticate"/>
133+ </Properties>
134+ <Events>
135+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnAuthenticateActionPerformed"/>
136+ </Events>
137+ </Component>
138+ </SubComponents>
139+</Form>
140
141=== added file 'syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.java'
142--- syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.java 1970-01-01 00:00:00 +0000
143+++ syncany/src/org/syncany/connection/plugins/dropbox/DropboxConfigPanel.java 2012-02-11 23:28:18 +0000
144@@ -0,0 +1,126 @@
145+/*
146+ * Syncany, www.syncany.org
147+ * Copyright (C) 2012 Maurus Cuelenaere<mcuelenaere@gmail.com>
148+ *
149+ * This program is free software: you can redistribute it and/or modify
150+ * it under the terms of the GNU General Public License as published by
151+ * the Free Software Foundation, either version 3 of the License, or
152+ * (at your option) any later version.
153+ *
154+ * This program is distributed in the hope that it will be useful,
155+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
156+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
157+ * GNU General Public License for more details.
158+ *
159+ * You should have received a copy of the GNU General Public License
160+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
161+ */
162+package org.syncany.connection.plugins.dropbox;
163+
164+import java.awt.Desktop;
165+import java.net.URI;
166+import java.util.ResourceBundle;
167+import javax.swing.JOptionPane;
168+import org.syncany.config.Config;
169+import org.syncany.connection.plugins.ConfigPanel;
170+import org.syncany.connection.plugins.dropbox.DropboxConnection.DropboxAuthentication;
171+
172+/**
173+ * @author Maurus Cuelenaere <mcuelenaere@gmail.com>
174+ */
175+public class DropboxConfigPanel extends ConfigPanel {
176+ private ResourceBundle resourceBundle;
177+ private DropboxAuthentication pendingAuthentication;
178+
179+ public DropboxConfigPanel(DropboxConnection connection) {
180+ super(connection);
181+ resourceBundle = Config.getInstance().getResourceBundle();
182+ initComponents();
183+ }
184+
185+ @Override
186+ public void load() {
187+ if (getConnection().isAuthenticated()) {
188+ lblStatus.setText(resourceBundle.getString("dropbox_auth_success"));
189+ btnAuthenticate.setText(resourceBundle.getString("dropbox_btn_reauthenticate"));
190+ } else {
191+ lblStatus.setText(resourceBundle.getString("dropbox_begin_auth"));
192+ btnAuthenticate.setText(resourceBundle.getString("dropbox_btn_authenticate"));
193+ }
194+ }
195+
196+ @Override
197+ public void save() {
198+ // do nothing
199+ }
200+
201+ @Override
202+ public DropboxConnection getConnection() {
203+ return (DropboxConnection) super.getConnection();
204+ }
205+
206+ private void browseUrl(String url) {
207+ try {
208+ Desktop.getDesktop().browse(new URI(url));
209+ } catch (Exception ex) {
210+ // fallback
211+ JOptionPane.showInputDialog(this, resourceBundle.getString("dropbox_browse_url"), url);
212+ }
213+ }
214+
215+ /** This method is called from within the constructor to
216+ * initialize the form.
217+ * WARNING: Do NOT modify this code. The content of this method is
218+ * always regenerated by the Form Editor.
219+ */
220+ @SuppressWarnings("unchecked")
221+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
222+ private void initComponents() {
223+
224+ lblStatus = new javax.swing.JLabel();
225+ btnAuthenticate = new javax.swing.JButton();
226+
227+ setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
228+
229+ lblStatus.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
230+ lblStatus.setText(resourceBundle.getString("dropbox_begin_auth"));
231+ lblStatus.setName("lblStatus"); // NOI18N
232+ add(lblStatus);
233+
234+ btnAuthenticate.setText(resourceBundle.getString("dropbox_btn_authenticate"));
235+ btnAuthenticate.setName("btnAuthenticate");
236+ btnAuthenticate.addActionListener(new java.awt.event.ActionListener() {
237+ public void actionPerformed(java.awt.event.ActionEvent evt) {
238+ btnAuthenticateActionPerformed(evt);
239+ }
240+ });
241+ add(btnAuthenticate);
242+ }// </editor-fold>//GEN-END:initComponents
243+
244+ private void btnAuthenticateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAuthenticateActionPerformed
245+ if (pendingAuthentication != null) {
246+ boolean result = pendingAuthentication.complete();
247+ pendingAuthentication = null;
248+
249+ if (result) {
250+ btnAuthenticate.setText(resourceBundle.getString("dropbox_btn_reauthenticate"));
251+ lblStatus.setText(resourceBundle.getString("dropbox_auth_success"));
252+ } else {
253+ btnAuthenticate.setText(resourceBundle.getString("dropbox_btn_authenticate"));
254+ lblStatus.setText(resourceBundle.getString("dropbox_auth_fail"));
255+ }
256+ } else {
257+ pendingAuthentication = getConnection().authenticate();
258+
259+ browseUrl(pendingAuthentication.getUrl());
260+
261+ lblStatus.setText(resourceBundle.getString("dropbox_awaiting_auth"));
262+ btnAuthenticate.setText(resourceBundle.getString("dropbox_btn_complete_authentication"));
263+ }
264+ }//GEN-LAST:event_btnAuthenticateActionPerformed
265+
266+ // Variables declaration - do not modify//GEN-BEGIN:variables
267+ private javax.swing.JButton btnAuthenticate;
268+ private javax.swing.JLabel lblStatus;
269+ // End of variables declaration//GEN-END:variables
270+}
271
272=== added file 'syncany/src/org/syncany/connection/plugins/dropbox/DropboxConnection.java'
273--- syncany/src/org/syncany/connection/plugins/dropbox/DropboxConnection.java 1970-01-01 00:00:00 +0000
274+++ syncany/src/org/syncany/connection/plugins/dropbox/DropboxConnection.java 2012-02-11 23:28:18 +0000
275@@ -0,0 +1,121 @@
276+/*
277+ * Syncany, www.syncany.org
278+ * Copyright (C) 2012 Maurus Cuelenaere<mcuelenaere@gmail.com>
279+ *
280+ * This program is free software: you can redistribute it and/or modify
281+ * it under the terms of the GNU General Public License as published by
282+ * the Free Software Foundation, either version 3 of the License, or
283+ * (at your option) any later version.
284+ *
285+ * This program is distributed in the hope that it will be useful,
286+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
287+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
288+ * GNU General Public License for more details.
289+ *
290+ * You should have received a copy of the GNU General Public License
291+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
292+ */
293+package org.syncany.connection.plugins.dropbox;
294+
295+import com.dropbox.client2.exception.DropboxException;
296+import com.dropbox.client2.session.AccessTokenPair;
297+import com.dropbox.client2.session.AppKeyPair;
298+import com.dropbox.client2.session.Session;
299+import com.dropbox.client2.session.WebAuthSession;
300+import com.dropbox.client2.session.WebAuthSession.WebAuthInfo;
301+import java.util.logging.Level;
302+import java.util.logging.Logger;
303+import org.syncany.config.ConfigNode;
304+import org.syncany.connection.plugins.ConfigPanel;
305+import org.syncany.connection.plugins.Connection;
306+import org.syncany.connection.plugins.PluginInfo;
307+import org.syncany.connection.plugins.TransferManager;
308+import org.syncany.exceptions.ConfigException;
309+
310+/**
311+ * @author Maurus Cuelenaere <mcuelenaere@gmail.com>
312+ */
313+public class DropboxConnection implements Connection {
314+ private static final AppKeyPair APP_KEY = new AppKeyPair("<FILLME>", "<FILLME>");
315+ private static final Logger logger = Logger.getLogger(DropboxConnection.class.getSimpleName());
316+
317+ private WebAuthSession authSession;
318+
319+ public DropboxConnection() {
320+ authSession = new WebAuthSession(APP_KEY, Session.AccessType.APP_FOLDER);
321+ }
322+
323+ public WebAuthSession getAuthSession() {
324+ return authSession;
325+ }
326+
327+ public boolean isAuthenticated() {
328+ return authSession.getAccessTokenPair() != null;
329+ }
330+
331+ public class DropboxAuthentication {
332+ private final WebAuthInfo authInfo;
333+
334+ public DropboxAuthentication() throws DropboxException {
335+ authInfo = authSession.getAuthInfo();
336+ }
337+
338+ public String getUrl() {
339+ return authInfo.url;
340+ }
341+
342+ public boolean complete() {
343+ try {
344+ authSession.retrieveWebAccessToken(authInfo.requestTokenPair);
345+ return true;
346+ } catch (DropboxException ex) {
347+ logger.log(Level.WARNING, "Couldn't complete Dropbox authentication", ex);
348+ return false;
349+ }
350+ }
351+ }
352+
353+ public DropboxAuthentication authenticate() {
354+ try {
355+ return new DropboxAuthentication();
356+ } catch (DropboxException ex) {
357+ logger.log(Level.WARNING, "Couldn't start Dropbox authentication", ex);
358+ return null;
359+ }
360+ }
361+
362+ @Override
363+ public TransferManager createTransferManager() {
364+ return new DropboxTransferManager(this);
365+ }
366+
367+ @Override
368+ public ConfigPanel createConfigPanel() {
369+ return new DropboxConfigPanel(this);
370+ }
371+
372+ @Override
373+ public PluginInfo getPluginInfo() {
374+ return new DropboxPluginInfo();
375+ }
376+
377+ @Override
378+ public void load(ConfigNode node) throws ConfigException {
379+ String key = node.getProperty("accessKey");
380+ String secret = node.getProperty("accessSecret");
381+
382+ if (key == null || secret == null)
383+ throw new ConfigException("Dropbox connection properties must at least contain the parameters 'accessKey' and 'accessSecret'.");
384+
385+ authSession.setAccessTokenPair(new AccessTokenPair(key, secret));
386+ }
387+
388+ @Override
389+ public void save(ConfigNode node) {
390+ AccessTokenPair tokenPair = authSession.getAccessTokenPair();
391+
392+ node.setAttribute("type", getPluginInfo().getId());
393+ node.setProperty("accessKey", tokenPair.key);
394+ node.setProperty("accessSecret", tokenPair.secret);
395+ }
396+}
397\ No newline at end of file
398
399=== added file 'syncany/src/org/syncany/connection/plugins/dropbox/DropboxPluginInfo.java'
400--- syncany/src/org/syncany/connection/plugins/dropbox/DropboxPluginInfo.java 1970-01-01 00:00:00 +0000
401+++ syncany/src/org/syncany/connection/plugins/dropbox/DropboxPluginInfo.java 2012-02-11 23:28:18 +0000
402@@ -0,0 +1,57 @@
403+/*
404+ * Syncany, www.syncany.org
405+ * Copyright (C) 2012 Maurus Cuelenaere<mcuelenaere@gmail.com>
406+ *
407+ * This program is free software: you can redistribute it and/or modify
408+ * it under the terms of the GNU General Public License as published by
409+ * the Free Software Foundation, either version 3 of the License, or
410+ * (at your option) any later version.
411+ *
412+ * This program is distributed in the hope that it will be useful,
413+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
415+ * GNU General Public License for more details.
416+ *
417+ * You should have received a copy of the GNU General Public License
418+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
419+ */
420+package org.syncany.connection.plugins.dropbox;
421+
422+import java.util.ResourceBundle;
423+import org.syncany.config.Config;
424+import org.syncany.connection.plugins.Connection;
425+import org.syncany.connection.plugins.PluginInfo;
426+
427+/**
428+ * @author Maurus Cuelenaere <mcuelenaere@gmail.com>
429+ */
430+public class DropboxPluginInfo extends PluginInfo {
431+ public static final String ID = "dropbox";
432+
433+ private ResourceBundle resourceBundle = Config.getInstance().getResourceBundle();
434+
435+ @Override
436+ public String getId() {
437+ return ID;
438+ }
439+
440+ @Override
441+ public String getName() {
442+ return resourceBundle.getString("dropbox_plugin_name");
443+ }
444+
445+ @Override
446+ public Integer[] getVersion() {
447+ return new Integer[] {0, 1};
448+ }
449+
450+ @Override
451+ public String getDescripton() {
452+ return resourceBundle.getString("dropbox_plugin_description");
453+ }
454+
455+ @Override
456+ public Connection createConnection() {
457+ return new DropboxConnection();
458+ }
459+}
460
461=== added file 'syncany/src/org/syncany/connection/plugins/dropbox/DropboxTransferManager.java'
462--- syncany/src/org/syncany/connection/plugins/dropbox/DropboxTransferManager.java 1970-01-01 00:00:00 +0000
463+++ syncany/src/org/syncany/connection/plugins/dropbox/DropboxTransferManager.java 2012-02-11 23:28:18 +0000
464@@ -0,0 +1,145 @@
465+/*
466+ * Syncany, www.syncany.org
467+ * Copyright (C) 2012 Maurus Cuelenaere<mcuelenaere@gmail.com>
468+ *
469+ * This program is free software: you can redistribute it and/or modify
470+ * it under the terms of the GNU General Public License as published by
471+ * the Free Software Foundation, either version 3 of the License, or
472+ * (at your option) any later version.
473+ *
474+ * This program is distributed in the hope that it will be useful,
475+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
476+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
477+ * GNU General Public License for more details.
478+ *
479+ * You should have received a copy of the GNU General Public License
480+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
481+ */
482+package org.syncany.connection.plugins.dropbox;
483+
484+import com.dropbox.client2.DropboxAPI;
485+import com.dropbox.client2.exception.DropboxException;
486+import com.dropbox.client2.exception.DropboxServerException;
487+import com.dropbox.client2.session.WebAuthSession;
488+import java.io.*;
489+import java.util.HashMap;
490+import java.util.Map;
491+import org.syncany.connection.plugins.AbstractTransferManager;
492+import org.syncany.exceptions.LocalFileNotFoundException;
493+import org.syncany.exceptions.RemoteFileNotFoundException;
494+import org.syncany.exceptions.StorageConnectException;
495+import org.syncany.exceptions.StorageException;
496+import org.syncany.repository.files.RemoteFile;
497+
498+/**
499+ * @author Maurus Cuelenaere <mcuelenaere@gmail.com>
500+ */
501+public class DropboxTransferManager extends AbstractTransferManager {
502+ private final DropboxAPI<WebAuthSession> api;
503+ private String cachedListHash;
504+ private Map<String, RemoteFile> cachedListResult;
505+
506+ public DropboxTransferManager(DropboxConnection connection) {
507+ super(connection);
508+
509+ api = new DropboxAPI<WebAuthSession>(connection.getAuthSession());
510+ }
511+
512+ @Override
513+ public void connect() throws StorageConnectException {
514+ }
515+
516+ @Override
517+ public void disconnect() throws StorageException {
518+ }
519+
520+ @Override
521+ public void download(RemoteFile remoteFile, File localFile) throws RemoteFileNotFoundException, StorageException {
522+ String name = "/" + remoteFile.getName();
523+ OutputStream out = null;
524+ try {
525+ out = new FileOutputStream(localFile);
526+ api.getFile(name, null, out, null);
527+ } catch (Exception ex) {
528+ if (ex instanceof DropboxServerException) {
529+ DropboxServerException sex = (DropboxServerException) ex;
530+ if (sex.error == 404)
531+ throw new RemoteFileNotFoundException(ex);
532+ }
533+
534+ throw new StorageException(ex);
535+ } finally {
536+ if (out != null) {
537+ try {
538+ out.close();
539+ } catch (IOException ex) {
540+ throw new StorageException(ex);
541+ }
542+ }
543+ }
544+ }
545+
546+ @Override
547+ public void upload(File localFile, RemoteFile remoteFile) throws LocalFileNotFoundException, StorageException {
548+ if (!localFile.exists())
549+ throw new LocalFileNotFoundException();
550+
551+ String name = "/" + remoteFile.getName();
552+ InputStream in = null;
553+ try {
554+ in = new FileInputStream(localFile);
555+ api.putFile(name, in, localFile.length(), null, null);
556+ } catch (Exception ex) {
557+ throw new StorageException(ex);
558+ } finally {
559+ if (in != null) {
560+ try {
561+ in.close();
562+ } catch (IOException ex) {
563+ throw new StorageException(ex);
564+ }
565+ }
566+ }
567+ }
568+
569+ @Override
570+ public void delete(RemoteFile remoteFile) throws RemoteFileNotFoundException, StorageException {
571+ try {
572+ api.delete(remoteFile.getName());
573+ } catch (DropboxException ex) {
574+ throw new StorageException(ex);
575+ }
576+ }
577+
578+ @Override
579+ public Map<String, RemoteFile> list() throws StorageException {
580+ try {
581+ Map<String, RemoteFile> result = new HashMap<String, RemoteFile>();
582+ DropboxAPI.Entry entry = api.metadata("", 0, cachedListHash, true, null);
583+ assert(!entry.isDir);
584+
585+ for (DropboxAPI.Entry child : entry.contents) {
586+ if (child.isDeleted || child.isDir)
587+ continue;
588+
589+ String name = child.path.substring(1); // skip the first slash
590+ RemoteFile file = new RemoteFile(name, child.bytes);
591+ result.put(name, file);
592+ }
593+
594+ // update cache
595+ cachedListHash = entry.hash;
596+ cachedListResult = result;
597+
598+ return result;
599+ } catch (DropboxException ex) {
600+ if (ex instanceof DropboxServerException) {
601+ DropboxServerException sex = (DropboxServerException) ex;
602+ if (sex.error == 304)
603+ return cachedListResult;
604+ }
605+
606+ throw new StorageException(ex);
607+ }
608+ }
609+}
610
611=== modified file 'syncany/src/org/syncany/i18n/I18n_en_US.properties'
612--- syncany/src/org/syncany/i18n/I18n_en_US.properties 2011-06-04 00:29:53 +0000
613+++ syncany/src/org/syncany/i18n/I18n_en_US.properties 2012-02-11 23:28:18 +0000
614@@ -290,3 +290,17 @@
615 webdav_path = Path:
616 webdav_name = WebDAV
617 webdav_plugin_description = Uses a WebDAV folder as data repository.
618+
619+## DROPBOX PLUGIN
620+## DROPBOX PLUGIN INFO
621+dropbox_plugin_name = Dropbox
622+dropbox_plugin_description = Uses Dropbox as data repository
623+## DROPBOX PLUGIN CONFIG PANEL
624+dropbox_auth_success = Authentication successfull!
625+dropbox_auth_fail = Couldn't complete authentication!
626+dropbox_begin_auth = Please start authentication
627+dropbox_awaiting_auth = Awaiting authentication completion...
628+dropbox_btn_authenticate = Authenticate
629+dropbox_btn_reauthenticate = Re-authenticate
630+dropbox_btn_complete_authentication = Complete authentication
631+dropbox_browse_url = Browse to the following url:
632\ No newline at end of file