ZMediumToMarkdown 2.4.0 → 2.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c57f5610ede891d1c9677db7c4c3c0345bb5d309f5825538524d238db5b991c4
4
- data.tar.gz: d06da63e8bb12bb776959d93d9dddff1f407a9654cec1883916b94c7ddd6b2d9
3
+ metadata.gz: b853d78f150d3134ac412b310a53a864fa4808a7c6dd476c28f534ecc607de18
4
+ data.tar.gz: 886dcd5efb04f28a033eb6ca80ed2babaa2f37c9afc4d524a776b3f154d96f35
5
5
  SHA512:
6
- metadata.gz: 2437e85b4184dfe4e72e8923af91a7ae4f849e973f618c4a66d8ff7edd3fc09122f32cc11152f8a947fc74d0fbec1f751eff57d94e036ef3b19060252c08d088
7
- data.tar.gz: d374e8169f365f4934b2911a96028680dc2ab0f57edd3a3a07469876ec131d0429679b45f9ba52202544c048792551d2f9bca47478a4c79fbed102f75a11ee00
6
+ metadata.gz: 7492890c6dbacf64ea895246224692d73925359489fd97383c6331eb613201dc64963631a72eaa2ae708470ebf912199057f800428ca847284300da1bb091b46
7
+ data.tar.gz: 869962271b377b7e258bf013d7136befba33bb8a72272f5aee15e10af209e1be276028c344bfb2335d094f28bffaabff723c6fd8f600a6a5051e7baa0b5a9bf0
@@ -16,14 +16,14 @@ class Main
16
16
  fetcher = ZMediumFetcher.new
17
17
  ARGV << '-h' if ARGV.empty?
18
18
 
19
+ options = {}
19
20
  filePath = ENV['PWD'] || ::Dir.pwd
20
-
21
+
21
22
  OptionParser.new do |opts|
22
23
  opts.banner = "Usage: ZMediumFetcher [options]"
23
-
24
+
24
25
  opts.on('-s', '--cookie_sid COOKIESID', 'Your logged-in Medium cookie sid value') do |cookie_sid|
25
26
  $cookie_sid = cookie_sid
26
- puts $cookie_sid
27
27
  end
28
28
 
29
29
  opts.on('-d', '--cookie_uid COOKIEUID', 'Your logged-in Medium cookie uid value') do |cookie_uid|
@@ -31,58 +31,83 @@ class Main
31
31
  end
32
32
 
33
33
  opts.on('-u', '--username USERNAME', 'Downloading all posts from user') do |username|
34
- outputFilePath = PathPolicy.new("#{filePath}/Output", "Output")
35
- fetcher.downloadPostsByUsername(username, outputFilePath)
36
-
37
- Helper.printNewVersionMessageIfExists()
34
+ options[:u] = username
38
35
  end
39
36
 
40
37
  opts.on('-p', '--postURL POST_URL', 'Downloading single post') do |postURL|
41
- outputFilePath = PathPolicy.new("#{filePath}/Output", "Output")
42
- fetcher.downloadPost(postURL, outputFilePath, nil)
43
-
44
- Helper.printNewVersionMessageIfExists()
38
+ options[:p] = postURL
45
39
  end
46
40
 
47
41
  opts.on('-j', '--jekyllUsername USERNAME', 'Downloading all posts from user with Jekyll friendly') do |username|
48
- outputFilePath = PathPolicy.new(filePath, "")
49
- fetcher.isForJekyll = true
50
- fetcher.downloadPostsByUsername(username, outputFilePath)
51
-
52
- Helper.printNewVersionMessageIfExists()
42
+ options[:j] = username
53
43
  end
54
44
 
55
45
  opts.on('-k', '--jekyllPostURL POST_URL', 'Downloading single post with Jekyll friendly') do |postURL|
56
- outputFilePath = PathPolicy.new(filePath, "")
57
- fetcher.isForJekyll = true
58
- fetcher.downloadPost(postURL, outputFilePath, nil)
59
-
60
- Helper.printNewVersionMessageIfExists()
46
+ options[:k] = postURL
61
47
  end
62
48
 
63
49
  opts.on('-n', '--new', 'Update to latest version') do
64
- if Helper.getRemoteVersionFromGithub() > Helper.getLocalVersion()
65
- Helper.downloadLatestVersion()
66
- else
67
- puts "You're using the latest version :)"
68
- end
50
+ options[:n] = true
69
51
  end
70
52
 
71
53
  opts.on('-c', '--clean', 'Remove all downloaded posts data') do
72
- outputFilePath = PathPolicy.new(filePath, "")
73
- FileUtils.rm_rf(Dir[outputFilePath.getAbsolutePath(nil)])
74
- puts "All downloaded posts data has been removed."
75
-
76
- Helper.printNewVersionMessageIfExists()
54
+ options[:c] = true
77
55
  end
78
56
 
79
57
  opts.on('-v', '--version', 'Print current ZMediumToMarkdown Version & Output Path') do
