skriptorium 0.1.1 → 0.1.2
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/Gemfile.lock +3 -1
- data/README.md +1 -0
- data/lib/skriptorium/article.rb +2 -1
- data/lib/skriptorium/base_source.rb +66 -4
- data/lib/skriptorium/version.rb +1 -1
- metadata +17 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d5f42e3d10dfaa5a21e7af891d70b73137e69a6b77ea03500316b4ac6d740a36
|
|
4
|
+
data.tar.gz: d19d84b93725ed0956322b4a39af3035bb02dcefe40c552c01b36eccdf345835
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6dff3c08ecdcae0bfb5da97230d0c5fbc4bd6439131ecdeae29cda11bfd1ba6023d8d4983371aa58892c180f5fed2eeacc9b80819ede1c5d2890479f56d7cfc1
|
|
7
|
+
data.tar.gz: bfc8d61ac8f20dc6c398cdf847f0046f801955b36d7f3ecfc174e403883c7c39aa220c31b2d53c8f0007d71f89b90a09c2a39f5c1a322644712a188781c31ecd
|
data/Gemfile.lock
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
skriptorium (0.1.
|
|
4
|
+
skriptorium (0.1.2)
|
|
5
5
|
activesupport (~> 8.1)
|
|
6
6
|
base64 (~> 0.3)
|
|
7
7
|
faraday (~> 2.14)
|
|
8
|
+
fastimage (~> 2.4)
|
|
8
9
|
front_matter_parser (~> 1.0)
|
|
9
10
|
redcarpet (~> 3.6)
|
|
10
11
|
reverse_markdown (~> 3.0)
|
|
@@ -44,6 +45,7 @@ GEM
|
|
|
44
45
|
logger
|
|
45
46
|
faraday-net_http (3.4.4)
|
|
46
47
|
net-http (~> 0.5)
|
|
48
|
+
fastimage (2.4.1)
|
|
47
49
|
front_matter_parser (1.0.1)
|
|
48
50
|
hashdiff (1.2.1)
|
|
49
51
|
i18n (1.15.2)
|
data/README.md
CHANGED
data/lib/skriptorium/article.rb
CHANGED
|
@@ -4,7 +4,8 @@ require 'russian'
|
|
|
4
4
|
|
|
5
5
|
module Skriptorium
|
|
6
6
|
class Article
|
|
7
|
-
attr_reader :id, :title, :content, :tags, :canonical_url, :published_at, :
|
|
7
|
+
attr_reader :id, :title, :content, :tags, :canonical_url, :published_at, :slug
|
|
8
|
+
attr_accessor :cover_image
|
|
8
9
|
|
|
9
10
|
FRONT_MATTER_RX = /---([\s\S]*?)---/.freeze
|
|
10
11
|
FRONT_MATTER_LINE_RX = /^(?<key>\w+)\s*:\s*(?<value>.*)/.freeze
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
require 'fastimage'
|
|
2
|
+
|
|
1
3
|
module Skriptorium
|
|
2
4
|
class BaseSource
|
|
5
|
+
IMAGE_EXTENSIONS = %w[.png .jpg .jpeg].freeze
|
|
6
|
+
MIN_IMAGE_WIDTH = 100
|
|
7
|
+
|
|
3
8
|
attr_reader :config, :limit
|
|
4
9
|
|
|
5
10
|
def initialize(config)
|
|
@@ -10,12 +15,14 @@ module Skriptorium
|
|
|
10
15
|
|
|
11
16
|
# @return [Array<Article>]
|
|
12
17
|
def fetch
|
|
13
|
-
raise NotImplementedError, "#{self.class} must implement #
|
|
18
|
+
raise NotImplementedError, "#{self.class} must implement #fetch"
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
def fetch_latest
|
|
17
|
-
|
|
18
|
-
filtered
|
|
22
|
+
stream = fetch
|
|
23
|
+
filtered = apply_filter(stream)
|
|
24
|
+
enriched = filtered.map { |article| enrich_article(article) }
|
|
25
|
+
enriched.first(@limit)
|
|
19
26
|
end
|
|
20
27
|
|
|
21
28
|
def apply_filter(stream)
|
|
@@ -32,9 +39,64 @@ module Skriptorium
|
|
|
32
39
|
raise "Invalid filter #{name}: #{opts.inspect}"
|
|
33
40
|
end
|
|
34
41
|
end
|
|
35
|
-
# puts " article \"#{article.title}\" pass=#{pass}"
|
|
36
42
|
pass
|
|
37
43
|
end
|
|
38
44
|
end
|
|
45
|
+
|
|
46
|
+
def enrich_article(article)
|
|
47
|
+
if article.cover_image.nil? || article.cover_image.to_s.strip.empty?
|
|
48
|
+
found = extract_cover_image(article.content)
|
|
49
|
+
article.cover_image = found if found
|
|
50
|
+
end
|
|
51
|
+
article
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def extract_cover_image(content)
|
|
55
|
+
return nil if content.nil? || content.to_s.strip.empty?
|
|
56
|
+
|
|
57
|
+
# 1. HTML img tags first — they may have width/height attributes
|
|
58
|
+
content.scan(/<img[^>]*>/i).each do |img_tag|
|
|
59
|
+
src = extract_src(img_tag)
|
|
60
|
+
next unless src && image_url?(src)
|
|
61
|
+
return src if image_large_enough?(src)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# 2. Markdown images
|
|
65
|
+
content.scan(/!\[.*?\]\((.+?)\)/).each do |match|
|
|
66
|
+
url = match[0].split(' ').first
|
|
67
|
+
next unless image_url?(url)
|
|
68
|
+
return url if image_large_enough?(url)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def image_url?(url)
|
|
77
|
+
return false if url.nil? || url.empty?
|
|
78
|
+
|
|
79
|
+
ext = File.extname(url.split('?').first.split('#').first).downcase
|
|
80
|
+
IMAGE_EXTENSIONS.include?(ext)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def extract_src(img_tag)
|
|
84
|
+
img_tag.match(/src=["']([^"']+)["']/i)&.[](1)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def image_large_enough?(url)
|
|
88
|
+
check_remote_width(url)
|
|
89
|
+
rescue StandardError
|
|
90
|
+
false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def check_remote_width(url)
|
|
94
|
+
size = FastImage.size(url)
|
|
95
|
+
return false unless size && size.is_a?(Array) && size.length >= 2
|
|
96
|
+
|
|
97
|
+
size[0] > MIN_IMAGE_WIDTH
|
|
98
|
+
rescue WebMock::NetConnectNotAllowedError, StandardError
|
|
99
|
+
false
|
|
100
|
+
end
|
|
39
101
|
end
|
|
40
102
|
end
|
data/lib/skriptorium/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: skriptorium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samoilenko Yuri
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -170,6 +169,20 @@ dependencies:
|
|
|
170
169
|
- - "~>"
|
|
171
170
|
- !ruby/object:Gem::Version
|
|
172
171
|
version: '1.0'
|
|
172
|
+
- !ruby/object:Gem::Dependency
|
|
173
|
+
name: fastimage
|
|
174
|
+
requirement: !ruby/object:Gem::Requirement
|
|
175
|
+
requirements:
|
|
176
|
+
- - "~>"
|
|
177
|
+
- !ruby/object:Gem::Version
|
|
178
|
+
version: '2.4'
|
|
179
|
+
type: :runtime
|
|
180
|
+
prerelease: false
|
|
181
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - "~>"
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '2.4'
|
|
173
186
|
description: Skriptorium fetches new articles from a single source and publishes them
|
|
174
187
|
to multiple destinations such as dev.to, hashnode, GitHub Pages, Blogger and local
|
|
175
188
|
files.
|
|
@@ -208,7 +221,6 @@ homepage: https://github.com/kinnalru/skriptorium
|
|
|
208
221
|
licenses:
|
|
209
222
|
- MIT
|
|
210
223
|
metadata: {}
|
|
211
|
-
post_install_message:
|
|
212
224
|
rdoc_options: []
|
|
213
225
|
require_paths:
|
|
214
226
|
- lib
|
|
@@ -223,8 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
223
235
|
- !ruby/object:Gem::Version
|
|
224
236
|
version: '0'
|
|
225
237
|
requirements: []
|
|
226
|
-
rubygems_version: 3.
|
|
227
|
-
signing_key:
|
|
238
|
+
rubygems_version: 3.6.9
|
|
228
239
|
specification_version: 4
|
|
229
240
|
summary: Personal CLI tool for automatic article publishing.
|
|
230
241
|
test_files: []
|