Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions doc/PLUGINS.md
Original file line number Diff line number Diff line change
Expand Up @@ -669,10 +669,13 @@ no network, which makes it the plugin to test a Recipe's later half with.
| `titles` | sequence | One item per title, no link |
| `urls` | sequence | One item per URL, no title |
| `feeds` | sequence | Mappings of `title`, `url`, `description`, `author`, `comments` |
| `files` | sequence | TSV paths; columns are title, url, description, author, comments |
| `files` | sequence | UTF-8 TSV paths; positional columns are title, url, description, author, comments |

The TSV separator is a tab, the file is read as UTF-8, and `~` is expanded. Any
combination of the four keys may be given.
The TSV separator is a tab and `~` is expanded. Empty columns supply no value
for that field without shifting later columns; blank or all-empty rows produce
no item. Only the first five columns are used. Line endings are removed before
splitting, but other field whitespace is preserved. Any combination of the four
keys may be given.

#### SubscriptionTumblr — **Supported (external)**

Expand Down
1 change: 1 addition & 0 deletions doc/VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ v26.09 (Release Date: TBD)
dependency from load failures, and preflight-validate Recipe plugins.
- Preserve nil-link pipeline items and remove SubscriptionText placeholder
title and link values.
- Preserve SubscriptionText TSV column positions and ignore empty input rows.

v26.08 (2026-08-22)
-------------------
Expand Down
17 changes: 13 additions & 4 deletions plugins/subscription/text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# License:: The GPL version 3, or LGPL version 3 (Dual License).
# Contact:: idnanashi@gmail.com
# Created:: May 6, 2013
# Updated:: Aug 15, 2026
# Updated:: Sep 8, 2026
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.

module Automatic::Plugin
Expand Down Expand Up @@ -41,13 +41,22 @@ def feeds
Array(@config['feeds']).map { |feed| Automatic::FeedMaker.generate_feed(feed) }
end

# Tab separated, read as UTF-8, and `~` expanded.
# Tab separated, read as UTF-8, and `~` expanded. Empty columns stay in
# position and an all-empty row produces no item.
def files
Array(@config['files']).flat_map do |path|
File.foreach(File.expand_path(path), encoding: 'UTF-8').map do |line|
Automatic::FeedMaker.generate_feed(COLUMNS.zip(line.strip.split("\t")).to_h)
File.foreach(File.expand_path(path), encoding: 'UTF-8').filter_map do |line|
fields = tsv_fields(line)
Automatic::FeedMaker.generate_feed(fields) unless fields.nil?
end
end
end

def tsv_fields(line)
values = line.chomp.split("\t", -1).first(COLUMNS.length)
fields = COLUMNS.zip(values).to_h
fields.delete_if { |_field, value| value.nil? || value.empty? }
fields unless fields.empty?
end
end
end
90 changes: 89 additions & 1 deletion spec/plugins/subscription/text_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@
# License:: The GPL version 3, or LGPL version 3 (Dual License).
# Contact:: idnanashi@gmail.com
# Created:: May 6, 2013
# Updated:: Sep 7, 2026
# Updated:: Sep 8, 2026
# Copyright:: Copyright (c) 2012-2026 Automatic Ruby Developers.

require File.expand_path(File.dirname(__FILE__) + '../../../spec_helper')

require 'subscription/text'

describe Automatic::Plugin::SubscriptionText do
def items_from_tsv(contents)
Dir.mktmpdir('automatic-subscription-text') do |dir|
path = File.join(dir, 'input.tsv')
File.write(path, contents, encoding: 'UTF-8')
Automatic::Plugin::SubscriptionText.new(
{ 'files' => [path] }
).run.flat_map(&:items)
end
end

context "with empty titles" do
subject {
Automatic::Plugin::SubscriptionText.new(
Expand Down Expand Up @@ -112,4 +122,82 @@

its(:run) { should have(1).feed }
end

it "builds a title-only item from a one-column TSV row" do
items = items_from_tsv("Title only\n")

items.should have(1).item
items.first.title.should == "Title only"
items.first.link.should be_nil
end

it "preserves a leading empty title column in a URL-only TSV row" do
items = items_from_tsv("\thttps://example.com/\r\n")

items.should have(1).item
items.first.title.should be_nil
items.first.link.should == "https://example.com/"
end

it "does not shift comments across an empty author column" do
items = items_from_tsv(
"Title\thttps://example.com/\tDescription\t\tComment\n"
)
item = items.first

items.should have(1).item
item.title.should == "Title"
item.link.should == "https://example.com/"
item.description.should == "Description"
item.author.should == ""
item.comments.should == "Comment"
end

it "accepts trailing empty TSV fields without changing earlier columns" do
items = items_from_tsv(
"Title\thttps://example.com/\tDescription\t\t\n"
)
item = items.first

items.should have(1).item
item.title.should == "Title"
item.link.should == "https://example.com/"
item.description.should == "Description"
item.author.should == ""
item.comments.should == ""
end

it "ignores blank and all-empty TSV rows" do
items = items_from_tsv(
"\n\t\t\t\t\nKept\thttps://example.com/\n"
)

items.should have(1).item
items.first.title.should == "Kept"
items.first.link.should == "https://example.com/"
end

it "ignores TSV columns after comments" do
items = items_from_tsv(
"Title\thttps://example.com/\tDescription\tAuthor\tComment\tExtra\tMore\n"
)
item = items.first

items.should have(1).item
item.title.should == "Title"
item.link.should == "https://example.com/"
item.description.should == "Description"
item.author.should == "Author"
item.comments.should == "Comment"
end

it "preserves field whitespace other than the line ending" do
items = items_from_tsv(
" Title \thttps://example.com/\t Description \n"
)
item = items.first

item.title.should == " Title "
item.description.should == " Description "
end
end
2 changes: 0 additions & 2 deletions test/integration/test_text2feed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ plugins:
description: 'aaa'
comments: 'bbb'
author: 'ccc'
files:
- 'spec/fixtures/sampleFeeds.tsv'
files:
- 'spec/fixtures/sampleFeeds.tsv'
- 'spec/fixtures/sampleFeeds2.tsv'
Expand Down
Loading