tumblr_to_dayone 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjJlZGVjYjVjMTFjOGQ0NWVjN2M1ZTUwN2M2ZGIyNzA0NGM2Y2FmYw==
5
+ data.tar.gz: !binary |-
6
+ YjdhYWIzYzg5YjIzYmJmMjQ4OGQ5ZWM2ZmQxNzJiY2RkZjNmZTc2Zg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NzE2MWYwMjdjOTI1NzM2OWYxNDZiZDVhNTlmYjA1OWIzNmQ5OTliZDliNmM2
10
+ MjE3ZGQzZGUzMjk2MjUzMDBmOTFkMmE2N2UzZGNmNDlmOWUzNjExOGFhMWVk
11
+ NDRkYTk5NmUyZjFhYmFkY2Y5OTZiZWIwZDhhOGEyNjRiY2FiZTY=
12
+ data.tar.gz: !binary |-
13
+ YjI2MzkzZWUxZjE5Yjk2YWE0NTMyYjEzOWViMjQ1ZWQxNjY5ODdkODc3OTQ1
14
+ MzNmNzg0ZWFkMzAwMzA2YzAyNjc4YWEzYjE2MDZmYjJiZDA0YjcyODEwNzEy
15
+ MzNlMzA1NWZhNDczNjk3MWU3MTRiZTUzMjE0M2QwOTYzMjI2NDM=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tumblr_to_dayone.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Joey Meyer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Tumblr to Day One
2
+
3
+ A simple command prompt that easily allows you to add posts from a [Tumblr](http://tumblr.com) blog to your [Day One](http://dayoneapp.com) journal.
4
+
5
+ ## Usage
6
+
7
+ Get started by installing the gem:
8
+
9
+ $ gem install tumblr_to_dayone
10
+
11
+ You will also need to install the [Day One CLI](http://dayoneapp.com/tools/).
12
+
13
+ After that you are ready to go:
14
+
15
+ $ tumblr_to_dayone
16
+
17
+ This command starts a prompt and asks a few questions to get things setup:
18
+
19
+ * Name of the blog
20
+ * Password (if there is one)
21
+ * Automatically add all posts – or choose which ones to add one by one
22
+ * Path to your Day One journal (leave blank if it's the default path)
23
+
24
+ After that it is ready to go and will start pulling down your Tumblr posts to either add one by one or all at once.
25
+
26
+ ## Creator
27
+
28
+ [Joey Meyer](http://joeymeyer.com)
29
+
30
+ ## License
31
+
32
+ tumblr_to_dayone is available under the MIT license. See the LICENSE file for more info.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ gem 'tumblr_to_dayone'
4
+
5
+ require 'tumblr_to_dayone/prompt'
6
+
7
+ TumblrToDayone::Prompt.start
@@ -0,0 +1,32 @@
1
+ require 'shellwords'
2
+
3
+ module Dayone
4
+
5
+ def self.cli_installed?
6
+ `which dayone`.length > 0
7
+ end
8
+
9
+ # options:
10
+ #
11
+ # date - Creation date of the entry
12
+ # starred - Whether or not to star the entry
13
+ # photo_path - File path to a photo to attach to entry
14
+ # journal_path - Location of Day One Journal file
15
+ #
16
+
17
+ def self.create_post(post, options = {})
18
+ return false unless Dayone.cli_installed? && post
19
+
20
+ arguments = {
21
+ :d => options[:date],
22
+ :s => options[:starred],
23
+ :p => options[:photo_path],
24
+ :j => options[:journal_path]
25
+ }.map { |k,v| "-#{k}=\"#{v}\"" unless !v }.compact.join(" ")
26
+
27
+ output = `echo #{Shellwords.escape(post)} | dayone #{arguments} new`
28
+
29
+ output.start_with?("New entry")
30
+ end
31
+
32
+ end
@@ -0,0 +1,37 @@
1
+ require 'tumblr_to_dayone'
2
+
3
+ module TumblrToDayone
4
+ module Prompt
5
+
6
+ def self.start
7
+ if Dayone.cli_installed?
8
+ puts "What is the name of your tumblr blog? (<name>.tumblr.com)"
9
+ blog_name = gets.chomp
10
+
11
+ puts "What is the password of your tumblr blog? (leave blank if none)"
12
+ password_input = gets.chomp
13
+ blog_password = password_input unless password_input.empty?
14
+
15
+ puts "Automatically add all blog posts? (y/n)"
16
+ automatic = gets.chomp == 'y'
17
+
18
+ puts "What is the location of your Dayone.journal? (leave blank if it is in the default location)"
19
+ journal_path_input = gets.chomp
20
+ journal_path = journal_path_input unless journal_path_input.empty?
21
+
22
+ TumblrToDayone.add_tumblr_posts_to_dayone(blog_name, :password => blog_password, :automatically_add_each_post => automatic, :journal_path => journal_path) do |post|
23
+ puts "- " * 30
24
+ puts post
25
+ puts "- " * 30
26
+ puts "Would you like to add this post to Day One? (y: yes, s: yes and star it, n: no, exit: exit the prompt)"
27
+ gets.chomp.downcase.to_sym
28
+ end
29
+
30
+ puts "Done."
31
+ else
32
+ puts "Download and install Day One CLI to continue. (http://dayoneapp.com/tools/)"
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ require 'cgi'
2
+ require 'reverse_markdown'
3
+
4
+ module Tumblr
5
+ class Post
6
+ attr_accessor :type, :created_at, :title, :body, :photo_url, :video_player, :caption, :tags
7
+
8
+ def initialize(post_hash)
9
+ self.type = post_hash["type"]
10
+ self.created_at = Time.at(post_hash["unix-timestamp"] || Time.now.to_i)
11
+ self.title = post_hash["regular-title"]
12
+ self.body = convert_to_markdown(post_hash["regular-body"]) || link_markdown(post_hash["link-text"], post_hash["link-url"])
13
+ self.photo_url = largest_photo_url(post_hash)
14
+ self.video_player = post_hash["video-player"]
15
+ self.caption = convert_to_markdown(post_hash["photo-caption"] || post_hash["video-caption"])
16
+ self.tags = post_hash["tags"] || []
17
+ end
18
+
19
+ def full_body
20
+ [
21
+ self.title ? "# #{self.title}" : nil,
22
+ self.video_player ? video_player : nil,
23
+ self.body ? self.body : nil,
24
+ self.caption ? self.caption : nil,
25
+ self.tags && !self.tags.empty? ? self.tags.map {|tag| "\\##{tag}"}.join(" ") : nil
26
+ ].compact.join("\n\n")
27
+ end
28
+
29
+ def to_s
30
+ "Tumblr post created on #{self.created_at}\ntitle: #{self.title ? self.title : "<no title>"}\nphoto: #{!!self.photo_url}\nbody:\n#{self.full_body}\n"
31
+ end
32
+
33
+ private
34
+
35
+ PHOTO_URL_KEY_PREFIX = "photo-url-"
36
+
37
+ def largest_photo_url(post_hash)
38
+ largest_width = post_hash.keys.map{ |key| key.match(PHOTO_URL_KEY_PREFIX) ? key.gsub(PHOTO_URL_KEY_PREFIX, "").to_i : nil }.compact.max
39
+
40
+ largest_width ? post_hash["#{PHOTO_URL_KEY_PREFIX}#{largest_width}"] : nil
41
+ end
42
+
43
+ def convert_to_markdown(content)
44
+ return nil unless content
45
+
46
+ ReverseMarkdown.parse(CGI.unescapeHTML(content))
47
+ end
48
+
49
+ def link_markdown(link_text, link_url)
50
+ return nil unless link_text && link_url
51
+
52
+ "[#{link_text}](#{link_url})"
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,52 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'tumblr_to_dayone/tumblr/post'
4
+
5
+ module Tumblr
6
+
7
+ # options:
8
+ #
9
+ # start - The post offset to start from. The default is 0.
10
+ # num - The number of posts to return. The default is 20, and the maximum is 50.
11
+ # type - The type of posts to return. If unspecified or empty, all types of posts are returned. Must be one of text, quote, photo, link, chat, video, or audio.
12
+ # id - A specific post ID to return. Use instead of start, num, or type.
13
+ # filter - Alternate filter to run on the text content. Allowed values:
14
+ # text: Plain text only. No HTML.
15
+ # none: No post-processing. Output exactly what the author entered. (Note: Some authors write in Markdown, which will not be converted to HTML when this option is used.)
16
+ # tagged - Return posts with this tag in reverse-chronological order (newest first). Optionally specify chrono=1 to sort in chronological order (oldest first).
17
+ # search - Search for posts with this query.
18
+ #
19
+
20
+ def self.posts(title, password = nil, options = {})
21
+ uri = URI.parse("http://#{title}.tumblr.com/api/read/json")
22
+ uri.query = URI.encode_www_form(options)
23
+
24
+ request = Net::HTTP::Get.new(uri.request_uri)
25
+ request.basic_auth title, password if password
26
+
27
+ http = Net::HTTP.new(uri.host, uri.port)
28
+ response = http.request(request)
29
+
30
+ if response.is_a?(Net::HTTPSuccess)
31
+ body = JSON.parse(response.body[22..-3])
32
+
33
+ total_posts = body["posts-total"].to_i
34
+ post_hashes = body["posts"]
35
+
36
+ posts = post_hashes.map { |post_hash| Tumblr::Post.new(post_hash) }
37
+
38
+ if block_given?
39
+ yield posts, total_posts
40
+ else
41
+ posts
42
+ end
43
+ else
44
+ raise TumblrPostsAPIError, "Failed to get posts, server returned #{response.code} #{response.message}"
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ class TumblrPostsAPIError < StandardError
51
+
52
+ end
@@ -0,0 +1,3 @@
1
+ module TumblrToDayone
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,86 @@
1
+ require "tumblr_to_dayone/version"
2
+ require 'tumblr_to_dayone/tumblr'
3
+ require 'tumblr_to_dayone/dayone'
4
+
5
+ module TumblrToDayone
6
+
7
+ # options:
8
+ #
9
+ # password - Password for blog (if there is one)
10
+ # filter - Only get Tumblr posts based on type (text, quote, photo, link, chat, video, or audio)
11
+ # automatically_add_each_post - Automatically add each Tumblr post or ask before adding each one (defaults to false)
12
+ # journal_path - Location of Day One Journal file
13
+ #
14
+
15
+ def self.add_tumblr_posts_to_dayone(blog, options={})
16
+ begin
17
+ post_index = 0
18
+ no_more_posts = false
19
+
20
+ while !no_more_posts
21
+ Tumblr.posts(blog, password = options[:password], :start => post_index, :type => options[:filter]) do |posts, total_posts|
22
+ post_index += posts.count
23
+ no_more_posts = posts.empty? || post_index >= total_posts
24
+
25
+ exited = false
26
+
27
+ posts.each do |post|
28
+ unless exited
29
+ post_status = options[:automatically_add_each_post] ? :y : yield(post)
30
+
31
+ if post_status == :y || post_status == :s
32
+ post_created = post.add_to_dayone!(starred = post_status == :s, dayone_journal = options[:journal_path])
33
+
34
+ puts "ERROR: There was a problem adding the post." unless post_created
35
+ elsif post_status == :exit
36
+ exited = true
37
+ no_more_posts = true
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ rescue TumblrPostsAPIError => e
44
+ puts e.message
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ module Tumblr
51
+ class Post
52
+
53
+ def add_to_dayone!(starred = false, dayone_journal = nil)
54
+
55
+ post_created = false
56
+
57
+ photo = nil
58
+
59
+ begin
60
+
61
+ if self.photo_url
62
+ photo = Tempfile.new(["#{self.photo_url.hash}", File.extname(self.photo_url)])
63
+ photo.open
64
+ photo.write open(self.photo_url).read
65
+ photo.close
66
+ end
67
+
68
+ post_created = Dayone.create_post(self.full_body,
69
+ :date => self.created_at,
70
+ :starred => starred,
71
+ :photo_path => photo ? photo.path : nil,
72
+ :journal_path => dayone_journal
73
+ )
74
+
75
+ ensure
76
+ if photo
77
+ photo.close
78
+ photo.unlink
79
+ end
80
+ end
81
+
82
+ post_created
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tumblr_to_dayone/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tumblr_to_dayone"
8
+ spec.version = TumblrToDayone::VERSION
9
+ spec.authors = ["Joey Meyer"]
10
+ spec.email = ["jmeyer41@gmail.com"]
11
+ spec.description = "Command prompt which makes it easy to add Tumblr posts to your Day One journal."
12
+ spec.summary = "A simple command prompt that easily allows you to add posts from a Tumblr blog to your Day One journal."
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency "reverse_markdown", "~> 0.4"
25
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tumblr_to_dayone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joey Meyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: reverse_markdown
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ description: Command prompt which makes it easy to add Tumblr posts to your Day One
56
+ journal.
57
+ email:
58
+ - jmeyer41@gmail.com
59
+ executables:
60
+ - tumblr_to_dayone
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - .gitignore
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - bin/tumblr_to_dayone
70
+ - lib/tumblr_to_dayone.rb
71
+ - lib/tumblr_to_dayone/dayone.rb
72
+ - lib/tumblr_to_dayone/prompt.rb
73
+ - lib/tumblr_to_dayone/tumblr.rb
74
+ - lib/tumblr_to_dayone/tumblr/post.rb
75
+ - lib/tumblr_to_dayone/version.rb
76
+ - tumblr_to_dayone.gemspec
77
+ homepage: ''
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.5
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: A simple command prompt that easily allows you to add posts from a Tumblr
101
+ blog to your Day One journal.
102
+ test_files: []