ZMediumToMarkdown 1.9.8 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/ZMediumToMarkdown +4 -4
- data/lib/Helper.rb +9 -18
- 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 +6 -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: 9d5d59f757813210f3d5d98025ab4bcbb79eaf99c7a8f75d9540854fc7aa7093
|
4
|
+
data.tar.gz: ab7fcd5f9d8588697bc59bd4f26b0a334d69b4e9f21325425e144f53c7a9f38b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d8913a1d4b741a30e4496513fa5c7e6cd0b80b495eb2b62a22eeee4f2e66cdb5873f5b886de1200dff62d2bb1dc175f15312999e7bc28f56fd0cffd361be9cd
|
7
|
+
data.tar.gz: 42dca718b61f52b20424edf8de42a0c9936f39adfdb0392efcc4990cc53df1b4534650d6cb5d48f6945e4d513a39a39657132682dce242d44a897686c5c39503
|
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')
|
@@ -99,7 +95,6 @@ class Helper
|
|
99
95
|
end
|
100
96
|
|
101
97
|
def self.createPostInfo(postInfo, isForJekyll)
|
102
|
-
|
103
98
|
title = postInfo.title.gsub("[","")
|
104
99
|
title = title.gsub("]","")
|
105
100
|
|
@@ -107,9 +102,14 @@ 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"
|
109
|
+
if !postInfo.previewImage.nil?
|
110
|
+
result += "image:\r\n"
|
111
|
+
result += " path: #{postInfo.previewImage}\r\n"
|
112
|
+
end
|
113
113
|
if isForJekyll
|
114
114
|
result += "render_with_liquid: false\n"
|
115
115
|
end
|
@@ -186,19 +186,10 @@ class Helper
|
|
186
186
|
|
187
187
|
|
188
188
|
def self.createWatermark(postURL)
|
189
|
-
text = ""
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
# text += "\r\n"
|
194
|
-
# text += "\r\n"
|
195
|
-
# text += "| **[View original post on Medium](#{postURL}) - Converted by [ZhgChgLi](https://zhgchg.li)/[ZMediumToMarkdown](https://github.com/ZhgChgLi/ZMediumToMarkdown)** |"
|
196
|
-
# text += "\r\n"
|
197
|
-
# text += "\r\n"
|
198
|
-
# text += "+-----------------------------------------------------------------------------------+"
|
199
|
-
# text += "\r\n"
|
200
|
-
|
201
|
-
# no need to show any watermark :)
|
189
|
+
text = "\r\n\r\n\r\n"
|
190
|
+
text += "_Converted [Medium Post](#{postURL}) by [ZMediumToMarkdown](https://github.com/ZhgChgLi/ZMediumToMarkdown)._"
|
191
|
+
text += "\r\n"
|
192
|
+
|
202
193
|
text
|
203
194
|
end
|
204
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![#{paragraph.
|
32
|
+
result = "\r\n\r\n![#{paragraph.text}](/#{relativePath}#{alt})\r\n\r\n"
|
36
33
|
else
|
37
|
-
result = "\r\n\r\n![#{paragraph.
|
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.
|
37
|
+
result = "\r\n\r\n![#{paragraph.text}](#{imageURL}#{alt})\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[![#{title}](/#{relativePath} \"#{title}\")](#{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[![#{title}](#{ogImageURL} \"#{title}\")](#{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.
|
14
|
+
"\r\n\r\n[![#{paragraph.text}](#{ogImageURL} \"#{paragraph.text}\")](#{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,12 @@ 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
|
+
escapeTagChar = TagChar.new(0,markup.start, markup.end,'','')
|
179
|
+
escapeTagChar.startChars = TextChar.new('\\'.chars,'Text')
|
180
|
+
escapeTagChar.endChars = TextChar.new([],'Text')
|
181
|
+
|
182
|
+
tag = escapeTagChar
|
177
183
|
elsif markup.type == "A"
|
178
184
|
url = markup.href
|
179
185
|
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.2
|
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
|