ZMediumToMarkdown 2.0.12 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/Helper.rb +3 -3
- data/lib/ImageDownloader.rb +2 -2
- data/lib/Models/Paragraph.rb +15 -2
- data/lib/Parsers/IframeParser.rb +5 -3
- data/lib/Parsers/PREParser.rb +7 -1
- data/lib/Post.rb +3 -4
- data/lib/Request.rb +25 -19
- data/lib/ZMediumFetcher.rb +24 -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: 439f4734a4dde11659f6dede1e220f9edfd2203c0a025599c8c5ca78e2e91aab
|
4
|
+
data.tar.gz: c83396525f04b9313ed53b23d2bdf5b7b4ca5d8a7257c5364d9988c802160bcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b14cc13afd0e3b16ab5195465067ba98b61827171dc38412ca75467670010c4ff0753c7ad94996d29dd3fca5d489de9f055986c0fdbc81b74e83a16bbf9a53f
|
7
|
+
data.tar.gz: 7f9745e8c4608bea3cdf613d262c709d317a5fe1a3e3731d27db990d639e8c1e8b162f453ecded98e6dd6c7a1b4ed54c05262b264ce8b27acecefbbcc4bbdddb
|
data/lib/Helper.rb
CHANGED
@@ -14,9 +14,9 @@ class Helper
|
|
14
14
|
|
15
15
|
def self.fetchOGImage(url)
|
16
16
|
html = Request.html(Request.URL(url))
|
17
|
-
|
18
|
-
|
19
|
-
content
|
17
|
+
return "" unless html
|
18
|
+
image = html.search("meta[property='og:image']")
|
19
|
+
image.attribute('content') || ""
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.escapeMarkdown(text)
|
data/lib/ImageDownloader.rb
CHANGED
@@ -9,8 +9,8 @@ class ImageDownloader
|
|
9
9
|
Helper.createDirIfNotExist(dir.join("/"))
|
10
10
|
|
11
11
|
begin
|
12
|
-
imageResponse = open(url)
|
13
|
-
File.write(path, imageResponse.read
|
12
|
+
imageResponse = URI.open(url)
|
13
|
+
File.write(path, imageResponse.read)
|
14
14
|
true
|
15
15
|
rescue
|
16
16
|
false
|
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, :text, :type, :href, :metadata, :mixtapeMetadata, :iframe, :oliIndex, :markups, :markupLinks
|
8
|
+
attr_accessor :postID, :name, :orgText, :text, :type, :href, :metadata, :mixtapeMetadata, :iframe, :oliIndex, :markups, :markupLinks, :codeBlockMetadata
|
9
9
|
|
10
10
|
class Iframe
|
11
11
|
attr_accessor :id, :title, :type, :src
|
@@ -49,6 +49,13 @@ class Paragraph
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
class CodeBlockMetadata
|
53
|
+
attr_accessor :lang
|
54
|
+
def initialize(json)
|
55
|
+
@lang = json['lang']
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
52
59
|
def self.makeBlankParagraph(postID)
|
53
60
|
json = {
|
54
61
|
"name" => "fakeBlankParagraph_#{SecureRandom.uuid}",
|
@@ -72,13 +79,19 @@ class Paragraph
|
|
72
79
|
@metadata = MetaData.new(json['metadata'])
|
73
80
|
end
|
74
81
|
|
82
|
+
if json['codeBlockMetadata'].nil?
|
83
|
+
@codeBlockMetadata = nil
|
84
|
+
else
|
85
|
+
@codeBlockMetadata = CodeBlockMetadata.new(json['codeBlockMetadata'])
|
86
|
+
end
|
87
|
+
|
75
88
|
if json['mixtapeMetadata'].nil?
|
76
89
|
@mixtapeMetadata = nil
|
77
90
|
else
|
78
91
|
@mixtapeMetadata = MixtapeMetadata.new(json['mixtapeMetadata'])
|
79
92
|
end
|
80
93
|
|
81
|
-
if json['iframe'].nil?
|
94
|
+
if json['iframe'].nil? || !json['iframe'] || !json['iframe']['mediaResource']
|
82
95
|
@iframe = nil
|
83
96
|
else
|
84
97
|
@iframe = Iframe.new(json['iframe']['mediaResource'])
|
data/lib/Parsers/IframeParser.rb
CHANGED
@@ -26,7 +26,7 @@ class IframeParser < Parser
|
|
26
26
|
end
|
27
27
|
|
28
28
|
if paragraph.type == 'IFRAME'
|
29
|
-
|
29
|
+
return unless paragraph.iframe
|
30
30
|
if !paragraph.iframe.src.nil? && paragraph.iframe.src != ""
|
31
31
|
url = paragraph.iframe.src
|
32
32
|
else
|
@@ -65,9 +65,11 @@ class IframeParser < Parser
|
|
65
65
|
end
|
66
66
|
else
|
67
67
|
html = Request.html(Request.URL(url))
|
68
|
-
|
68
|
+
return "" unless html
|
69
|
+
src = html.search('script').first
|
70
|
+
srce = src.attribute('src') if src
|
69
71
|
result = nil
|
70
|
-
if !
|
72
|
+
if !srce.to_s[/^(https\:\/\/gist\.github\.com)/].nil?
|
71
73
|
# is gist
|
72
74
|
gist = Request.body(Request.URL(src)).scan(/(document\.write\('){1}(.*)(\)){1}/)[1][1]
|
73
75
|
gist.gsub! '\n', ''
|
data/lib/Parsers/PREParser.rb
CHANGED
@@ -20,7 +20,13 @@ class PREParser < Parser
|
|
20
20
|
|
21
21
|
def parse(paragraph)
|
22
22
|
if PREParser.isPRE(paragraph)
|
23
|
-
|
23
|
+
|
24
|
+
lang = ""
|
25
|
+
if !paragraph.codeBlockMetadata.nil?
|
26
|
+
lang = paragraph.codeBlockMetadata.lang
|
27
|
+
end
|
28
|
+
|
29
|
+
result = "```#{lang}\n"
|
24
30
|
|
25
31
|
paragraph.text.each_line do |p|
|
26
32
|
result += p
|
data/lib/Post.rb
CHANGED
@@ -23,13 +23,12 @@ class Post
|
|
23
23
|
|
24
24
|
def self.getPostPathFromPostURLString(postURLString)
|
25
25
|
uri = URI.parse(postURLString)
|
26
|
-
|
27
|
-
|
28
|
-
URI.decode(postPath)
|
26
|
+
uri.path.split('/').last
|
29
27
|
end
|
30
28
|
|
31
29
|
def self.parsePostContentFromHTML(html)
|
32
30
|
json = nil
|
31
|
+
return "" unless html
|
33
32
|
html.search('script').each do |script|
|
34
33
|
match = script.to_s[/(<script>window\.__APOLLO_STATE__ \= ){1}(.*)(<\/script>){1}/,2]
|
35
34
|
if !match.nil? && match != ""
|
@@ -47,7 +46,7 @@ class Post
|
|
47
46
|
"variables": {
|
48
47
|
"postId": postID
|
49
48
|
},
|
50
|
-
"query": "query PostViewerEdgeContentQuery($postId: ID!, $postMeteringOptions: PostMeteringOptions) {\n post(id: $postId) {\n ... on Post {\n id\n viewerEdge {\n id\n fullContent(postMeteringOptions: $postMeteringOptions) {\n isLockedPreviewOnly\n validatedShareKey\n bodyModel {\n ...PostBody_bodyModel\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n}\n\nfragment PostBody_bodyModel on RichText {\n sections {\n name\n startIndex\n textLayout\n imageLayout\n backgroundImage {\n id\n originalHeight\n originalWidth\n __typename\n }\n videoLayout\n backgroundVideo {\n videoId\n originalHeight\n originalWidth\n previewImageId\n __typename\n }\n __typename\n }\n paragraphs {\n id\n ...PostBodySection_paragraph\n __typename\n }\n ...normalizedBodyModel_richText\n __typename\n}\n\nfragment PostBodySection_paragraph on Paragraph {\n name\n ...PostBodyParagraph_paragraph\n __typename\n id\n}\n\nfragment PostBodyParagraph_paragraph on Paragraph {\n name\n type\n ...ImageParagraph_paragraph\n ...TextParagraph_paragraph\n ...IframeParagraph_paragraph\n ...MixtapeParagraph_paragraph\n __typename\n id\n}\n\nfragment ImageParagraph_paragraph on Paragraph {\n href\n layout\n metadata {\n id\n originalHeight\n originalWidth\n focusPercentX\n focusPercentY\n alt\n __typename\n }\n ...Markups_paragraph\n ...ParagraphRefsMapContext_paragraph\n ...PostAnnotationsMarker_paragraph\n __typename\n id\n}\n\nfragment Markups_paragraph on Paragraph {\n name\n text\n hasDropCap\n dropCapImage {\n ...MarkupNode_data_dropCapImage\n __typename\n id\n }\n markups {\n type\n start\n end\n href\n anchorType\n userId\n linkMetadata {\n httpStatus\n __typename\n }\n __typename\n }\n __typename\n id\n}\n\nfragment MarkupNode_data_dropCapImage on ImageMetadata {\n ...DropCap_image\n __typename\n id\n}\n\nfragment DropCap_image on ImageMetadata {\n id\n originalHeight\n originalWidth\n __typename\n}\n\nfragment ParagraphRefsMapContext_paragraph on Paragraph {\n id\n name\n text\n __typename\n}\n\nfragment PostAnnotationsMarker_paragraph on Paragraph {\n ...PostViewNoteCard_paragraph\n __typename\n id\n}\n\nfragment PostViewNoteCard_paragraph on Paragraph {\n name\n __typename\n id\n}\n\nfragment TextParagraph_paragraph on Paragraph {\n type\n hasDropCap\n ...Markups_paragraph\n ...ParagraphRefsMapContext_paragraph\n __typename\n id\n}\n\nfragment IframeParagraph_paragraph on Paragraph {\n iframe {\n mediaResource {\n id\n iframeSrc\n iframeHeight\n iframeWidth\n title\n __typename\n }\n __typename\n }\n layout\n ...getEmbedlyCardUrlParams_paragraph\n ...Markups_paragraph\n __typename\n id\n}\n\nfragment getEmbedlyCardUrlParams_paragraph on Paragraph {\n type\n iframe {\n mediaResource {\n iframeSrc\n __typename\n }\n __typename\n }\n __typename\n id\n}\n\nfragment MixtapeParagraph_paragraph on Paragraph {\n type\n mixtapeMetadata {\n href\n mediaResource {\n mediumCatalog {\n id\n __typename\n }\n __typename\n }\n __typename\n }\n ...GenericMixtapeParagraph_paragraph\n __typename\n id\n}\n\nfragment GenericMixtapeParagraph_paragraph on Paragraph {\n text\n mixtapeMetadata {\n href\n thumbnailImageId\n __typename\n }\n markups {\n start\n end\n type\n href\n __typename\n }\n __typename\n id\n}\n\nfragment normalizedBodyModel_richText on RichText {\n paragraphs {\n markups {\n type\n __typename\n }\n ...getParagraphHighlights_paragraph\n ...getParagraphPrivateNotes_paragraph\n __typename\n }\n sections {\n startIndex\n ...getSectionEndIndex_section\n __typename\n }\n ...getParagraphStyles_richText\n ...getParagraphSpaces_richText\n __typename\n}\n\nfragment getParagraphHighlights_paragraph on Paragraph {\n name\n __typename\n id\n}\n\nfragment getParagraphPrivateNotes_paragraph on Paragraph {\n name\n __typename\n id\n}\n\nfragment getSectionEndIndex_section on Section {\n startIndex\n __typename\n}\n\nfragment getParagraphStyles_richText on RichText {\n paragraphs {\n text\n type\n __typename\n }\n sections {\n ...getSectionEndIndex_section\n __typename\n }\n __typename\n}\n\nfragment getParagraphSpaces_richText on RichText {\n paragraphs {\n layout\n metadata {\n originalHeight\n originalWidth\n __typename\n }\n type\n ...paragraphExtendsImageGrid_paragraph\n __typename\n }\n ...getSeriesParagraphTopSpacings_richText\n ...getPostParagraphTopSpacings_richText\n __typename\n}\n\nfragment paragraphExtendsImageGrid_paragraph on Paragraph {\n layout\n type\n __typename\n id\n}\n\nfragment getSeriesParagraphTopSpacings_richText on RichText {\n paragraphs {\n id\n __typename\n }\n sections {\n startIndex\n __typename\n }\n __typename\n}\n\nfragment getPostParagraphTopSpacings_richText on RichText {\n paragraphs {\n layout\n text\n __typename\n }\n sections {\n startIndex\n __typename\n }\n __typename\n}\n"
|
49
|
+
"query": "query PostViewerEdgeContentQuery($postId: ID!, $postMeteringOptions: PostMeteringOptions) {\n post(id: $postId) {\n ... on Post {\n id\n viewerEdge {\n id\n fullContent(postMeteringOptions: $postMeteringOptions) {\n isLockedPreviewOnly\n validatedShareKey\n bodyModel {\n ...PostBody_bodyModel\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n}\n\nfragment PostBody_bodyModel on RichText {\n sections {\n name\n startIndex\n textLayout\n imageLayout\n backgroundImage {\n id\n originalHeight\n originalWidth\n __typename\n }\n videoLayout\n backgroundVideo {\n videoId\n originalHeight\n originalWidth\n previewImageId\n __typename\n }\n __typename\n }\n paragraphs {\n id\n ...PostBodySection_paragraph\n __typename\n }\n ...normalizedBodyModel_richText\n __typename\n}\n\nfragment PostBodySection_paragraph on Paragraph {\n name\n ...PostBodyParagraph_paragraph\n __typename\n id\n}\n\nfragment PostBodyParagraph_paragraph on Paragraph {\n name\n type\n ...ImageParagraph_paragraph\n ...TextParagraph_paragraph\n ...IframeParagraph_paragraph\n ...MixtapeParagraph_paragraph\n ...CodeBlockParagraph_paragraph\n __typename\n id\n}\n\nfragment ImageParagraph_paragraph on Paragraph {\n href\n layout\n metadata {\n id\n originalHeight\n originalWidth\n focusPercentX\n focusPercentY\n alt\n __typename\n }\n ...Markups_paragraph\n ...ParagraphRefsMapContext_paragraph\n ...PostAnnotationsMarker_paragraph\n __typename\n id\n}\n\nfragment Markups_paragraph on Paragraph {\n name\n text\n hasDropCap\n dropCapImage {\n ...MarkupNode_data_dropCapImage\n __typename\n id\n }\n markups {\n type\n start\n end\n href\n anchorType\n userId\n linkMetadata {\n httpStatus\n __typename\n }\n __typename\n }\n __typename\n id\n}\n\nfragment MarkupNode_data_dropCapImage on ImageMetadata {\n ...DropCap_image\n __typename\n id\n}\n\nfragment DropCap_image on ImageMetadata {\n id\n originalHeight\n originalWidth\n __typename\n}\n\nfragment ParagraphRefsMapContext_paragraph on Paragraph {\n id\n name\n text\n __typename\n}\n\nfragment PostAnnotationsMarker_paragraph on Paragraph {\n ...PostViewNoteCard_paragraph\n __typename\n id\n}\n\nfragment PostViewNoteCard_paragraph on Paragraph {\n name\n __typename\n id\n}\n\nfragment TextParagraph_paragraph on Paragraph {\n type\n hasDropCap\n codeBlockMetadata {\n mode\n lang\n __typename\n }\n ...Markups_paragraph\n ...ParagraphRefsMapContext_paragraph\n __typename\n id\n}\n\nfragment IframeParagraph_paragraph on Paragraph {\n iframe {\n mediaResource {\n id\n iframeSrc\n iframeHeight\n iframeWidth\n title\n __typename\n }\n __typename\n }\n layout\n ...getEmbedlyCardUrlParams_paragraph\n ...Markups_paragraph\n __typename\n id\n}\n\nfragment getEmbedlyCardUrlParams_paragraph on Paragraph {\n type\n iframe {\n mediaResource {\n iframeSrc\n __typename\n }\n __typename\n }\n __typename\n id\n}\n\nfragment MixtapeParagraph_paragraph on Paragraph {\n type\n mixtapeMetadata {\n href\n mediaResource {\n mediumCatalog {\n id\n __typename\n }\n __typename\n }\n __typename\n }\n ...GenericMixtapeParagraph_paragraph\n __typename\n id\n}\n\nfragment GenericMixtapeParagraph_paragraph on Paragraph {\n text\n mixtapeMetadata {\n href\n thumbnailImageId\n __typename\n }\n markups {\n start\n end\n type\n href\n __typename\n }\n __typename\n id\n}\n\nfragment CodeBlockParagraph_paragraph on Paragraph {\n codeBlockMetadata {\n lang\n mode\n __typename\n }\n __typename\n id\n}\n\nfragment normalizedBodyModel_richText on RichText {\n paragraphs {\n markups {\n type\n __typename\n }\n codeBlockMetadata {\n lang\n mode\n __typename\n }\n ...getParagraphHighlights_paragraph\n ...getParagraphPrivateNotes_paragraph\n __typename\n }\n sections {\n startIndex\n ...getSectionEndIndex_section\n __typename\n }\n ...getParagraphStyles_richText\n ...getParagraphSpaces_richText\n __typename\n}\n\nfragment getParagraphHighlights_paragraph on Paragraph {\n name\n __typename\n id\n}\n\nfragment getParagraphPrivateNotes_paragraph on Paragraph {\n name\n __typename\n id\n}\n\nfragment getSectionEndIndex_section on Section {\n startIndex\n __typename\n}\n\nfragment getParagraphStyles_richText on RichText {\n paragraphs {\n text\n type\n __typename\n }\n sections {\n ...getSectionEndIndex_section\n __typename\n }\n __typename\n}\n\nfragment getParagraphSpaces_richText on RichText {\n paragraphs {\n layout\n metadata {\n originalHeight\n originalWidth\n id\n __typename\n }\n type\n ...paragraphExtendsImageGrid_paragraph\n __typename\n }\n ...getSeriesParagraphTopSpacings_richText\n ...getPostParagraphTopSpacings_richText\n __typename\n}\n\nfragment paragraphExtendsImageGrid_paragraph on Paragraph {\n layout\n type\n __typename\n id\n}\n\nfragment getSeriesParagraphTopSpacings_richText on RichText {\n paragraphs {\n id\n __typename\n }\n sections {\n startIndex\n __typename\n }\n __typename\n}\n\nfragment getPostParagraphTopSpacings_richText on RichText {\n paragraphs {\n layout\n text\n codeBlockMetadata {\n lang\n mode\n __typename\n }\n __typename\n }\n sections {\n startIndex\n __typename\n }\n __typename\n}\n"
|
51
50
|
}
|
52
51
|
]
|
53
52
|
|
data/lib/Request.rb
CHANGED
@@ -22,34 +22,40 @@ class Request
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
25
|
+
begin
|
26
|
+
response = https.request(request)
|
27
|
+
# 3XX Redirect
|
28
|
+
if response.code.to_i >= 300 && response.code.to_i <= 399 && !response['location'].nil? && response['location'] != ''
|
29
|
+
if retryCount >= 10
|
30
|
+
raise "Error: Retry limit reached. path: #{url}"
|
31
|
+
else
|
32
|
+
location = response['location']
|
33
|
+
if !location.match? /^(http)/
|
34
|
+
location = "#{uri.scheme}://#{uri.host}#{location}"
|
35
|
+
end
|
36
|
+
response = self.URL(location, method, data)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue
|
40
|
+
|
38
41
|
end
|
42
|
+
|
39
43
|
response
|
40
44
|
end
|
41
45
|
|
42
46
|
def self.html(response)
|
43
|
-
|
44
|
-
|
45
|
-
|
47
|
+
if response.nil? || (response && response.code.to_i != 200)
|
48
|
+
nil
|
49
|
+
else
|
46
50
|
Nokogiri::HTML(response.read_body)
|
51
|
+
end
|
47
52
|
end
|
48
53
|
|
49
54
|
def self.body(response)
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
if response.nil? || (response && response.code.to_i != 200)
|
56
|
+
nil
|
57
|
+
else
|
53
58
|
response.read_body
|
59
|
+
end
|
54
60
|
end
|
55
61
|
end
|
data/lib/ZMediumFetcher.rb
CHANGED
@@ -26,6 +26,14 @@ require "Request"
|
|
26
26
|
require "Post"
|
27
27
|
require "User"
|
28
28
|
require 'date'
|
29
|
+
require "uri"
|
30
|
+
|
31
|
+
module URI
|
32
|
+
def self.decode url
|
33
|
+
url ? URI.decode_www_form_component(url).gsub(" ", "%20") : ""
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
29
37
|
|
30
38
|
class ZMediumFetcher
|
31
39
|
|
@@ -128,7 +136,7 @@ class ZMediumFetcher
|
|
128
136
|
imagePathPolicy = PathPolicy.new(postPathPolicy.getAbsolutePath("assets"), "assets")
|
129
137
|
end
|
130
138
|
|
131
|
-
progress.postPath = postPath
|
139
|
+
progress.postPath = URI.decode(postPath)
|
132
140
|
progress.message = "Downloading Post..."
|
133
141
|
progress.printLog()
|
134
142
|
|
@@ -154,6 +162,7 @@ class ZMediumFetcher
|
|
154
162
|
previousParagraph = nil
|
155
163
|
preTypeParagraphs = []
|
156
164
|
sourceParagraphs.each do |sourcParagraph|
|
165
|
+
return if (!sourcParagraph || !postID)
|
157
166
|
paragraph = Paragraph.new(sourcParagraph, postID)
|
158
167
|
if OLIParser.isOLI(paragraph)
|
159
168
|
oliIndex += 1
|
@@ -223,8 +232,7 @@ class ZMediumFetcher
|
|
223
232
|
progress.printLog()
|
224
233
|
|
225
234
|
postWithDatePath = "#{postInfo.firstPublishedAt.strftime("%Y-%m-%d")}-#{postPath}"
|
226
|
-
|
227
|
-
absolutePath = postPathPolicy.getAbsolutePath("#{postWithDatePath}.md")
|
235
|
+
absolutePath = URI.decode(postPathPolicy.getAbsolutePath("#{postWithDatePath}")) + ".md"
|
228
236
|
|
229
237
|
fileLatestPublishedAt = nil
|
230
238
|
|
@@ -287,7 +295,7 @@ class ZMediumFetcher
|
|
287
295
|
|
288
296
|
def downloadPostsByUsername(username, pathPolicy)
|
289
297
|
progress.username = username
|
290
|
-
progress.message = "Fetching
|
298
|
+
progress.message = "Fetching posts..."
|
291
299
|
progress.printLog()
|
292
300
|
|
293
301
|
userID = User.convertToUserIDFromUsername(username)
|
@@ -295,9 +303,6 @@ class ZMediumFetcher
|
|
295
303
|
raise "Medium's Username:#{username} not found!"
|
296
304
|
end
|
297
305
|
|
298
|
-
progress.message = "Fetching posts..."
|
299
|
-
progress.printLog()
|
300
|
-
|
301
306
|
postURLS = []
|
302
307
|
nextID = nil
|
303
308
|
begin
|
@@ -321,14 +326,19 @@ class ZMediumFetcher
|
|
321
326
|
downloadPathPolicy = PathPolicy.new(pathPolicy.getAbsolutePath("users/#{username}"), pathPolicy.getRelativePath("users/#{username}"))
|
322
327
|
end
|
323
328
|
|
324
|
-
index =
|
329
|
+
index = 1
|
325
330
|
postURLS.each do |postURL|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
331
|
+
begin
|
332
|
+
# todo: unless File.exists? Post.getPostPathFromPostURLString(postURL) +".md"
|
333
|
+
downloadPost(postURL, downloadPathPolicy)
|
334
|
+
rescue => e
|
335
|
+
puts e
|
336
|
+
end
|
337
|
+
|
338
|
+
index += 1
|
339
|
+
progress.currentPostIndex = index
|
340
|
+
progress.message = "Downloading posts..."
|
341
|
+
progress.printLog()
|
332
342
|
end
|
333
343
|
|
334
344
|
progress.message = "All posts has been downloaded!, Total posts: #{postURLS.length}"
|
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
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ZhgChgLi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|