jekyll-crosseverything-to-medium 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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cf717970cd9398b00938e7e185767d9dbd298e16
4
+ data.tar.gz: 4effb5a9330c68a0767d5291a5e7d7315565b953
5
+ SHA512:
6
+ metadata.gz: 90be13033347102b620c794599c94c803fca8a31ed90b5238a2ac60bf53deabfeffc1ff7428960e5ca4d444c48a71dca26f815e31338bade55e2889d29eb22aa
7
+ data.tar.gz: 7d5b3b57da2301df1a3b246a93cd72a96cb7e36cde7fca0c849e76b7e1ee31203af3ca4fdf30d65cdb204c94a4dfc7b2050bdd88c69146014ded04d73f815e51
@@ -0,0 +1,220 @@
1
+ # By Vincenzo Tilotta (tailot@gmail.com), based on the work of Jeremy Keith and Aaron Gustafson
2
+ # https://github.com/tailot/jekyll-crosserything-to-medium
3
+ # https://github.com/aarongustafson/jekyll-crosseverything_to_medium
4
+ # https://gist.github.com/adactio/c174a4a68498e30babfd
5
+ # Licence : MIT
6
+ #
7
+ # This generator cross-posts entries to Medium. To work, this script requires
8
+ # a MEDIUM_USER_ID environment variable and a MEDIUM_INTEGRATION_TOKEN.
9
+ #
10
+ # The generator will only pick up posts with the following front matter:
11
+ #
12
+ # `crosseverything_to_medium: true`
13
+ #
14
+ # You can control crosseverythinging globally by setting `enabled: true` under the
15
+ # `jekyll-crosseverything_to_medium` variable in your Jekyll configuration file.
16
+ # Setting it to false will skip the processing loop entirely which can be
17
+ # useful for local preview builds.
18
+
19
+ require 'json'
20
+ require 'net/http'
21
+ require 'net/https'
22
+ require 'kramdown'
23
+ require 'uri'
24
+ require 'date'
25
+
26
+ module Jekyll
27
+ class MediumCrosseverythingGenerator < Generator
28
+ safe true
29
+ priority :low
30
+
31
+ def generate(site)
32
+ @site = site
33
+
34
+ @settings = @site.config['jekyll-crosseverything_to_medium'] || {}
35
+
36
+ globally_enabled = if @settings.has_key?('enabled') then @settings['enabled'] else true end
37
+ cache_dir = @settings['cache'] || @site.config['source'] + '/.jekyll-crosseverything_to_medium'
38
+ backdate = if @settings.has_key? 'backdate' then @settings['backdate'] else true end
39
+ @crosseverything_file = File.join(cache_dir, "medium_crosseverything.yml")
40
+
41
+ if globally_enabled
42
+ # puts "Cross-posting enabled"
43
+ user_id = ENV['MEDIUM_USER_ID'] or false
44
+ token = ENV['MEDIUM_INTEGRATION_TOKEN'] or false
45
+ entity = ENV['MEDIUM_ENTITY'] or false
46
+
47
+ if ! user_id or ! token or ! entity
48
+ raise ArgumentError, "MediumCrosseverythingGenerator: Environment variables not found"
49
+ return
50
+ end
51
+
52
+ if defined?(cache_dir)
53
+ FileUtils.mkdir_p(cache_dir)
54
+
55
+ if File.exists?(@crosseverything_file)
56
+ crossposteverything = open(@crosseverything_file) { |f| YAML.load(f) }
57
+ # convert from an array to a hash (upgrading older versions of this plugin)
58
+ if crossposteverything.kind_of?(Array)
59
+ new_crosseverything = {}
60
+ crossposteverything.each do |url|
61
+ new_crosseverything[url] = 'unknown'
62
+ end
63
+ crossposteverything = new_crosseverything
64
+ end
65
+ # end upgrade
66
+ else
67
+ crossposteverything = {}
68
+ end
69
+
70
+ # If Jekyll 3.0, use hooks
71
+ if (Jekyll.const_defined? :Hooks)
72
+ Jekyll::Hooks.register entity.to_sym, :post_render do |post|
73
+ if ! post.published?
74
+ next
75
+ end
76
+
77
+ crosseverything = post.data.include? 'crosseverything_to_medium'
78
+ if ! crosseverything or ! post.data['crosseverything_to_medium']
79
+ next
80
+ end
81
+
82
+ content = post.content
83
+ url = "#{@site.config['url']}#{post.url}"
84
+ title = post.data['title']
85
+
86
+ published_at = backdate ? post.date : DateTime.now
87
+
88
+ crosseverything_payload(crossposteverything, post, content, title, url, published_at)
89
+ end
90
+ else
91
+
92
+ # post Jekyll commit 0c0aea3
93
+ # https://github.com/jekyll/jekyll/commit/0c0aea3ad7d2605325d420a23d21729c5cf7cf88
94
+ if defined? site.find_converter_instance
95
+ markdown_converter = @site.find_converter_instance(Jekyll::Converters::Markdown)
96
+ # Prior to Jekyll commit 0c0aea3
97
+ else
98
+ markdown_converter = @site.getConverterImpl(Jekyll::Converters::Markdown)
99
+ end
100
+
101
+ @site.site_payload['site'][entity].each do |post|
102
+
103
+ if ! post.published?
104
+ next
105
+ end
106
+
107
+ crosseverything = post.data.include? 'crosseverything_to_medium'
108
+ if ! crosseverything or ! post.data['crosseverything_to_medium']
109
+ next
110
+ end
111
+
112
+ # Convert the content
113
+ content = markdown_converter.convert(post.content)
114
+ # Render any plugins
115
+ content = (Liquid::Template.parse content).render @site.site_payload
116
+
117
+ url = "#{@site.config['url']}#{post.url}"
118
+ title = post.title
119
+
120
+ published_at = backdate ? post.date : DateTime.now
121
+
122
+ crosseverything_payload(crosseverything, post, content, title, url, published_at)
123
+
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+
131
+ def crosseverything_payload(crosseverything, post, content, title, url, published_at)
132
+ # Update any absolute URLs
133
+ # But don’t clobber protocol-less (i.e. "//") URLs
134
+ content = content.gsub /href=(["'])\/(?!\/)/, "href=\\1#{@site.config['url']}/"
135
+ content = content.gsub /src=(["'])\/(?!\/)/, "src=\\1#{@site.config['url']}/"
136
+ # puts content
137
+
138
+ # Save canonical URL
139
+ canonical_url = url
140
+
141
+ # Prepend the title and add a link back to originating site
142
+ content.prepend("<h1>#{title}</h1>")
143
+ # Append a canonical link and text
144
+ # TODO Accept a position option, e.g., top, bottom.
145
+ #
146
+ # User the user's config if it exists
147
+ if @settings['text']
148
+ canonical_text = "#{@settings['text']}"
149
+ canonical_text = canonical_text.gsub /{{ url }}/, canonical_url
150
+ # Otherwise, use boilerplate
151
+ else
152
+ canonical_text = "<p><i>This article was originally posted <a href=\"#{url}\" rel=\"canonical\">on my own site</a>.</i></p>"
153
+ end
154
+ content << canonical_text
155
+
156
+ # Strip domain name from the URL we check against
157
+ url = url.sub(/^#{@site.config['url']}?/,'')
158
+
159
+ # coerce tage to an array
160
+ tags = post.data['tags']
161
+ if tags.kind_of? String
162
+ tags = tags.split(',')
163
+ end
164
+
165
+ # Only cross-post if content has not already been cross-posted
166
+ if url and ! crosseverything.has_key? url
167
+ payload = {
168
+ 'title' => title,
169
+ 'contentFormat' => "html",
170
+ 'content' => content,
171
+ 'tags' => tags,
172
+ 'publishStatus' => @settings['status'] || "public",
173
+ 'publishedAt' => published_at.iso8601,
174
+ 'license' => @settings['license'] || "all-rights-reserved",
175
+ 'canonicalUrl' => canonical_url
176
+ }
177
+
178
+ if medium_url = crosseverything_to_medium(payload)
179
+ crosseverything[url] = medium_url
180
+ # Update cache
181
+ File.open(@crosseverything_file, 'w') { |f| YAML.dump(crosseverything, f) }
182
+ end
183
+ end
184
+ end
185
+
186
+
187
+ def crosseverything_to_medium(payload)
188
+ user_id = ENV['MEDIUM_USER_ID'] or false
189
+ token = ENV['MEDIUM_INTEGRATION_TOKEN'] or false
190
+ medium_api = URI.parse("https://api.medium.com/v1/users/#{user_id}/posts")
191
+
192
+ # Build the connection
193
+ https = Net::HTTP.new(medium_api.host, medium_api.port)
194
+ https.use_ssl = true
195
+ request = Net::HTTP::Post.new(medium_api.path)
196
+
197
+ # Set the headers
198
+ request['Authorization'] = "Bearer #{token}"
199
+ request['Content-Type'] = "application/json"
200
+ request['Accept'] = "application/json"
201
+ request['Accept-Charset'] = "utf-8"
202
+
203
+ # Set the payload
204
+ request.body = JSON.generate(payload)
205
+
206
+ # Post it
207
+ response = https.request(request)
208
+
209
+ if response.code == '201'
210
+ medium_response = JSON.parse(response.body)
211
+ puts "Posted '#{payload['title']}' to Medium as #{payload['publishStatus']} (#{medium_response['data']['url']})"
212
+ return medium_response['data']['url']
213
+ else
214
+ puts "Attempted to post '#{payload['title']}' to Medium. They responded #{response.body}"
215
+ return false
216
+ end
217
+ end
218
+
219
+ end
220
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-crosseverything-to-medium
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vincenzo Tilotta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: " This generator cross-everything entries to Medium. To work, this script
14
+ requires\n a MEDIUM_USER_ID environment variable and a MEDIUM_INTEGRATION_TOKEN,
15
+ MEDIUM_ENTITY.\n\n The generator will only pick up posts with the following front
16
+ matter:\n\n `crosseverything_to_medium: true`\n\n You can control crosseverything
17
+ globally by setting `enabled: true` under the \n `jekyll-crosserything_to_medium`
18
+ variable in your Jekyll configuration file.\n Setting it to false will skip the
19
+ processing loop entirely which can be\n useful for local preview builds.\n"
20
+ email: tailot@gmail.com
21
+ executables: []
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - lib/jekyll-crosseverything-to-medium.rb
26
+ homepage: http://rubygems.org/gems/jekyll-crosseverything-to-medium
27
+ licenses:
28
+ - MIT
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 2.5.1
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Crosseverything to Medium Generator for Jekyll
50
+ test_files: []