ZMediumToMarkdown 2.0.12 → 2.1.0
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/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
|