ZMediumToMarkdown 2.0.0 → 2.0.1

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: 796d995f3d5f3f1edf3de599a28df4a8bea5ab9083d9bf8191d0d0535c924eb3
4
- data.tar.gz: 7fa92c888507d4fea9293a3649c1656d3891a04b34d73d035d1a65676a5c8dc4
3
+ metadata.gz: c410145d7924db7410198b57030d8a886b81162d2dc0f63c580d9140131aaae3
4
+ data.tar.gz: 91930b43c92725becb2d6f2e2246a4df6c2bed1d7616cd4f6dfb11cafa0d3af3
5
5
  SHA512:
6
- metadata.gz: 434c7f737e281189a0feaa821d25e936632be3e72731a495ba62ea945bfef67063518637879b44ecf5f9121ce4ae8b302553bca55959a93e874904cc0fddc808
7
- data.tar.gz: 298efd510208b800826cd39be456e47a7b1744291078fd7e61b954a59e9c9257e796c09ed1813b098ad0c8615c17b1b7e19217388dcbcd9f085d9b5151a35663
6
+ metadata.gz: b23e795f4af879ad6902dcf7a842cb0f1ad160e722196b1e8e4b17bb404686ac0f9fb3801b396124e4f248beb4743c1c56787bf5ef17fecb1b662f880983ce74
7
+ data.tar.gz: 9fa9954456a922437b624e2b4a762b509e5fac44ba453ca947b87ab838ad0110fd005cb628e9ae8042d2ddf60f0b850e92a08a8a9a148c0a00e8c30c77326670
@@ -19,21 +19,21 @@ class Main
19
19
  opts.banner = "Usage: ZMediumFetcher [options]"
20
20
 
21
21
  opts.on('-uUSERNAME', '--username=USERNAME', 'Downloading all posts from user') do |username|
22
- outputFilePath = PathPolicy.new(filePath, "Output")
22
+ outputFilePath = PathPolicy.new("#{filePath}/Output", "Output")
23
23
  fetcher.downloadPostsByUsername(username, outputFilePath)
24
24
 
25
25
  Helper.printNewVersionMessageIfExists()
26
26
  end
27
27
 
28
28
  opts.on('-pPOST_URL', '--postURL=POST_URL', 'Downloading single post') do |postURL|
29
- outputFilePath = PathPolicy.new(filePath, "Output")
29
+ outputFilePath = PathPolicy.new("#{filePath}/Output", "Output")
30
30
  fetcher.downloadPost(postURL, outputFilePath)
31
31
 
32
32
  Helper.printNewVersionMessageIfExists()
33
33
  end
34
34
 
35
35
  opts.on('-jUSERNAME', '--jekyllUsername=USERNAME', 'Downloading all posts from user with Jekyll friendly') do |username|
36
- outputFilePath = PathPolicy.new(filePath, "/")
36
+ outputFilePath = PathPolicy.new(filePath, "")
37
37
  fetcher.isForJekyll = true
38
38
  fetcher.downloadPostsByUsername(username, outputFilePath)
39
39
 
@@ -41,7 +41,7 @@ class Main
41
41
  end
42
42
 
43
43
  opts.on('-kPOST_URL', '--jekyllPostURL=POST_URL', 'Downloading single post with Jekyll friendly') do |postURL|
44
- outputFilePath = PathPolicy.new(filePath, "/")
44
+ outputFilePath = PathPolicy.new(filePath, "")
45
45
  fetcher.isForJekyll = true
46
46
  fetcher.downloadPost(postURL, outputFilePath)
47
47
 
data/lib/Helper.rb CHANGED
@@ -12,10 +12,6 @@ require 'nokogiri'
12
12
 
13
13
  class Helper
14
14
 
