ZMediumToMarkdown 1.9.7 → 2.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 +4 -4
- data/bin/ZMediumToMarkdown +4 -4
- data/lib/Helper.rb +11 -15
- data/lib/Models/Paragraph.rb +15 -9
- data/lib/Parsers/IMGParser.rb +6 -9
- data/lib/Parsers/IframeParser.rb +46 -11
- data/lib/Parsers/MIXTAPEEMBEDParser.rb +2 -2
- data/lib/Parsers/MarkupStyleRender.rb +2 -0
- data/lib/PathPolicy.rb +19 -8
- data/lib/Post.rb +21 -3
- data/lib/ZMediumFetcher.rb +31 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c410145d7924db7410198b57030d8a886b81162d2dc0f63c580d9140131aaae3
|
4
|
+
data.tar.gz: 91930b43c92725becb2d6f2e2246a4df6c2bed1d7616cd4f6dfb11cafa0d3af3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b23e795f4af879ad6902dcf7a842cb0f1ad160e722196b1e8e4b17bb404686ac0f9fb3801b396124e4f248beb4743c1c56787bf5ef17fecb1b662f880983ce74
|
7
|
+
data.tar.gz: 9fa9954456a922437b624e2b4a762b509e5fac44ba453ca947b87ab838ad0110fd005cb628e9ae8042d2ddf60f0b850e92a08a8a9a148c0a00e8c30c77326670
|
data/bin/ZMediumToMarkdown
CHANGED
@@ -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')
|
@@ -98,8 +94,7 @@ class Helper
|
|
98
94
|
end
|
99
95
|
end
|
100
96
|
|
101
|
-
def self.createPostInfo(postInfo)
|
102
|
-
|
97
|
+
def self.createPostInfo(postInfo, isForJekyll)
|
103
98
|
title = postInfo.title.gsub("[","")
|
104
99
|
title = title.gsub("]","")
|
105
100
|
|
@@ -107,10 +102,17 @@ class Helper
|
|
107
102
|
result += "title: #{title}\n"
|
108
103
|
result += "author: #{postInfo.creator}\n"
|
109
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"
|
110
106
|
result += "categories: #{postInfo.collectionName}\n"
|
111
107
|
result += "tags: [#{postInfo.tags.join(",")}]\n"
|
112
108
|
result += "description: #{postInfo.description}\n"
|
113
|
-
|
109
|
+
if !postInfo.previewImage.nil?
|
110
|
+
result += "image:\r\n"
|
111
|
+
result += " path: #{postInfo.previewImage}\r\n"
|
112
|
+
end
|
113
|
+
if isForJekyll
|
114
|
+
result += "render_with_liquid: false\n"
|
115
|
+
end
|
114
116
|
result += "---\n"
|
115
117
|
result += "\r\n"
|
116
118
|
|
@@ -185,15 +187,9 @@ class Helper
|
|
185
187
|
|
186
188
|
def self.createWatermark(postURL)
|
187
189
|
text = "\r\n\r\n\r\n"
|
188
|
-
text += "
|
189
|
-
text += "\r\n"
|
190
|
+
text += "_Converted [Medium Post](#{postURL}) by [ZMediumToMarkdown](https://github.com/ZhgChgLi/ZMediumToMarkdown)._"
|
190
191
|
text += "\r\n"
|
191
|
-
|
192
|
-
text += "\r\n"
|
193
|
-
text += "\r\n"
|
194
|
-
text += "+-----------------------------------------------------------------------------------+"
|
195
|
-
text += "\r\n"
|
196
|
-
|
192
|
+
|
197
193
|
text
|
198
194
|
end
|
199
195
|
end
|
data/lib/Models/Paragraph.rb
CHANGED
@@ -5,7 +5,7 @@ require 'Parsers/PParser'
|
|
5
5
|
require 'securerandom'
|
6
6
|
|
7
7
|
class Paragraph
|
8
|
-
attr_accessor :postID, :name, :orgText, :
|
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
|
-
|
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
|
data/lib/Parsers/IMGParser.rb
CHANGED
@@ -18,26 +18,23 @@ class IMGParser < Parser
|
|
18
18
|
|
19
19
|
fileName = paragraph.metadata.id #d*fsafwfe.jpg
|
20
20
|
|
21
|
-
imageURL = "https://miro.medium.com/max/1400/#{
|
21
|
+
imageURL = "https://miro.medium.com/max/1400/#{fileName}"
|
22
22
|
|
23
|
-
imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(
|
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 =
|
30
|
+
relativePath = imagePathPolicy.getRelativePath(fileName)
|
34
31
|
if isForJekyll
|
35
|
-
result = "\r\n\r\n\r\n\r\n"
|
36
33
|
else
|
37
|
-
result = "\r\n\r\n\r\n\r\n"
|
38
35
|
end
|
39
36
|
else
|
40
|
-
result = "\r\n\r\n\r\n\r\n"
|
41
38
|
end
|
42
39
|
|
43
40
|
if paragraph.text != ""
|
data/lib/Parsers/IframeParser.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$lib = File.expand_path('../', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
require 'uri'
|
4
|
+
require 'net/http'
|
4
5
|
|
5
6
|
require "Request"
|
6
7
|
require "Parsers/Parser"
|
@@ -38,7 +39,7 @@ class IframeParser < Parser
|
|
38
39
|
fileName = "#{paragraph.name}_#{URI(params["image"]).path.split("/").last}" #21de_default.jpg
|
39
40
|
|
40
41
|
imageURL = params["image"]
|
41
|
-
imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(
|
42
|
+
imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(paragraph.postID), pathPolicy.getRelativePath(paragraph.postID))
|
42
43
|
absolutePath = imagePathPolicy.getAbsolutePath(fileName)
|
43
44
|
title = paragraph.iframe.title
|
44
45
|
if title.nil? or title == ""
|
@@ -46,7 +47,7 @@ class IframeParser < Parser
|
|
46
47
|
end
|
47
48
|
|
48
49
|
if ImageDownloader.download(absolutePath, imageURL)
|
49
|
-
relativePath =
|
50
|
+
relativePath = imagePathPolicy.getRelativePath(fileName)
|
50
51
|
if isForJekyll
|
51
52
|
result = "\r\n\r\n[](#{params["url"]})\r\n\r\n"
|
52
53
|
else
|
@@ -90,17 +91,51 @@ class IframeParser < Parser
|
|
90
91
|
ogURL = params["url"]
|
91
92
|
end
|
92
93
|
end
|
93
|
-
ogImageURL = Helper.fetchOGImage(ogURL)
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
95
|
+
twitterID = ogURL[/^(https\:\/\/twitter\.com\/){1}.+(\/){1}(\d+)/, 3]
|
96
|
+
|
97
|
+
if !twitterID.nil?
|
98
|
+
uri = URI("https://api.twitter.com/1.1/statuses/show.json?simple_quoted_tweet=true&include_entities=true&tweet_mode=extended&include_cards=1&id=#{twitterID}")
|
99
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
100
|
+
https.use_ssl = true
|
101
|
+
|
102
|
+
request = Net::HTTP::Get.new(uri)
|
103
|
+
request['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.17.375.766 Safari/537.36';
|
104
|
+
request['Authorization'] = 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'; # twitter private api
|
105
|
+
|
106
|
+
response = https.request(request)
|
107
|
+
if response.code.to_i == 200
|
108
|
+
twitterObj = JSON.parse(response.read_body)
|
109
|
+
|
110
|
+
fullText = twitterObj["full_text"]
|
111
|
+
twitterObj["entities"]["user_mentions"].each do |user_mention|
|
112
|
+
fullText = fullText.gsub(user_mention["screen_name"],"[#{user_mention["screen_name"]}](https://twitter.com/#{user_mention["screen_name"]})")
|
113
|
+
end
|
114
|
+
twitterObj["entities"]["urls"].each do |url|
|
115
|
+
fullText = fullText.gsub(url["url"],"[#{url["display_url"]}](#{url["expanded_url"]})")
|
116
|
+
end
|
117
|
+
|
118
|
+
createdAt = Time.parse(twitterObj["created_at"]).strftime('%Y-%m-%d %H:%M:%S')
|
119
|
+
result = "\n\n"
|
120
|
+
result += "■■■■■■■■■■■■■■ \n"
|
121
|
+
result += "> **[#{twitterObj["user"]["name"]}](https://twitter.com/#{twitterObj["user"]["screen_name"]}) @ Twitter Says:** \n\n"
|
122
|
+
result += "> > #{fullText} \n\n"
|
123
|
+
result += "> **Tweeted at [#{createdAt}](#{ogURL}).** \n\n"
|
124
|
+
result += "■■■■■■■■■■■■■■ \n\n"
|
125
|
+
end
|
102
126
|
else
|
103
|
-
|
127
|
+
ogImageURL = Helper.fetchOGImage(ogURL)
|
128
|
+
|
129
|
+
title = paragraph.iframe.title
|
130
|
+
if title.nil? or title == ""
|
131
|
+
title = Helper.escapeMarkdown(ogURL)
|
132
|
+
end
|
133
|
+
|
134
|
+
if !ogImageURL.nil?
|
135
|
+
result = "\r\n\r\n[](#{ogURL})\r\n\r\n"
|
136
|
+
else
|
137
|
+
result = "[#{title}](#{ogURL})"
|
138
|
+
end
|
104
139
|
end
|
105
140
|
end
|
106
141
|
end
|
@@ -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.mixtapeMetadata.href})\r\n\r\n"
|
15
15
|
else
|
16
|
-
"\n[#{paragraph.
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
"
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
"
|
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
@@ -6,10 +6,12 @@ require 'nokogiri'
|
|
6
6
|
require 'json'
|
7
7
|
require 'date'
|
8
8
|
|
9
|
-
|
9
|
+
require 'ImageDownloader'
|
10
|
+
require 'PathPolicy'
|
10
11
|
|
12
|
+
class Post
|
11
13
|
class PostInfo
|
12
|
-
attr_accessor :title, :tags, :creator, :firstPublishedAt, :latestPublishedAt, :collectionName, :description
|
14
|
+
attr_accessor :title, :tags, :creator, :firstPublishedAt, :latestPublishedAt, :collectionName, :description, :previewImage
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.getPostIDFromPostURLString(postURLString)
|
@@ -58,12 +60,28 @@ class Post
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
def self.parsePostInfoFromPostContent(content, postID)
|
63
|
+
def self.parsePostInfoFromPostContent(content, postID, pathPolicy)
|
62
64
|
postInfo = PostInfo.new()
|
63
65
|
postInfo.description = content&.dig("Post:#{postID}", "previewContent", "subtitle")
|
64
66
|
postInfo.title = content&.dig("Post:#{postID}", "title")
|
65
67
|
postInfo.tags = content&.dig("Post:#{postID}", "tags").map{ |tag| tag["__ref"].gsub! 'Tag:', '' }
|
66
68
|
|
69
|
+
previewImage = content&.dig("Post:#{postID}", "previewImage", "__ref")
|
70
|
+
if !previewImage.nil?
|
71
|
+
previewImageFIleName = content&.dig(previewImage, "id")
|
72
|
+
|
73
|
+
imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(postID), pathPolicy.getRelativePath(postID))
|
74
|
+
|
75
|
+
absolutePath = imagePathPolicy.getAbsolutePath(previewImageFIleName)
|
76
|
+
|
77
|
+
imageURL = "https://miro.medium.com/max/1400/#{previewImageFIleName}"
|
78
|
+
|
79
|
+
if ImageDownloader.download(absolutePath, imageURL)
|
80
|
+
relativePath = imagePathPolicy.getRelativePath(previewImageFIleName)
|
81
|
+
postInfo.previewImage = relativePath
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
67
85
|
creatorRef = content&.dig("Post:#{postID}", "creator", "__ref")
|
68
86
|
if !creatorRef.nil?
|
69
87
|
postInfo.creator = content&.dig(creatorRef, "name")
|
data/lib/ZMediumFetcher.rb
CHANGED
@@ -121,6 +121,14 @@ class ZMediumFetcher
|
|
121
121
|
postPath = Post.getPostPathFromPostURLString(postURL)
|
122
122
|
end
|
123
123
|
|
124
|
+
if isForJekyll
|
125
|
+
postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("_posts/zmediumtomarkdown"), pathPolicy.getRelativePath("_posts/zmediumtomarkdown"))
|
126
|
+
imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("assets"), "assets")
|
127
|
+
else
|
128
|
+
postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("zmediumtomarkdown"), pathPolicy.getRelativePath("zmediumtomarkdown"))
|
129
|
+
imagePathPolicy = PathPolicy.new(postPathPolicy.getAbsolutePath("assets"), "assets")
|
130
|
+
end
|
131
|
+
|
124
132
|
progress.postPath = postPath
|
125
133
|
progress.message = "Downloading Post..."
|
126
134
|
progress.printLog()
|
@@ -132,7 +140,7 @@ class ZMediumFetcher
|
|
132
140
|
raise "Error: Content is empty! PostURL: #{postURL}"
|
133
141
|
end
|
134
142
|
|
135
|
-
postInfo = Post.parsePostInfoFromPostContent(postContent, postID)
|
143
|
+
postInfo = Post.parsePostInfoFromPostContent(postContent, postID, imagePathPolicy)
|
136
144
|
|
137
145
|
sourceParagraphs = Post.fetchPostParagraphs(postID)
|
138
146
|
if sourceParagraphs.nil?
|
@@ -207,14 +215,6 @@ class ZMediumFetcher
|
|
207
215
|
paragraphs.append(paragraph)
|
208
216
|
previousParagraph = paragraph
|
209
217
|
end
|
210
|
-
|
211
|
-
if isForJekyll
|
212
|
-
postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "_posts/zmediumtomarkdown")
|
213
|
-
imagePathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "assets")
|
214
|
-
else
|
215
|
-
postPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(nil), "zmediumtomarkdown")
|
216
|
-
imagePathPolicy = PathPolicy.new(postPathPolicy.getAbsolutePath(nil), "assets")
|
217
|
-
end
|
218
218
|
|
219
219
|
startParser = buildParser(imagePathPolicy)
|
220
220
|
|
@@ -229,8 +229,19 @@ class ZMediumFetcher
|
|
229
229
|
|
230
230
|
absolutePath = postPathPolicy.getAbsolutePath("#{postWithDatePath}.md")
|
231
231
|
|
232
|
-
|
233
|
-
|
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!"
|
@@ -239,7 +250,10 @@ class ZMediumFetcher
|
|
239
250
|
Helper.createDirIfNotExist(postPathPolicy.getAbsolutePath(nil))
|
240
251
|
File.open(absolutePath, "w+") do |file|
|
241
252
|
# write postInfo into top
|
242
|
-
|
253
|
+
postMetaInfo = Helper.createPostInfo(postInfo, isForJekyll)
|
254
|
+
if !postMetaInfo.nil?
|
255
|
+
file.puts(postMetaInfo)
|
256
|
+
end
|
243
257
|
|
244
258
|
index = 0
|
245
259
|
paragraphs.each do |paragraph|
|
@@ -260,7 +274,10 @@ class ZMediumFetcher
|
|
260
274
|
progress.printLog()
|
261
275
|
end
|
262
276
|
|
263
|
-
|
277
|
+
postWatermark = Helper.createWatermark(postURL)
|
278
|
+
if !postWatermark.nil?
|
279
|
+
file.puts(postWatermark)
|
280
|
+
end
|
264
281
|
end
|
265
282
|
FileUtils.touch absolutePath, :mtime => postInfo.latestPublishedAt
|
266
283
|
|
@@ -304,7 +321,7 @@ class ZMediumFetcher
|
|
304
321
|
if isForJekyll
|
305
322
|
downloadPathPolicy = pathPolicy
|
306
323
|
else
|
307
|
-
downloadPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath(
|
324
|
+
downloadPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("users/#{username}"), pathPolicy.getRelativePath("users/#{username}"))
|
308
325
|
end
|
309
326
|
|
310
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:
|
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-
|
11
|
+
date: 2022-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|