80
- puts "Version:#{Helper.getLocalVersion().to_s}"
81
-
82
- Helper.printNewVersionMessageIfExists()
58
+ options[:v] = true
83
59
  end
84
-
85
60
  end.parse!
61
+
62
+ #
63
+ if !options[:v].nil? && options[:v] == true
64
+ puts "Version:#{Helper.getLocalVersion().to_s}"
65
+
66
+ Helper.printNewVersionMessageIfExists()
67
+ elsif !options[:c].nil? && options[:c] == true
68
+ outputFilePath = PathPolicy.new(filePath, "")
69
+ FileUtils.rm_rf(Dir[outputFilePath.getAbsolutePath(nil)])
70
+ puts "All downloaded posts data has been removed."
71
+
72
+ Helper.printNewVersionMessageIfExists()
73
+ elsif !options[:n].nil? && options[:n] == true
74
+ if Helper.getRemoteVersionFromGithub() > Helper.getLocalVersion()
75
+ Helper.downloadLatestVersion()
76
+ else
77
+ puts "You're using the latest version :)"
78
+ end
79
+ elsif !options[:k].nil?
80
+ postURL = options[:k]
81
+
82
+ outputFilePath = PathPolicy.new(filePath, "")
83
+ fetcher.isForJekyll = true
84
+ fetcher.downloadPost(postURL, outputFilePath, nil)
85
+
86
+ Helper.printNewVersionMessageIfExists()
87
+ elsif !options[:j].nil?
88
+ username = options[:j]
89
+
90
+ outputFilePath = PathPolicy.new(filePath, "")
91
+ fetcher.isForJekyll = true
92
+ fetcher.downloadPostsByUsername(username, outputFilePath)
93
+
94
+ Helper.printNewVersionMessageIfExists()
95
+ elsif !options[:p].nil?
96
+ postURL = options[:p]
97
+
98
+ outputFilePath = PathPolicy.new("#{filePath}/Output", "Output")
99
+ fetcher.downloadPost(postURL, outputFilePath, nil)
100
+
101
+ Helper.printNewVersionMessageIfExists()
102
+ elsif !options[:u].nil?
103
+ username = options[:u]
104
+
105
+ outputFilePath = PathPolicy.new("#{filePath}/Output", "Output")
106
+ fetcher.downloadPostsByUsername(username, outputFilePath)
107
+
108
+ Helper.printNewVersionMessageIfExists()
109
+ end
110
+
86
111
  end
87
112
  end
88
113
 
data/lib/Helper.rb CHANGED
@@ -99,7 +99,7 @@ class Helper
99
99
  end
100
100
  end
101
101
 
102
- def self.createPostInfo(postInfo, isPin, isForJekyll)
102
+ def self.createPostInfo(postInfo, isPin, isLockedPreviewOnly, isForJekyll)
103
103
  title = postInfo.title&.gsub("[","")
104
104
  title = title&.gsub("]","")
105
105
 
@@ -123,6 +123,9 @@ class Helper
123
123
  if !isPin.nil? && isPin == true
124
124
  result += "pin: true\r\n"
125
125
  end
126
+ if !isLockedPreviewOnly.nil? && isLockedPreviewOnly == true
127
+ result += "lockedPreviewOnly: true\r\n"
128
+ end
126
129
 
127
130
  if isForJekyll
128
131
  result += "render_with_liquid: false\n"
@@ -211,4 +214,17 @@ class Helper
211
214
 
212
215
  text
213
216
  end
217
+
218
+ def self.createViewFullPost(postURL, isForJekyll)
219
+ jekyllOpen = ""
220
+ if isForJekyll
221
+ jekyllOpen = "{:target=\"_blank\"}"
222
+ end
223
+
224
+ text = "\r\n\r\n\r\n"
225
+ text += "**This [post](#{postURL})#{jekyllOpen} is behind Medium's paywall, View the full [post](#{postURL})#{jekyllOpen} on Medium, converted by [ZMediumToMarkdown](https://github.com/ZhgChgLi/ZMediumToMarkdown)#{jekyllOpen}.**"
226
+ text += "\r\n"
227
+
228
+ text
229
+ end
214
230
  end
@@ -76,20 +76,28 @@ class IframeParser < Parser
76
76
  gist.gsub! '\"', '"'
77
77
  gist.gsub! '<\/', '</'
78
78
  gistHTML = Nokogiri::HTML(gist)
79
- lang = gistHTML.search('table').first['data-tagsearch-lang'].downcase
80
- if isForJekyll and lang == "objective-c"
81
- lang = "objectivec"
82
- end
83
- gistHTML.search('a').each do |a|
84
- if a.text == 'view raw'
85
- gistRAW = Request.body(Request.URL(a['href']))
79
+
80
+ lang = gistHTML.search('table').first['data-tagsearch-lang']
86
81
 
87
- result = "```#{lang}\n"
82
+ if !lang.nil?
83
+ lang = lang.downcase
84
+ if isForJekyll and lang == "objective-c"
85
+ lang = "objectivec"
86
+ end
87
+ gistHTML.search('a').each do |a|
88
+ if a.text == 'view raw'
89
+ gistRAW = Request.body(Request.URL(a['href']))
88
90
 