15
- def self.escapeMarkdown(text)
16
- text.gsub(/(\*|_|`|\||\\|\{|\}|\[|\]|\(|\)|#|\+|\-|\.|\!)/){ |x| "\\#{x}" }
17
- end
18
-
19
15
  def self.fetchOGImage(url)
20
16
  html = Request.html(Request.URL(url))
21
17
  content = html.search("meta[property='og:image']").attribute('content')
@@ -99,30 +95,28 @@ class Helper
99
95
  end
100
96
 
101
97
  def self.createPostInfo(postInfo, isForJekyll)
98
+ title = postInfo.title.gsub("[","")
99
+ title = title.gsub("]","")
100
+
101
+ result = "---\n"
102
+ result += "title: #{title}\n"
103
+ result += "author: #{postInfo.creator}\n"
104
+ result += "date: #{postInfo.firstPublishedAt.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}\n"
105
+ result += "last_modified_at: #{postInfo.latestPublishedAt.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}\n"
106
+ result += "categories: #{postInfo.collectionName}\n"
107
+ result += "tags: [#{postInfo.tags.join(",")}]\n"
108
+ result += "description: #{postInfo.description}\n"
109
+ if !postInfo.previewImage.nil?
110
+ result += "image:\r\n"
111
+ result += " path: #{postInfo.previewImage}\r\n"
112
+ end
102
113
  if isForJekyll
103
- title = postInfo.title.gsub("[","")
104
- title = title.gsub("]","")
105
-
106
- result = "---\n"
107
- result += "title: #{title}\n"
108
- result += "author: #{postInfo.creator}\n"
109
- result += "date: #{postInfo.firstPublishedAt.strftime('%Y-%m-%dT%H:%M:%S.%LZ')}\n"
110
- result += "categories: #{postInfo.collectionName}\n"
111
- result += "tags: [#{postInfo.tags.join(",")}]\n"
112
- result += "description: #{postInfo.description}\n"
113
- if !postInfo.previewImage.nil?
114
- result += "image:\r\n"
115
- result += " path: #{postInfo.previewImage}\r\n"
116
- end
117
114
  result += "render_with_liquid: false\n"
118
-
119
- result += "---\n"
120
- result += "\r\n"
121
-
122
- result
123
- else
124
- nil
125
115
  end
116
+ result += "---\n"
117
+ result += "\r\n"
118
+
119
+ result
126
120
  end
127
121
 
128
122
  def self.printNewVersionMessageIfExists()
@@ -5,7 +5,7 @@ require 'Parsers/PParser'
5
5
  require 'securerandom'
6
6
 
7
7
  class Paragraph
8
- attr_accessor :postID, :name, :orgText, :orgTextWithEscape, :text, :type, :href, :metadata, :mixtapeMetadata, :iframe, :oliIndex, :markups, :markupLinks
8
+ attr_accessor :postID, :name, :orgText, :text, :type, :href, :metadata, :mixtapeMetadata, :iframe, :oliIndex, :markups, :markupLinks
9
9
 
10
10
  class Iframe
11
11
  attr_accessor :id, :title, :type, :src
@@ -66,9 +66,6 @@ class Paragraph
66
66
  @href = json['href']
67
67
  @postID = postID
68
68
 
69
- orgTextWithEscape = Helper.escapeMarkdown(json['text'])
70
- @orgTextWithEscape = orgTextWithEscape
71
-
72
69
  if json['metadata'].nil?
73
70
  @metadata = nil
74
71
  else
@@ -87,19 +84,28 @@ class Paragraph
87
84
  @iframe = Iframe.new(json['iframe']['mediaResource'])
88
85
  end
89
86
 
87
+ markups = []
90
88
  if !json['markups'].nil? && json['markups'].length > 0
91
- markups = []
92
89
  json['markups'].each do |markup|
93
90
  markups.append(Markup.new(markup))
94
91
  end
95
- @markups = markups
96
-
92
+
97
93
  links = json['markups'].select{ |markup| markup["type"] == "A" }
98
94
  if !links.nil? && links.length > 0
99
95
  @markupLinks = links.map{ |link| link["href"] }
100
96
  end
101
- else
102
- @markups = nil
103
97
  end
98
+
99
+ i = 0
100
+ while i = orgText.index(/(\*|_|`|\||\\|\{|\}|\[|\]|\(|\)|#|\+|\-|\.|\!)/, i + 1)
101
+ escapeMarkup = {
102
+ "type" => 'ESCAPE',
103
+ "start" => i,
104
+ "end" => i + 1
105
+ }
106
+ markups.append(Markup.new(escapeMarkup))
107
+ end
108
+
109
+ @markups = markups
104
110
  end
105
111
  end
@@ -20,24 +20,21 @@ class IMGParser < Parser
20
20
 
21
21
  imageURL = "https://miro.medium.com/max/1400/#{fileName}"
22
22
 
23
- imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), paragraph.postID)
23
+ imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(paragraph.postID), pathPolicy.getRelativePath(paragraph.postID))
24
24
  absolutePath = imagePathPolicy.getAbsolutePath(fileName)
25
25
 
26
26
  result = ""
