├── .gitignore ├── src ├── main │ ├── resources │ │ └── .gitkeep │ └── java │ │ └── com │ │ └── podio │ │ └── sample │ │ └── delicious │ │ ├── Bookmark.java │ │ ├── Importer.java │ │ ├── DeliciousReader.java │ │ └── PodioWriter.java └── test │ ├── resources │ └── .gitkeep │ └── java │ └── com │ └── podio │ └── delicious │ └── DeliciousReaderTest.java ├── README.markdown ├── example.config.properties ├── .settings ├── org.maven.ide.eclipse.prefs └── org.eclipse.jdt.core.prefs ├── .project ├── .classpath └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /src/main/resources/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/resources/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Podio API Example - Delicious 2 | ----------------------------- 3 | 4 | This is an example use of the Podio API to import bookmarks from delicious into Podio -------------------------------------------------------------------------------- /example.config.properties: -------------------------------------------------------------------------------- 1 | delicious.feed=http://feeds.delicious.com/v2/rss/chrholm2003 2 | podio.app=13938 3 | podio.endpoint=podio.com 4 | podio.client.mail=client@mail.com 5 | podio.client.secret=clientsecret 6 | podio.user.mail=user@mail.com 7 | podio.user.password=usersecret -------------------------------------------------------------------------------- /.settings/org.maven.ide.eclipse.prefs: -------------------------------------------------------------------------------- 1 | #Fri Dec 17 21:01:08 CET 2010 2 | activeProfiles= 3 | eclipse.preferences.version=1 4 | fullBuildGoals=process-test-resources 5 | resolveWorkspaceProjects=true 6 | resourceFilterGoals=process-resources resources\:testResources 7 | skipCompilerPlugin=true 8 | version=1 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | #Fri Dec 17 21:01:38 CET 2010 2 | eclipse.preferences.version=1 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.compliance=1.5 5 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 6 | org.eclipse.jdt.core.compiler.source=1.5 7 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | delicious 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.maven.ide.eclipse.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.maven.ide.eclipse.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/test/java/com/podio/delicious/DeliciousReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.podio.delicious; 2 | 3 | import java.util.List; 4 | 5 | import junit.framework.Assert; 6 | 7 | import org.junit.Test; 8 | 9 | import com.podio.sample.delicious.Bookmark; 10 | import com.podio.sample.delicious.DeliciousReader; 11 | 12 | public class DeliciousReaderTest { 13 | 14 | @Test 15 | public void readBookmarks() throws Exception { 16 | DeliciousReader reader = new DeliciousReader( 17 | "http://feeds.delicious.com/v2/rss/chrholm"); 18 | List bookmarks = reader.read(); 19 | 20 | Bookmark bookmark = bookmarks.get(1); 21 | Assert.assertEquals(bookmark.getId(), 22 | "1300b39b849a84f637af0d46dbaf9995"); 23 | Assert.assertEquals(bookmark.getTitle(), "Podio"); 24 | Assert.assertEquals(bookmark.getLink(), "http://podio.com/"); 25 | Assert.assertEquals(bookmark.getNotes(), "My note"); 26 | Assert.assertEquals(bookmark.getTags().size(), 1); 27 | Assert.assertEquals(bookmark.getTags().get(0), "podio"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/podio/sample/delicious/Bookmark.java: -------------------------------------------------------------------------------- 1 | package com.podio.sample.delicious; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Represents a bookmark in delicious 7 | */ 8 | public final class Bookmark { 9 | 10 | private final String id; 11 | 12 | private final String title; 13 | 14 | private final String link; 15 | 16 | private final List tags; 17 | 18 | private final String notes; 19 | 20 | public Bookmark(String id, String title, String link, List tags, 21 | String notes) { 22 | super(); 23 | this.id = id; 24 | this.title = title; 25 | this.link = link; 26 | this.tags = tags; 27 | this.notes = notes; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "Bookmark [id=" + id + ", title=" + title + ", link=" + link 33 | + ", tags=" + tags + ", notes=" + notes + "]"; 34 | } 35 | 36 | public String getId() { 37 | return id; 38 | } 39 | 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | public String getLink() { 45 | return link; 46 | } 47 | 48 | public List getTags() { 49 | return tags; 50 | } 51 | 52 | public String getNotes() { 53 | return notes; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/podio/sample/delicious/Importer.java: -------------------------------------------------------------------------------- 1 | package com.podio.sample.delicious; 2 | 3 | import java.io.FileInputStream; 4 | import java.util.List; 5 | import java.util.Properties; 6 | 7 | import com.podio.ResourceFactory; 8 | import com.podio.oauth.OAuthClientCredentials; 9 | import com.podio.oauth.OAuthUsernameCredentials; 10 | 11 | /** 12 | * Imports bookmarks from delicious to a Podio app. The feed, app id and 13 | * authentication configuration must be given in a configuration file. 14 | * 15 | * The app in Podio must have 3 fields with the labels Title, URL and Notes. 16 | */ 17 | public final class Importer { 18 | 19 | private Importer() { 20 | } 21 | 22 | /** 23 | * Start the importer with the given configuration file. This will read the 24 | * bookmarks from delicious and write them to an app in Podio. 25 | * 26 | * @param args 27 | * The first parameter must be the path to the configuration file 28 | * @throws Exception 29 | * If any error occurs during execution 30 | */ 31 | public static void main(String[] args) throws Exception { 32 | if (args.length != 1) { 33 | throw new IllegalArgumentException( 34 | "Expected exactly one argument which should be the path of the configuration file"); 35 | } 36 | 37 | Properties config = new Properties(); 38 | config.load(new FileInputStream(args[0])); 39 | 40 | ResourceFactory podioAPI = new ResourceFactory( 41 | new OAuthClientCredentials( 42 | config.getProperty("podio.client.mail"), 43 | config.getProperty("podio.client.secret")), 44 | new OAuthUsernameCredentials(config 45 | .getProperty("podio.user.mail"), config 46 | .getProperty("podio.user.password"))); 47 | 48 | String feed = config.getProperty("delicious.feed"); 49 | int appId = Integer.parseInt(config.getProperty("podio.app")); 50 | 51 | List bookmarks = new DeliciousReader(feed).read(); 52 | new PodioWriter(appId, podioAPI).write(bookmarks); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.podio.sample 5 | delicious 6 | 0.1.0 7 | Delicious 8 | 9 | 10 | 11 | maven-compiler-plugin 12 | 13 | 1.6 14 | 1.6 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-shade-plugin 20 | 1.4 21 | 22 | 23 | package 24 | 25 | shade 26 | 27 | 28 | 29 | 31 | 32 | com.podio.sample.delicious.Importer 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | MIT 47 | http://creativecommons.org/licenses/MIT/ 48 | 49 | 50 | 51 | 52 | com.podio 53 | api 54 | 0.7.2-SNAPSHOT 55 | compile 56 | 57 | 58 | net.java.dev.rome 59 | rome 60 | 1.0.0 61 | compile 62 | 63 | 64 | net.java.dev.rome 65 | rome-fetcher 66 | 1.0.0 67 | jar 68 | compile 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/com/podio/sample/delicious/DeliciousReader.java: -------------------------------------------------------------------------------- 1 | package com.podio.sample.delicious; 2 | 3 | import java.net.URL; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import com.sun.syndication.feed.synd.SyndCategory; 8 | import com.sun.syndication.feed.synd.SyndEntry; 9 | import com.sun.syndication.feed.synd.SyndFeed; 10 | import com.sun.syndication.fetcher.FeedFetcher; 11 | import com.sun.syndication.fetcher.impl.FeedFetcherCache; 12 | import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache; 13 | import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher; 14 | 15 | /** 16 | * Class for reading feeds from delicious 17 | */ 18 | public final class DeliciousReader { 19 | 20 | private final String feed; 21 | 22 | /** 23 | * Createa new reader for the given feed 24 | * 25 | * @param feed 26 | * The feed to read 27 | */ 28 | public DeliciousReader(String feed) { 29 | super(); 30 | this.feed = feed; 31 | } 32 | 33 | /** 34 | * Retrieves the feed from delicious as an RSS feed 35 | * 36 | * @return The given feed 37 | * @throws Exception 38 | * If any error occurs during communication with delicious 39 | */ 40 | private SyndFeed getFeed() throws Exception { 41 | FeedFetcherCache feedInfoCache = HashMapFeedInfoCache.getInstance(); 42 | FeedFetcher feedFetcher = new HttpURLFeedFetcher(feedInfoCache); 43 | return feedFetcher.retrieveFeed(new URL(feed)); 44 | } 45 | 46 | /** 47 | * Loads the bookmarks from delicious by parsing the RSS feed 48 | * 49 | * @return The loaded bookmarks 50 | * @throws Exception 51 | * If any error occurs while loading the bookmarks 52 | */ 53 | public List read() throws Exception { 54 | SyndFeed syndFeed = getFeed(); 55 | 56 | List bookmarks = new ArrayList(); 57 | List entries = syndFeed.getEntries(); 58 | for (SyndEntry entry : entries) { 59 | List tags = new ArrayList(); 60 | List categories = entry.getCategories(); 61 | for (SyndCategory category : categories) { 62 | tags.add(category.getName()); 63 | } 64 | 65 | String id = entry.getUri().substring( 66 | entry.getUri().lastIndexOf('/') + 1, 67 | entry.getUri().lastIndexOf('#')); 68 | 69 | bookmarks.add(new Bookmark(id, entry.getTitle(), entry.getLink(), 70 | tags, entry.getDescription() != null ? entry.getDescription().getValue() : null)); 71 | } 72 | 73 | return bookmarks; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/podio/sample/delicious/PodioWriter.java: -------------------------------------------------------------------------------- 1 | package com.podio.sample.delicious; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import com.podio.ResourceFactory; 8 | import com.podio.app.AppAPI; 9 | import com.podio.app.Application; 10 | import com.podio.app.ApplicationField; 11 | import com.podio.item.FieldValuesUpdate; 12 | import com.podio.item.ItemAPI; 13 | import com.podio.item.ItemBadge; 14 | import com.podio.item.ItemCreate; 15 | 16 | /** 17 | * Writer to save bookmarks to a Podio app. 18 | * 19 | * The app in Podio must have 3 fields with the labels Title, URL and Notes. 20 | */ 21 | public final class PodioWriter { 22 | 23 | private final int appId; 24 | 25 | private final ResourceFactory podioAPI; 26 | 27 | /** 28 | * Creates a new writer that will write to the given app using the API 29 | * 30 | * @param appId 31 | * The id of the app 32 | * @param podioAPI 33 | * The API class to use 34 | */ 35 | public PodioWriter(int appId, ResourceFactory podioAPI) { 36 | super(); 37 | this.appId = appId; 38 | this.podioAPI = podioAPI; 39 | } 40 | 41 | /** 42 | * Creates the app mapping for the app id from the configuration 43 | * 44 | * @return The app mapping created 45 | */ 46 | private AppMapping getAppMapping() { 47 | Application app = new AppAPI(podioAPI).getApp(appId); 48 | 49 | return AppMapping.get(app); 50 | } 51 | 52 | /** 53 | * Saves the bookmarks as items in Podio 54 | * 55 | * @param bookmarks 56 | * The bookmarks to save 57 | */ 58 | public void write(List bookmarks) { 59 | AppMapping mapping = getAppMapping(); 60 | ItemAPI itemAPI = new ItemAPI(podioAPI); 61 | 62 | for (Bookmark bookmark : bookmarks) { 63 | // Check that the bookmark has not already been added 64 | List items = itemAPI.getItemsByExternalId(appId, 65 | bookmark.getId()).getItems(); 66 | if (items.size() == 0) { 67 | // No items exists, so add the item 68 | itemAPI.addItem(appId, mapping.map(bookmark), true); 69 | } 70 | // TODO: Update the existing bookmark with new title, notes and tags 71 | } 72 | } 73 | 74 | /** 75 | * Maintans a mapping for the individual fields in the app 76 | */ 77 | private static final class AppMapping { 78 | 79 | private final int title; 80 | 81 | private final int url; 82 | 83 | private final int notes; 84 | 85 | private AppMapping(int title, int url, int notes) { 86 | super(); 87 | this.title = title; 88 | this.url = url; 89 | this.notes = notes; 90 | } 91 | 92 | /** 93 | * Returns the create object to be used when creating the object in 94 | * Podio 95 | * 96 | * @param bookmark 97 | * The bookmark to map 98 | * @return The mapped object 99 | */ 100 | public ItemCreate map(Bookmark bookmark) { 101 | List fields = new ArrayList(); 102 | fields.add(new FieldValuesUpdate(title, "value", bookmark 103 | .getTitle())); 104 | fields.add(new FieldValuesUpdate(url, "value", bookmark.getLink())); 105 | if (bookmark.getNotes() != null) { 106 | fields.add(new FieldValuesUpdate(notes, "value", bookmark 107 | .getNotes())); 108 | } 109 | 110 | return new ItemCreate(bookmark.getId(), fields, 111 | Collections. emptyList(), bookmark.getTags()); 112 | } 113 | 114 | /** 115 | * Creates a mapping configuration based on the app 116 | * 117 | * @param app 118 | * The app to create a mapping for 119 | * @return The mapping created 120 | */ 121 | public static AppMapping get(Application app) { 122 | List fields = app.getFields(); 123 | 124 | return new AppMapping(getField(fields, "Title"), getField(fields, 125 | "URL"), getField(fields, "Notes")); 126 | } 127 | 128 | /** 129 | * Finds a field in the list of fields with the given name 130 | * 131 | * @param fields 132 | * The fields to search through 133 | * @param label 134 | * The label to search for 135 | * @return The id of the matching field 136 | */ 137 | private static int getField(List fields, String label) { 138 | for (ApplicationField field : fields) { 139 | if (field.getConfiguration().getLabel().equals(label)) { 140 | return field.getId(); 141 | } 142 | } 143 | 144 | throw new IllegalArgumentException("No field found with the label " 145 | + label); 146 | } 147 | } 148 | } 149 | --------------------------------------------------------------------------------