package ti;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern;
import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document;
import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.collect.Collections2; import com.google.common.collect.Lists;
public class InstagramReplicator { public static InstagramReplicator newInstance(String instagramUser, String tumblrUser, String tagName) throws IOException { return new InstagramReplicator(instagramUser, tumblrUser, tagName); } public void doUpdate() throws IOException { System.out.println(βChecking for updates: instagramUser=β + instagramUser); Β Β for(String instagramUrl : loadInstagramUrls()) { Β Β if(!currentImages.contains(instagramUrl)) Β Β { Β Β Β Β submitPostToTumblr Β Β Β Β Β Β Β Β ( Β Β Β Β Β Β Β Β Β Β loadInstagramPost(instagramUrl) Β Β Β Β Β Β Β Β ); Β Β Β Β Β Β Β Β currentImages.add(instagramUrl); Β Β Β Β Β Β Β Β if(currentImages.size() > 100) Β Β Β Β { Β Β Β Β Β Β currentImages.remove(currentImages.get(0)); Β Β Β Β } Β Β } } } private List<String> loadInstagramUrls() throws IOException { Β Β List<String> instagramUrls = findMatches Β Β Β Β ( Β Β Β Β Β Β Jsoup.connect(βhttp://instagram.com/β + instagramUser).get().outerHtml(), Β Β Β Β Β Β ""link":"(http:\\/\\/instagram\.com\\/p\\/[^\\]*\\/)"β, Β Β Β Β Β Β true Β Β Β Β ); Β Β Β Β Collections.reverse(instagramUrls); Β Β Β Β //System.out.println(instagramUser + β - β + instagramUrls); Β Β Β Β return instagramUrls; } private Post loadInstagramPost(String postUrl) throws IOException { System.out.println("Loading post: postUrl=β + postUrl); Β Β String docText = Jsoup.connect(postUrl).get().outerHtml(); //System.out.println(βdoctext=β + docText); String caption = β<p>β + findMatch(docText, β"caption":"(.*?[^\\])"β, false) + β</p>β; String tagRegEx = β#([A-Za-z0-9_]+)β; String userRegEx = β@([A-Za-z0-9_]+)β; List<String> tags = Lists.newArrayList(); tags.addAll(findMatches(caption, tagRegEx, false)); tags.addAll(findMatches(caption, userRegEx, false)); //caption = caption.replaceAll(tagRegEx, β<a href=\\"http://www.gramfeed.com/instagram/tags#$1\\">$0</a>β); caption = caption.replaceAll(userRegEx, β<a href=\\"http://instagram.com/$1\\">$0</a>β); if(docText.contains(β"is_video":trueβ)) { Β Β caption += β<p><a href=\"β + postUrl + β\">Watch Video</a></p>β; } return new Post Β Β Β Β ( Β Β Β Β Β Β postUrl, Β Β Β Β Β Β findMatch(docText, β"display_src":"([^"]*)"β, true), //imageUrl Β Β Β Β Β Β caption, Β Β Β Β Β Β Joiner.on(β,β).join(tags) Β Β Β Β ); } private void submitPostToTumblr(Post post) throws IOException { System.out.println(βSubmitting post: post=β + post); try Β Β Β Β { Β Β Β Β Β Β HttpURLConnection connection = (HttpURLConnection) new URL(βhttp://www.tumblr.com/svc/post/updateβ).openConnection();
Β Β Β Β Β Β connection.setDoOutput(true); Β Β Β Β Β Β connection.setDoInput(true); Β Β Β Β Β Β connection.setInstanceFollowRedirects(false); Β Β Β Β Β Β connection.setRequestMethod(βPOSTβ); Β Β Β Β Β Β connection.setRequestProperty(βCookieβ, tumblrCookie); Β Β Β Β Β Β connection.setRequestProperty(βX-tumblr-puppiesβ, getSecureFormKey()); Β Β Β Β Β Β connection.setRequestProperty(βX-tumblr-form-keyβ,βOdhVH6QQTBzl9IZZDViXwyj5vOUβ); Β Β Β Β Β Β connection.setRequestProperty(βOriginβ,βhttp://www.tumblr.comβ); Β Β Β Β Β Β connection.setRequestProperty(βAccept-Encodingβ,βgzip,deflate,sdchβ); Β Β Β Β Β Β connection.setRequestProperty(βHostβ,βwww.tumblr.comβ); Β Β Β Β Β Β connection.setRequestProperty(βAccept-Languageβ,βen-US,en;q=0.8β); Β Β Β Β Β Β connection.setRequestProperty(βUser-Agentβ,βMozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36β); Β Β Β Β Β Β connection.setRequestProperty(βContent-Typeβ,βapplication/jsonβ); Β Β Β Β Β Β connection.setRequestProperty(βAcceptβ,βapplication/json, text/javascript, */*; q=0.01β); Β Β Β Β Β Β connection.setRequestProperty(βRefererβ,βhttp://www.tumblr.com/new/photoβ); Β Β Β Β Β Β connection.setRequestProperty(βX-Requested-Withβ,βXMLHttpRequestβ); Β Β Β Β Β Β connection.setRequestProperty(βConnectionβ,βkeep-aliveβ); Β Β Β Β Β Β connection.setRequestProperty(βDNTβ,β1β); Β Β Β Β Β Β connection.setUseCaches(false);
Β Β Β Β Β Β OutputStream output = connection.getOutputStream(); Β Β Β Β Β Β Β Β Β Β Β Β output.write Β Β Β Β Β Β ( Β Β Β Β Β Β Β Β (β{"form_key":"OdhVH6QQTBzl9IZZDViXwyj5vOU","context_id":"","context_page":"dashboard",β Β Β Β Β Β Β Β Β + β"editor_type":"rich","is_rich_text[one]":"0","is_rich_text[two]":"1","is_rich_text[three]":"0",β Β Β Β Β Β Β Β Β + β"channel_id":"β + tumblrUser + Β Β Β Β Β Β Β Β "","post[slug]":"",β Β Β Β Β Β Β Β Β + β"post[source_url]":"β + post.postUrl + Β Β Β Β Β Β Β Β β","post[date]":"","post[three]":"β + post.postUrl + Β Β Β Β Β Β Β Β β","MAX_FILE_SIZE":"10485760","post[type]":"photo",β Β Β Β Β Β Β Β Β + β"post[two]":"β + post.caption + Β Β Β Β Β Β Β Β β","post[tags]":"β + Joiner.on(β,β).join(userTags, post.tags, instagramUser, "instagramβ).replace(β_β, β β) + Β Β Β Β Β Β Β Β "","post[publish_on]":"","post[state]":"0 3","post[photoset_layout]":"1","post[photoset_order]":"o1",β Β Β Β Β Β Β Β Β + β"images[o1]":"β + post.imageUrl + β","photo_src[]":"β + post.imageUrl + Β Β Β Β Β Β Β Β β"}β).getBytes(Charset.forName("UTF-8β)) Β Β Β Β Β Β ); Β Β Β Β Β Β output.close();
Β Β Β Β Β Β InputStream input = connection.getInputStream(); Β Β Β Β Β Β while(input.read() != -1) {}
Β Β Β Β Β Β System.out.println(βPost submission complete, httpStatusCode=β + connection.getResponseCode());
Β Β Β Β Β Β input.close(); Β Β Β Β } catch (IOException e) Β Β Β Β { Β Β if(consecutiveTumblrErrors++ > 10) Β Β { Β Β Β Β System.err.println(βFATAL: Too many consecutive tumblr failures, shutting downβ); Β Β Β Β System.exit(1); Β Β } Β Β Β Β throw e; Β Β Β Β } consecutiveTumblrErrors = 0; } private String getSecureFormKey() throws IOException { Β Β Β Β Connection connection = Jsoup.connect(βhttp://www.tumblr.com/svc/secure_form_keyβ) Β Β Β Β Β Β Β Β .header(βCookieβ, tumblrCookie) Β Β Β Β Β Β Β Β .header(βX-tumblr-form-keyβ,βOdhVH6QQTBzl9IZZDViXwyj5vOUβ) Β Β Β Β Β Β Β Β .header(βOriginβ,βhttp://www.tumblr.comβ) Β Β Β Β Β Β Β Β .header(βAccept-Encodingβ,βgzip,deflate,sdchβ) Β Β Β Β Β Β Β Β .header(βHostβ,βwww.tumblr.comβ) Β Β Β Β Β Β Β Β .header(βAccept-Languageβ,βen-US,en;q=0.8β) Β Β Β Β Β Β Β Β .header(βUser-Agentβ,βMozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36β) Β Β Β Β Β Β Β Β .header(βContent-Typeβ,βapplication/jsonβ) Β Β Β Β Β Β Β Β .header(βAcceptβ,βapplication/json, text/javascript, */*; q=0.01β) Β Β Β Β Β Β Β Β .header(βRefererβ,βhttp://www.tumblr.com/new/photoβ) Β Β Β Β Β Β Β Β .header(βX-Requested-Withβ,βXMLHttpRequestβ) Β Β Β Β Β Β Β Β .header(βConnectionβ,βkeep-aliveβ) Β Β Β Β Β Β Β Β .header(βDNTβ,β1β) Β Β Β Β Β Β Β Β .header(βContent-Lengthβ, β0β); Β Β Β Β connection.post(); Β Β Β Β String secureFormKey = connection.response().header(βX-tumblr-secure-form-keyβ); Β Β Β Β System.out.println(βsecureFormKey=β + secureFormKey);
Β Β Β Β return secureFormKey; }
private String findMatch(String string, String regex, boolean isUrl) { Β Β List<String> matches = findMatches(string, regex, isUrl); Β Β Β Β if(matches.isEmpty()) Β Β { Β Β Β Β return ββ; Β Β } Β Β Β Β return matches.get(0); } private List<String> findMatches(String string, String regex, boolean isUrl) { Β Β Β Matcher matcher = Pattern Β Β Β Β Β Β Β .compile(regex) Β Β Β Β Β Β Β .matcher(string);
Β Β Β Β Β List<String> matches = Lists.newArrayList();
Β Β Β Β Β while(matcher.find()) Β Β Β Β Β { Β Β Β Β Β Β Β matches.add Β Β Β Β Β Β Β ( Β Β Β Β Β Β Β Β Β matcher Β Β Β Β Β Β Β Β Β Β Β .group(1) Β Β Β Β Β Β Β Β Β Β Β .replace Β Β Β Β Β Β Β Β Β Β Β ( Β Β Β Β Β Β Β Β Β Β Β Β Β (isUrl ? β\β : ββ), Β Β Β Β Β Β Β Β Β Β Β Β Β ββ Β Β Β Β Β Β Β Β Β Β Β ) Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β ); Β Β Β Β Β }
Β Β Β Β Β return matches; } //nested classes private class Post { Β Β Β Β public Post(String postUrl, String imageUrl, String caption, String tags) { this.postUrl = postUrl; this.imageUrl = imageUrl; this.caption = caption; this.tags = tags; } @Override Β Β Β Β public String toString() { Β Β Β Β Β Β return βPost [postUrl=β + postUrl + β, imageUrl=β + imageUrl Β Β Β Β Β Β Β Β Β Β + β, caption=β + caption + β, tags=β + tags + β]β; Β Β Β Β }
Β Β Β Β private final String postUrl; private final String imageUrl; private final String caption; private final String tags; } Β //constructors
Β Β private InstagramReplicator(String instagramUser, String tumblrUser, String tagName) throws IOException Β Β { Β Β Β Β this.instagramUser = instagramUser; Β Β Β Β this.tumblrUser = tumblrUser; Β Β Β Β this.userTags = tagName; Β Β Β Β currentImages = loadInstagramUrls();
Β Β Β /* currentImages.removeAll Β Β Β Β ( Β Β Β Β Β Β Splitter Β Β Β Β Β Β Β Β .on(β,β) Β Β Β Β Β Β Β Β .trimResults() Β Β Β Β Β Β Β Β .omitEmptyStrings() Β Β Β Β Β Β Β Β .splitToList Β Β Β Β Β Β Β Β ( Β Β Β Β Β Β Β Β ) Β Β Β Β );*/
Β Β }
Β Β //attributes
Β Β private final String instagramUser; Β Β private final String tumblrUser; Β Β private final String userTags; Β Β private final List<String> currentImages;
Β Β //static
Β Β public static void main(String[] args) throws IOException Β Β { Β Β Β Β Executors.newScheduledThreadPool(0).scheduleWithFixedDelay Β Β Β Β ( Β Β Β Β Β Β new Runnable() Β Β Β Β Β Β { Β Β Β Β Β Β Β Β List<InstagramReplicator> replicators = Lists.newArrayList Β Β Β Β Β Β Β Β ( Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βwillaaaahhβ, βwillaaaahhhβ, βwilla hollandβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βemmarobertsβ, βemmaroberts9β, βemma robertsβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βtfarm7β, βtfarm11β, βtaissa farmigaβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βtaylorswiftβ, βtaylorswift26β, βtaylor swift,taylorswift13β), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βyelyahwilliamsβ, βyelyahwilliams-instagramβ, βhayley williamsβ),
Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βMileyCyrusβ, βmileycyrus-instagramβ, βmiley cyrusβ), Β Β Β Β Β Β Β Β Β Β //InstagramReplicator.newInstance(βbadgalririβ, βbadgalriri-instagramβ, βrihannaβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βbeyonceβ, βbeyonce-instagramβ, βbeyonce knowlesβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βcaradelevingneβ, βcaradelevingne-instagramβ, βcara delevingneβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βnickiminajβ, βnickiminaj-instagramβ, βnicki minajβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βemmyrossumβ, βemmyrossum-instagramβ, βemmy rossumβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βtigersjawβ, βtigersjaw-instagramβ, βtigers jaw,brianna collinsβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βtayjardineβ, βtayjardine-instagramβ, βtay jardine,taylor jardine,we are the in crowdβ), Β Β Β Β Β Β Β Β Β Β InstagramReplicator.newInstance(βlordemusicβ, βlordemusic-instagramβ, βlordeβ) Β Β Β Β Β Β Β Β );
Β Β Β Β Β Β Β Β Iterator<InstagramReplicator> replicatorIterator = replicators.iterator();
Β Β Β Β Β Β Β Β @Override Β Β Β Β Β Β Β Β public void run() Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β if(!replicatorIterator.hasNext()) Β Β Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β replicatorIterator = replicators.iterator(); Β Β Β Β Β Β Β Β Β Β }
Β Β Β Β Β Β Β Β Β Β InstagramReplicator replicator = replicatorIterator.next();
Β Β Β Β Β Β Β Β Β Β try Β Β Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β replicator.doUpdate(); Β Β Β Β Β Β Β Β Β Β } Β Β Β Β Β Β Β Β Β Β catch (Throwable e) Β Β Β Β Β Β Β Β Β Β { Β Β Β Β Β Β Β Β Β Β Β Β e.printStackTrace(); Β Β Β Β Β Β Β Β Β Β } Β Β Β Β Β Β Β Β } Β Β Β Β Β Β }, Β Β Β Β Β Β 0, Β Β Β Β Β Β 5, Β Β Β Β Β Β TimeUnit.SECONDS Β Β Β Β ); Β Β } private static int consecutiveTumblrErrors = 0; private static final String tumblrCookie = ββ; }

