27
27
  alt = ""
28
- if paragraph.orgTextWithEscape != ""
29
- alt = " \"#{paragraph.orgTextWithEscape}\""
30
- end
31
28
 
32
29
  if ImageDownloader.download(absolutePath, imageURL)
33
- relativePath = "#{pathPolicy.getRelativePath(nil)}/#{imagePathPolicy.getRelativePath(fileName)}"
30
+ relativePath = imagePathPolicy.getRelativePath(fileName)
34
31
  if isForJekyll
35
- result = "\r\n\r\n![#{paragraph.orgTextWithEscape}](/#{relativePath}#{alt})\r\n\r\n"
32
+ result = "\r\n\r\n![#{paragraph.text}](/#{relativePath}#{alt})\r\n\r\n"
36
33
  else
37
- result = "\r\n\r\n![#{paragraph.orgTextWithEscape}](#{relativePath}#{alt})\r\n\r\n"
34
+ result = "\r\n\r\n![#{paragraph.text}](#{relativePath}#{alt})\r\n\r\n"
38
35
  end
39
36
  else
40
- result = "\r\n\r\n![#{paragraph.orgTextWithEscape}](#{imageURL}#{alt})\r\n\r\n"
37
+ result = "\r\n\r\n![#{paragraph.text}](#{imageURL}#{alt})\r\n\r\n"
41
38
  end
42
39
 
43
40
  if paragraph.text != ""
@@ -39,7 +39,7 @@ class IframeParser < Parser
39
39
  fileName = "#{paragraph.name}_#{URI(params["image"]).path.split("/").last}" #21de_default.jpg
40
40
 
41
41
  imageURL = params["image"]
42
- imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), paragraph.postID)
42
+ imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(paragraph.postID), pathPolicy.getRelativePath(paragraph.postID))
43
43
  absolutePath = imagePathPolicy.getAbsolutePath(fileName)
44
44
  title = paragraph.iframe.title
45
45
  if title.nil? or title == ""
@@ -47,7 +47,7 @@ class IframeParser < Parser
47
47
  end
48
48
 
49
49
  if ImageDownloader.download(absolutePath, imageURL)
50
- relativePath = "#{pathPolicy.getRelativePath(nil)}/#{imagePathPolicy.getRelativePath(fileName)}"
50
+ relativePath = imagePathPolicy.getRelativePath(fileName)
51
51
  if isForJekyll
52
52
  result = "\r\n\r\n[![#{title}](/#{relativePath} \"#{title}\")](#{params["url"]})\r\n\r\n"
53
53
  else
@@ -11,9 +11,9 @@ class MIXTAPEEMBEDParser < Parser
11
11
  if !paragraph.mixtapeMetadata.nil? && !paragraph.mixtapeMetadata.href.nil?
12
12
  ogImageURL = Helper.fetchOGImage(paragraph.mixtapeMetadata.href)
13
13
  if !ogImageURL.nil?
14
- "\r\n\r\n[![#{paragraph.orgTextWithEscape}](#{ogImageURL} \"#{paragraph.orgTextWithEscape}\")](#{paragraph.mixtapeMetadata.href})\r\n\r\n"
14
+ "\r\n\r\n[![#{paragraph.text}](#{ogImageURL} \"#{paragraph.text}\")](#{paragraph.mixtapeMetadata.href})\r\n\r\n"
15
15
  else
16
- "\n[#{paragraph.orgTextWithEscape}](#{paragraph.mixtapeMetadata.href})"
16
+ "\n[#{paragraph.text}](#{paragraph.mixtapeMetadata.href})"
17
17
  end
18
18
  else
19
19
  "\n#{paragraph.text}"
@@ -174,6 +174,8 @@ class MarkupStyleRender
174
174
  tag = TagChar.new(3, markup.start, markup.end, "`", "`")
175
175
  elsif markup.type == "STRONG"
176
176
  tag = TagChar.new(2, markup.start, markup.end, "**", "**")
177
+ elsif markup.type == "ESCAPE"
178
+ tag = TagChar.new(2, markup.start, markup.end, "\\", "**")
177
179
  elsif markup.type == "A"
178
180
  url = markup.href
179
181
  if markup.anchorType == "LINK"
data/lib/PathPolicy.rb CHANGED
@@ -8,18 +8,29 @@ class PathPolicy
8
8
  end
9
9
 
10
10
  def getRelativePath(lastPath)