89
- result += gistRAW.chomp
90
-
91
- result += "\n```"
91
+ result = "```#{lang}\n"
92
+
93
+ result += gistRAW.chomp
94
+
95
+ result += "\n```"
96
+ end
92
97
  end
98
+ else
99
+ clean_url = srce.to_s.gsub(/\.js$/, '')
100
+ result = "[#{clean_url}](#{clean_url})#{jekyllOpen}"
93
101
  end
94
102
  else
95
103
  ogURL = url
@@ -156,11 +156,6 @@ class ZMediumFetcher
156
156
 
157
157
  isLockedPreviewOnly = contentInfo&.dig("isLockedPreviewOnly")
158
158
 
159
- if isLockedPreviewOnly
160
- puts "Skip: This post is listed in Medium's paywall. You need to provide Medium Member vaild logged-in cookies to access it (refer to Readme.md). PostURL: #{postURL}"
161
- return
162
- end
163
-
164
159
  sourceParagraphs = contentInfo&.dig("bodyModel", "paragraphs")
165
160
 
166
161
  if sourceParagraphs.nil?
@@ -249,6 +244,7 @@ class ZMediumFetcher
249
244
 
250
245
  fileLatestPublishedAt = nil
251
246
  filePin = false
247
+ fileLockedPreviewOnly = false
252
248
  if File.file?(absolutePath)
253
249
  lines = File.foreach(absolutePath).first(15)
254
250
  if lines.first&.start_with?("---")
@@ -261,10 +257,15 @@ class ZMediumFetcher
261
257
  if !pinLine.nil?
262
258
  filePin = pinLine[/^(pin:)\s+(\S*)/, 2].downcase == "true"
263
259
  end
260
+
261
+ lockedPreviewOnlyLine = lines.select { |line| line.start_with?("lockedPreviewOnly:") }.first
262
+ if !lockedPreviewOnlyLine.nil?
263
+ fileLockedPreviewOnly = lockedPreviewOnlyLine[/^(lockedPreviewOnly:)\s+(\S*)/, 2].downcase == "true"
264
+ end
264
265
  end
265
266
  end
266
267
 
267
- if (!fileLatestPublishedAt.nil? && fileLatestPublishedAt >= postInfo.latestPublishedAt.to_i) && (!isPin.nil? && isPin == filePin)
268
+ if (!fileLatestPublishedAt.nil? && fileLatestPublishedAt >= postInfo.latestPublishedAt.to_i) && (!isPin.nil? && isPin == filePin) && (!isLockedPreviewOnly.nil? && isLockedPreviewOnly == fileLockedPreviewOnly)
268
269
  # Already downloaded and nothing has changed!, Skip!
269
270
  progress.currentPostParagraphIndex = paragraphs.length
270
271
  progress.message = "Skip, Post already downloaded and nothing has changed!"
@@ -273,7 +274,7 @@ class ZMediumFetcher
273
274
  Helper.createDirIfNotExist(postPathPolicy.getAbsolutePath(nil))
274
275
  File.open(absolutePath, "w+") do |file|
275
276
  # write postInfo into top
276
- postMetaInfo = Helper.createPostInfo(postInfo, isPin, isForJekyll)
277
+ postMetaInfo = Helper.createPostInfo(postInfo, isPin, isLockedPreviewOnly, isForJekyll)
277
278
  if !postMetaInfo.nil?
278
279
  file.puts(postMetaInfo)
279
280
  end
@@ -296,15 +297,29 @@ class ZMediumFetcher
296
297
  progress.message = "Converting Post..."
297
298
  progress.printLog()
298
299
  end
299
-
300
- postWatermark = Helper.createWatermark(postURL, isForJekyll)
301
- if !postWatermark.nil?
302
- file.puts(postWatermark)
300
+
301
+ if isLockedPreviewOnly
302
+ viewFullPost = Helper.createViewFullPost(postURL, isForJekyll)
303
+ if !viewFullPost.nil?
304
+ file.puts(viewFullPost)
305
+ end
306
+ else
307
+ postWatermark = Helper.createWatermark(postURL, isForJekyll)
308
+ if !postWatermark.nil?
309
+ file.puts(postWatermark)
310
+ end
303
311
  end
312
+
313
+
304
314
  end
305
315
  FileUtils.touch absolutePath, :mtime => postInfo.latestPublishedAt
306
316
 
307
- progress.message = "Post Successfully Downloaded!"
317
+ if isLockedPreviewOnly
318
+ progress.message = "This post is behind Medium's paywall. You need to provide valid Medium Member login cookies to download the full post."
319
+ else
320
+ progress.message = "Post Successfully Downloaded!"
321
+ end
322
+
308
323
  progress.printLog()
309
324
  end
310
325
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ZMediumToMarkdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ZhgChgLi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-10 00:00:00.000000000 Z
11
+ date: 2024-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri