automatic 26.08 → 26.09
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/README.md +80 -46
- data/VERSION +1 -1
- data/assets/siteinfo/items_all.json +60300 -52138
- data/automatic.gemspec +4 -3
- data/bin/automatic +1 -1
- data/doc/AI_TUTORIAL.md +64 -40
- data/doc/BASIC_DESIGN.md +31 -0
- data/doc/DEPLOYMENT.md +53 -47
- data/doc/PLUGINS.md +231 -91
- data/doc/POLICY.md +149 -44
- data/doc/QUICKSTART.md +19 -15
- data/doc/RELEASING.md +20 -7
- data/doc/REQUIREMENTS.md +40 -10
- data/doc/VERSIONS +112 -54
- data/lib/automatic/cli.rb +40 -18
- data/lib/automatic/environment.rb +1 -1
- data/lib/automatic/feed_maker.rb +57 -18
- data/lib/automatic/feed_parser.rb +1 -1
- data/lib/automatic/http.rb +1 -1
- data/lib/automatic/log.rb +1 -1
- data/lib/automatic/pipeline.rb +15 -5
- data/lib/automatic/recipe.rb +45 -1
- data/lib/automatic/version.rb +3 -3
- data/lib/automatic.rb +18 -3
- data/plugins/custom_feed/web.rb +1 -1
- data/plugins/filter/absolute_uri.rb +1 -1
- data/plugins/filter/batch.rb +97 -0
- data/plugins/filter/claude.rb +1 -1
- data/plugins/filter/clear.rb +1 -1
- data/plugins/filter/description_link.rb +20 -3
- data/plugins/filter/full_feed.rb +28 -16
- data/plugins/filter/gemini.rb +1 -1
- data/plugins/filter/ignore.rb +1 -1
- data/plugins/filter/image.rb +1 -1
- data/plugins/filter/image_source.rb +20 -3
- data/plugins/filter/join.rb +4 -6
- data/plugins/filter/kimi.rb +216 -0
- data/plugins/filter/limit.rb +57 -0
- data/plugins/filter/open_ai.rb +1 -1
- data/plugins/filter/present.rb +75 -0
- data/plugins/filter/sakura_ai.rb +1 -1
- data/plugins/filter/sanitize.rb +1 -1
- data/plugins/filter/sort.rb +1 -1
- data/plugins/filter/tumblr_resize.rb +1 -1
- data/plugins/notify/ikachan.rb +1 -1
- data/plugins/provide/fluentd.rb +1 -1
- data/plugins/publish/amazon_s3.rb +9 -3
- data/plugins/publish/console.rb +1 -1
- data/plugins/publish/fluentd.rb +1 -1
- data/plugins/publish/hatena_bookmark.rb +1 -1
- data/plugins/publish/markdown.rb +1 -1
- data/plugins/publish/memcached.rb +1 -1
- data/plugins/store/digest.rb +1 -1
- data/plugins/store/file.rb +11 -3
- data/plugins/store/full_text.rb +9 -13
- data/plugins/store/permalink.rb +1 -1
- data/plugins/subscription/feed.rb +1 -1
- data/plugins/subscription/link.rb +1 -1
- data/plugins/subscription/text.rb +13 -4
- data/plugins/subscription/tumblr.rb +1 -1
- data/plugins/subscription/xml.rb +1 -1
- metadata +6 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Name:: Automatic::Plugin::Filter::Limit
|
|
3
|
+
# Description:: Limit the number of items passed by the whole pipeline.
|
|
4
|
+
# Author: id774 (More info: https://id774.net)
|
|
5
|
+
# Source Code:: https://github.com/id774/automaticruby
|
|
6
|
+
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
7
|
+
# Contact:: idnanashi@gmail.com
|
|
8
|
+
# Created:: Aug 24, 2026
|
|
9
|
+
# Updated:: Aug 24, 2026
|
|
10
|
+
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.
|
|
11
|
+
|
|
12
|
+
module Automatic::Plugin
|
|
13
|
+
class FilterLimit
|
|
14
|
+
def initialize(config, pipeline = [])
|
|
15
|
+
@config = config || {}
|
|
16
|
+
@pipeline = pipeline
|
|
17
|
+
@max_items = validated_max_items
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Selects items in feed order, item order, up to max_items shared across the
|
|
21
|
+
# whole pipeline rather than reset per feed. A feed that contributed no item
|
|
22
|
+
# is dropped from the output; the walk stops as soon as the limit is met.
|
|
23
|
+
def run
|
|
24
|
+
remaining = @max_items
|
|
25
|
+
returned = []
|
|
26
|
+
|
|
27
|
+
@pipeline.each do |feeds|
|
|
28
|
+
next if feeds.nil?
|
|
29
|
+
break if remaining <= 0
|
|
30
|
+
|
|
31
|
+
selected = feeds.items.first(remaining)
|
|
32
|
+
next if selected.empty?
|
|
33
|
+
|
|
34
|
+
returned << Automatic::FeedMaker.create_pipeline(selected)
|
|
35
|
+
remaining -= selected.size
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
returned
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def validated_max_items
|
|
44
|
+
value = begin
|
|
45
|
+
Integer(@config['max_items'].to_s, 10)
|
|
46
|
+
rescue ArgumentError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if value.nil? || value < 1
|
|
51
|
+
raise ArgumentError, 'FilterLimit needs max_items to be a positive integer'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
value
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/plugins/filter/open_ai.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Filter::OpenAI
|
|
3
3
|
# Description:: Replace each item's description with what the OpenAI API answers.
|
|
4
|
-
# Author: id774 (More info:
|
|
4
|
+
# Author: id774 (More info: https://id774.net)
|
|
5
5
|
# Source Code:: https://github.com/id774/automaticruby
|
|
6
6
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
7
7
|
# Contact:: idnanashi@gmail.com
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Name:: Automatic::Plugin::Filter::Present
|
|
3
|
+
# Description:: Keep items whose configured fields are all present.
|
|
4
|
+
# Author: id774 (More info: https://id774.net)
|
|
5
|
+
# Source Code:: https://github.com/id774/automaticruby
|
|
6
|
+
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
7
|
+
# Contact:: idnanashi@gmail.com
|
|
8
|
+
# Created:: Aug 24, 2026
|
|
9
|
+
# Updated:: Aug 24, 2026
|
|
10
|
+
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.
|
|
11
|
+
|
|
12
|
+
module Automatic::Plugin
|
|
13
|
+
class FilterPresent
|
|
14
|
+
# The item fields presence may be checked over. `date` is not one, being
|
|
15
|
+
# absent from a plain summary as often as not, and `enclosure` is not
|
|
16
|
+
# either, being a structure rather than a value.
|
|
17
|
+
FIELDS = %w[title link description author comments source content_encoded].freeze
|
|
18
|
+
|
|
19
|
+
def initialize(config, pipeline = [])
|
|
20
|
+
@config = config || {}
|
|
21
|
+
@pipeline = pipeline
|
|
22
|
+
@fields = validated_fields
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Keeps only the items where every configured field is present. A feed
|
|
26
|
+
# that kept nothing is dropped from the output rather than passed on empty.
|
|
27
|
+
def run
|
|
28
|
+
@pipeline.each_with_object([]) do |feeds, returned|
|
|
29
|
+
next if feeds.nil?
|
|
30
|
+
|
|
31
|
+
survivors = feeds.items.select { |item| present?(item) }
|
|
32
|
+
returned << Automatic::FeedMaker.create_pipeline(survivors) unless survivors.empty?
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def validated_fields
|
|
39
|
+
given = @config['fields']
|
|
40
|
+
raise ArgumentError, 'FilterPresent takes fields as a list' unless given.is_a?(Array)
|
|
41
|
+
|
|
42
|
+
names = given.map(&:to_s)
|
|
43
|
+
raise ArgumentError, 'FilterPresent needs a non-empty fields list' if names.empty?
|
|
44
|
+
|
|
45
|
+
unknown = names - FIELDS
|
|
46
|
+
unless unknown.empty?
|
|
47
|
+
raise ArgumentError,
|
|
48
|
+
"FilterPresent cannot inspect #{unknown.join(', ')}; " \
|
|
49
|
+
"the fields are #{FIELDS.join(', ')}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
duplicated = names.tally.select { |_name, count| count > 1 }.keys
|
|
53
|
+
raise ArgumentError, "FilterPresent was given #{duplicated.join(', ')} twice" unless duplicated.empty?
|
|
54
|
+
|
|
55
|
+
names
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def present?(item)
|
|
59
|
+
@fields.all? { |field| field_present?(item, field) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# A field an item does not carry, or whose value is nil, is absent. A
|
|
63
|
+
# field whose value answers #content -- a parsed source or enclosure -- is
|
|
64
|
+
# judged on that content rather than on the element itself.
|
|
65
|
+
def field_present?(item, field)
|
|
66
|
+
return false unless item.respond_to?(field)
|
|
67
|
+
|
|
68
|
+
value = item.public_send(field)
|
|
69
|
+
return false if value.nil?
|
|
70
|
+
|
|
71
|
+
value = value.content if value.respond_to?(:content)
|
|
72
|
+
!value.to_s.strip.empty?
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
data/plugins/filter/sakura_ai.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Filter::SakuraAI
|
|
3
3
|
# Description:: Replace each item's description with what the Sakura AI Engine answers.
|
|
4
|
-
# Author: id774 (More info:
|
|
4
|
+
# Author: id774 (More info: https://id774.net)
|
|
5
5
|
# Source Code:: https://github.com/id774/automaticruby
|
|
6
6
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
7
7
|
# Contact:: idnanashi@gmail.com
|
data/plugins/filter/sanitize.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Filter::Sanitize
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/filter/sort.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Filter::Sort
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Filter::TumblrResize
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/notify/ikachan.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Notify::Ikachan
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/provide/fluentd.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Provide::Fluentd
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Publish::AmazonS3
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
7
7
|
# Created:: Feb 24, 2014
|
|
8
|
-
# Updated::
|
|
8
|
+
# Updated:: Sep 9, 2026
|
|
9
9
|
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.
|
|
10
10
|
|
|
11
11
|
module Automatic::Plugin
|
|
12
12
|
class PublishAmazonS3
|
|
13
13
|
require 'uri'
|
|
14
14
|
|
|
15
|
+
FILE_URI_ESCAPER = URI::RFC2396_Parser.new
|
|
16
|
+
|
|
15
17
|
def initialize(config, pipeline = [])
|
|
16
18
|
@config = config || {}
|
|
17
19
|
@pipeline = pipeline
|
|
@@ -35,7 +37,7 @@ module Automatic::Plugin
|
|
|
35
37
|
|
|
36
38
|
uri = URI.parse(feed.link)
|
|
37
39
|
if uri.scheme == 'file'
|
|
38
|
-
upload(uri
|
|
40
|
+
upload(file_path(uri))
|
|
39
41
|
else
|
|
40
42
|
Automatic::Log.puts('warn', 'Skip feed due to uri scheme is not file.')
|
|
41
43
|
end
|
|
@@ -44,6 +46,10 @@ module Automatic::Plugin
|
|
|
44
46
|
"Error detected with #{feed.link} in uploading AmazonS3: #{e.message}")
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
def file_path(uri)
|
|
50
|
+
FILE_URI_ESCAPER.unescape(uri.path.to_s)
|
|
51
|
+
end
|
|
52
|
+
|
|
47
53
|
def upload(path)
|
|
48
54
|
key = target_key(path)
|
|
49
55
|
File.open(path, 'rb') { |body| s3.put_object(bucket: bucket, key: key, body: body) } unless test?
|
data/plugins/publish/console.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Publish::Console
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/publish/fluentd.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Publish::Fluentd
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Publish::HatenaBookmark
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/publish/markdown.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Publish::Markdown
|
|
3
3
|
# Description:: Render the pipeline as a Markdown document, to a file or to standard output.
|
|
4
|
-
# Author: id774 (More info:
|
|
4
|
+
# Author: id774 (More info: https://id774.net)
|
|
5
5
|
# Source Code:: https://github.com/id774/automaticruby
|
|
6
6
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
7
7
|
# Contact:: idnanashi@gmail.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Publish::Memcached
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/store/digest.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Store::Digest
|
|
3
3
|
# Description:: Drop items whose content has been seen before, by SHA-256 digest.
|
|
4
|
-
# Author: id774 (More info:
|
|
4
|
+
# Author: id774 (More info: https://id774.net)
|
|
5
5
|
# Source Code:: https://github.com/id774/automaticruby
|
|
6
6
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
7
7
|
# Contact:: idnanashi@gmail.com
|
data/plugins/store/file.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Store::File
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
7
7
|
# Created:: Feb 28, 2012
|
|
8
|
-
# Updated::
|
|
8
|
+
# Updated:: Sep 9, 2026
|
|
9
9
|
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.
|
|
10
10
|
|
|
11
11
|
require 'fileutils'
|
|
@@ -18,6 +18,8 @@ module Automatic::Plugin
|
|
|
18
18
|
# everything else uses and is accepted as well.
|
|
19
19
|
S3_SCHEMES = %w[s3 s3n].freeze
|
|
20
20
|
|
|
21
|
+
FILE_URI_ESCAPER = URI::RFC2396_Parser.new
|
|
22
|
+
|
|
21
23
|
def initialize(config, pipeline = [])
|
|
22
24
|
@config = config || {}
|
|
23
25
|
@pipeline = pipeline
|
|
@@ -69,7 +71,13 @@ module Automatic::Plugin
|
|
|
69
71
|
uri = URI.parse(url)
|
|
70
72
|
path = S3_SCHEMES.include?(uri.scheme) ? from_s3(uri) : download(url)
|
|
71
73
|
Automatic::Log.puts('info', "Saved File: #{path}")
|
|
72
|
-
|
|
74
|
+
file_uri(path)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def file_uri(path)
|
|
78
|
+
absolute_path = File.absolute_path(path.to_s)
|
|
79
|
+
escaped_path = FILE_URI_ESCAPER.escape(absolute_path)
|
|
80
|
+
URI::Generic.build(scheme: 'file', path: escaped_path).to_s
|
|
73
81
|
end
|
|
74
82
|
|
|
75
83
|
# Only HTTP and HTTPS are fetched: a link arrives from a feed, which is to
|
data/plugins/store/full_text.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Store::FullText
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
7
7
|
# Created:: Feb 26, 2012
|
|
8
|
-
# Updated::
|
|
8
|
+
# Updated:: Sep 12, 2026
|
|
9
9
|
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.
|
|
10
10
|
|
|
11
11
|
require_relative 'database'
|
|
@@ -46,18 +46,14 @@ module Automatic::Plugin
|
|
|
46
46
|
# what is new.
|
|
47
47
|
def run
|
|
48
48
|
for_each_new_feed do |feed|
|
|
49
|
+
Blog.create!(
|
|
50
|
+
title: feed.title,
|
|
51
|
+
link: feed.link,
|
|
52
|
+
description: feed.description,
|
|
53
|
+
content: feed.content_encoded,
|
|
54
|
+
created_at: Time.now.strftime('%Y/%m/%d %X')
|
|
55
|
+
)
|
|
49
56
|
Automatic::Log.puts('info', "Saving FullText: #{feed.link}")
|
|
50
|
-
begin
|
|
51
|
-
Blog.create(
|
|
52
|
-
title: feed.title,
|
|
53
|
-
link: feed.link,
|
|
54
|
-
description: feed.description,
|
|
55
|
-
content: feed.content_encoded,
|
|
56
|
-
created_at: Time.now.strftime('%Y/%m/%d %X')
|
|
57
|
-
)
|
|
58
|
-
rescue StandardError => e
|
|
59
|
-
Automatic::Log.puts('warn', "Skip feed due to fault in save: #{e.message}")
|
|
60
|
-
end
|
|
61
57
|
end
|
|
62
58
|
end
|
|
63
59
|
end
|
data/plugins/store/permalink.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Store::Permalink
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::SubscriptionFeed
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Subscription::Link
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
|
7
7
|
# Created:: May 6, 2013
|
|
8
|
-
# Updated::
|
|
8
|
+
# Updated:: Sep 8, 2026
|
|
9
9
|
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.
|
|
10
10
|
|
|
11
11
|
module Automatic::Plugin
|
|
@@ -41,13 +41,22 @@ module Automatic::Plugin
|
|
|
41
41
|
Array(@config['feeds']).map { |feed| Automatic::FeedMaker.generate_feed(feed) }
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# Tab separated, read as UTF-8, and `~` expanded.
|
|
44
|
+
# Tab separated, read as UTF-8, and `~` expanded. Empty columns stay in
|
|
45
|
+
# position and an all-empty row produces no item.
|
|
45
46
|
def files
|
|
46
47
|
Array(@config['files']).flat_map do |path|
|
|
47
|
-
File.foreach(File.expand_path(path), encoding: 'UTF-8').
|
|
48
|
-
|
|
48
|
+
File.foreach(File.expand_path(path), encoding: 'UTF-8').filter_map do |line|
|
|
49
|
+
fields = tsv_fields(line)
|
|
50
|
+
Automatic::FeedMaker.generate_feed(fields) unless fields.nil?
|
|
49
51
|
end
|
|
50
52
|
end
|
|
51
53
|
end
|
|
54
|
+
|
|
55
|
+
def tsv_fields(line)
|
|
56
|
+
values = line.chomp.split("\t", -1).first(COLUMNS.length)
|
|
57
|
+
fields = COLUMNS.zip(values).to_h
|
|
58
|
+
fields.delete_if { |_field, value| value.nil? || value.empty? }
|
|
59
|
+
fields unless fields.empty?
|
|
60
|
+
end
|
|
52
61
|
end
|
|
53
62
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Subscription::Tumblr
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
data/plugins/subscription/xml.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Name:: Automatic::Plugin::Subscription::Xml
|
|
3
|
-
# Author: id774 (More info:
|
|
3
|
+
# Author: id774 (More info: https://id774.net)
|
|
4
4
|
# Source Code:: https://github.com/id774/automaticruby
|
|
5
5
|
# License:: The GPL version 3, or LGPL version 3 (Dual License).
|
|
6
6
|
# Contact:: idnanashi@gmail.com
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: automatic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '26.
|
|
4
|
+
version: '26.09'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- id774
|
|
@@ -223,6 +223,7 @@ files:
|
|
|
223
223
|
- plugins/custom_feed/web.rb
|
|
224
224
|
- plugins/filter/absolute_uri.rb
|
|
225
225
|
- plugins/filter/accept.rb
|
|
226
|
+
- plugins/filter/batch.rb
|
|
226
227
|
- plugins/filter/claude.rb
|
|
227
228
|
- plugins/filter/clear.rb
|
|
228
229
|
- plugins/filter/description_link.rb
|
|
@@ -233,8 +234,11 @@ files:
|
|
|
233
234
|
- plugins/filter/image.rb
|
|
234
235
|
- plugins/filter/image_source.rb
|
|
235
236
|
- plugins/filter/join.rb
|
|
237
|
+
- plugins/filter/kimi.rb
|
|
238
|
+
- plugins/filter/limit.rb
|
|
236
239
|
- plugins/filter/one.rb
|
|
237
240
|
- plugins/filter/open_ai.rb
|
|
241
|
+
- plugins/filter/present.rb
|
|
238
242
|
- plugins/filter/rand.rb
|
|
239
243
|
- plugins/filter/sakura_ai.rb
|
|
240
244
|
- plugins/filter/sanitize.rb
|
|
@@ -285,7 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
285
289
|
- !ruby/object:Gem::Version
|
|
286
290
|
version: '0'
|
|
287
291
|
requirements: []
|
|
288
|
-
rubygems_version: 4.0.
|
|
292
|
+
rubygems_version: 4.0.16
|
|
289
293
|
specification_version: 4
|
|
290
294
|
summary: Automatic Ruby
|
|
291
295
|
test_files: []
|