11
- if lastPath.nil?
12
- "#{path}"
13
- else
14
- "#{path}/#{lastPath}"
11
+ result = path
12
+
13
+ if result != ""
14
+ result += "/"
15
+ end
16
+
17
+ if !lastPath.nil?
18
+ result += lastPath
15
19
  end
20
+
21
+ result
16
22
  end
17
23
 
18
24
  def getAbsolutePath(lastPath)
19
- if lastPath.nil?
20
- "#{rootPath}/#{path}"
21
- else
22
- "#{rootPath}/#{path}/#{lastPath}"
25
+ result = rootPath
26
+
27
+ if !lastPath.nil?
28
+ if result != ""
29
+ result += "/"
30
+ end
31
+ result += "#{lastPath}"
23
32
  end
33
+
34
+ result
24
35
  end
25
36
  end
data/lib/Post.rb CHANGED
@@ -70,13 +70,14 @@ class Post
70
70
  if !previewImage.nil?
71
71
  previewImageFIleName = content&.dig(previewImage, "id")
72
72
 
73
- imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), postID)
73
+ imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(postID), pathPolicy.getRelativePath(postID))
74
+
74
75
  absolutePath = imagePathPolicy.getAbsolutePath(previewImageFIleName)
75
76
 
76
77
  imageURL = "https://miro.medium.com/max/1400/#{previewImageFIleName}"
77
78
 
78
79
  if ImageDownloader.download(absolutePath, imageURL)
79
- relativePath = "#{pathPolicy.getRelativePath(nil)}/#{imagePathPolicy.getRelativePath(previewImageFIleName)}"
80
+ relativePath = imagePathPolicy.getRelativePath(previewImageFIleName)
80
81
  postInfo.previewImage = relativePath
81
82
  end
82
83
  end
@@ -122,11 +122,11 @@ class ZMediumFetcher
122
122
  end
123
123
 
124
124
  if isForJekyll
125
- postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "_posts/zmediumtomarkdown")
126
- imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "assets")
125
+ postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("_posts/zmediumtomarkdown"), pathPolicy.getRelativePath("_posts/zmediumtomarkdown"))
126
+ imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("assets"), "assets")
127
127
  else
128
- postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "zmediumtomarkdown")
129
- imagePathPolicy = PathPolicy.new(postPathPolicy.getAbsolutePath(nil), "assets")
128
+ postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("zmediumtomarkdown"), pathPolicy.getRelativePath("zmediumtomarkdown"))
129
+ imagePathPolicy = PathPolicy.new(postPathPolicy.getAbsolutePath("assets"), "assets")
130
130
  end
131
131
 
132
132
  progress.postPath = postPath
@@ -229,8 +229,19 @@ class ZMediumFetcher
229
229
 
230
230
  absolutePath = postPathPolicy.getAbsolutePath("#{postWithDatePath}.md")
231
231
 
232
- # if markdown file is exists and last modification time is >= latestPublishedAt(last update post time on medium)
233
- if File.file?(absolutePath) && File.mtime(absolutePath).to_time.to_i >= postInfo.latestPublishedAt.to_i
232
+ fileLatestPublishedAt = nil
233
+
234
+ if File.file?(absolutePath)
235
+ lines = File.foreach(absolutePath).first(15)
236
+ if lines.first.start_with?("---")
237
+ dateLine = lines.select { |line| line.start_with?("last_modified_at:") }.first
238
+ if !dateLine.nil?
239
+ fileLatestPublishedAt = Time.parse(dateLine[/^(last_modified_at:)\s+(\S*)/, 2]).to_i
240
+ end
241
+ end
242
+ end
243
+
244
+ if !fileLatestPublishedAt.nil? && fileLatestPublishedAt >= postInfo.latestPublishedAt.to_i
234
245
  # Already downloaded and nothing has changed!, Skip!
235
246
  progress.currentPostParagraphIndex = paragraphs.length
236
247
  progress.message = "Skip, Post already downloaded and nothing has changed!"
@@ -310,7 +321,7 @@ class ZMediumFetcher
310
321
  if isForJekyll
311
322
  downloadPathPolicy = pathPolicy
312
323
  else
313
- downloadPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "users/#{username}")
324
+ downloadPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("users/#{username}"), pathPolicy.getRelativePath("users/#{username}"))
314
325
  end
315
326
 
316
327
  index = 0
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.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ZhgChgLi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-18 00:00:00.000000000 Z
11
+ date: 2022-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri