mako_rss 0.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 +7 -0
- data/.gitignore +33 -0
- data/.rspec +2 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +38 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +124 -0
- data/Rakefile +13 -0
- data/bin/mako +6 -0
- data/lib/mako/article.rb +36 -0
- data/lib/mako/cli.rb +49 -0
- data/lib/mako/commands/build.rb +33 -0
- data/lib/mako/commands/new.rb +28 -0
- data/lib/mako/commands/schedule.rb +12 -0
- data/lib/mako/commands/version.rb +11 -0
- data/lib/mako/configuration.rb +44 -0
- data/lib/mako/core.rb +81 -0
- data/lib/mako/core_ext/numeric.rb +10 -0
- data/lib/mako/core_ext/time.rb +10 -0
- data/lib/mako/core_ext.rb +4 -0
- data/lib/mako/errors.rb +25 -0
- data/lib/mako/feed.rb +29 -0
- data/lib/mako/feed_constructor.rb +71 -0
- data/lib/mako/feed_requester.rb +43 -0
- data/lib/mako/file_open_util.rb +19 -0
- data/lib/mako/html_renderer.rb +30 -0
- data/lib/mako/layouts/_feed_container.html.erb +19 -0
- data/lib/mako/mako_logger.rb +12 -0
- data/lib/mako/sass_renderer.rb +30 -0
- data/lib/mako/subscription_list_parser.rb +28 -0
- data/lib/mako/version.rb +5 -0
- data/lib/mako/view_helpers.rb +28 -0
- data/lib/mako/writer.rb +18 -0
- data/lib/mako.rb +41 -0
- data/lib/templates/Gemfile +5 -0
- data/lib/templates/config.yaml +14 -0
- data/lib/templates/sample_subscriptions/subscriptions.json +1 -0
- data/lib/templates/sample_subscriptions/subscriptions.txt +5 -0
- data/lib/templates/sample_subscriptions/subscriptions.xml +12 -0
- data/lib/templates/themes/sass/_fonts.scss +38 -0
- data/lib/templates/themes/sass/_layout.scss +97 -0
- data/lib/templates/themes/sass/_reboot.scss +473 -0
- data/lib/templates/themes/sass/_utilities.scss +13 -0
- data/lib/templates/themes/sass/_variables.scss +57 -0
- data/lib/templates/themes/simple.html.erb +46 -0
- data/lib/templates/themes/simple.scss +6 -0
- data/mako_rss.gemspec +36 -0
- metadata +233 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bb8b5a3c394b989b9722f6ae04b6373d23ba7e08
|
4
|
+
data.tar.gz: 11efdfb201da11cf3ec348d84ae41c639c7a52a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a7603d695ded87c83719c2cd159d4e33f85878525fdd29c597c6a6fd033148c7e7a3add809f824c6e544634b196b109b3a1ada4d8cb0fcb5b6a44f7c93751f99
|
7
|
+
data.tar.gz: 0ba4e36181aa8dd232ad7f83fb3960dba146c136095cd0e875e0547a262aee1ceb80980e2a98a886a1534bb000bfd5259df3e77815ea87c0da2f8ea1bec675d9
|
data/.gitignore
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
.byebug_history
|
13
|
+
.sass-cache
|
14
|
+
|
15
|
+
# Used by dotenv library to load environment variables.
|
16
|
+
# .env
|
17
|
+
|
18
|
+
## Documentation cache and generated files:
|
19
|
+
/.yardoc/
|
20
|
+
/_yardoc/
|
21
|
+
/doc/
|
22
|
+
/rdoc/
|
23
|
+
|
24
|
+
## Environment normalization:
|
25
|
+
/.bundle/
|
26
|
+
/vendor/bundle
|
27
|
+
/lib/bundler/man/
|
28
|
+
|
29
|
+
# for a library or gem, you might want to ignore these files since the code is
|
30
|
+
# intended to run in multiple environments; otherwise, check them in:
|
31
|
+
Gemfile.lock
|
32
|
+
# .ruby-version
|
33
|
+
# .ruby-gemset
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-06-06 16:33:49 -0400 using RuboCop version 0.35.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 3
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 26
|
12
|
+
|
13
|
+
# Offense count: 37
|
14
|
+
# Configuration parameters: AllowURI, URISchemes.
|
15
|
+
Metrics/LineLength:
|
16
|
+
Max: 629
|
17
|
+
|
18
|
+
# Offense count: 5
|
19
|
+
# Configuration parameters: CountComments.
|
20
|
+
Metrics/MethodLength:
|
21
|
+
Max: 25
|
22
|
+
|
23
|
+
# Offense count: 1
|
24
|
+
Style/AccessorMethodName:
|
25
|
+
Exclude:
|
26
|
+
- 'lib/mako/core.rb'
|
27
|
+
|
28
|
+
# Offense count: 22
|
29
|
+
# Configuration parameters: Exclude.
|
30
|
+
Style/Documentation:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
# Offense count: 1
|
34
|
+
# Cop supports --auto-correct.
|
35
|
+
# Configuration parameters: AllowAsExpressionSeparator.
|
36
|
+
Style/Semicolon:
|
37
|
+
Exclude:
|
38
|
+
- 'lib/mako/article.rb'
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Jonathan Pike
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Mako 🥛 [](https://travis-ci.org/jonathanpike/mako) [](https://coveralls.io/github/jonathanpike/mako?branch=master)
|
2
|
+
|
3
|
+
Mako is a static-site generating RSS reader. Mako is also my son's name for
|
4
|
+
milk.
|
5
|
+
|
6
|
+
I designed Mako with the following principals in mind:
|
7
|
+
|
8
|
+
1. RSS feeds are freely available, so reader software should be freely
|
9
|
+
available.
|
10
|
+
2. RSS feeds are part of the web, so reader software should be part of the web.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
To install Mako, do:
|
15
|
+
|
16
|
+
$ gem install mako
|
17
|
+
|
18
|
+
Once the gem is installed, you'll need to generate a new Mako site. You can do
|
19
|
+
this in 1 of 2 ways.
|
20
|
+
|
21
|
+
1. If you already have a directory that you want Mako to live in, run:
|
22
|
+
|
23
|
+
$ mako new
|
24
|
+
|
25
|
+
2. If you don't have a directory and want Mako to create on, run:
|
26
|
+
|
27
|
+
$ mako new path/to/directory
|
28
|
+
|
29
|
+
In your new Mako site, you'll see a directory structure like this:
|
30
|
+
|
31
|
+
```
|
32
|
+
.
|
33
|
+
├── sample_subscriptions
|
34
|
+
| ├── subscriptions.json
|
35
|
+
| ├── subscriptions.txt
|
36
|
+
| └── subscriptions.xml
|
37
|
+
├── site
|
38
|
+
├── themes
|
39
|
+
| ├── sass
|
40
|
+
| | ├── _fonts.scss
|
41
|
+
| | ├── _layout.scss
|
42
|
+
| | ├── _reboot.scss
|
43
|
+
| | ├── _utitilies.scss
|
44
|
+
| | └── _variables.scss
|
45
|
+
| ├── simple.html.erb
|
46
|
+
| └── simple.scss
|
47
|
+
├── Gemfile
|
48
|
+
└── config.yaml
|
49
|
+
```
|
50
|
+
|
51
|
+
## Adding Feeds
|
52
|
+
|
53
|
+
Once Mako is installed and your Mako site has been created, the next step is to
|
54
|
+
add your own feeds. Mako currently supports 3 formats:
|
55
|
+
|
56
|
+
1. OPML
|
57
|
+
2. JSON
|
58
|
+
3. Plain Text
|
59
|
+
|
60
|
+
In the [`sample_subscriptions`](/lib/templates/sample_subscriptions) directory, you'll see an example of each format.
|
61
|
+
Whichever you choose, place the file in the root directory and be sure its name
|
62
|
+
is `subscriptions`. The file extension (`.xml`/`.opml`, `.json`, or `.txt`)
|
63
|
+
will tell Mako what kind of subscription file you have.
|
64
|
+
|
65
|
+
## Configuration
|
66
|
+
|
67
|
+
Mako has very few configuration options. You can see all of them in the
|
68
|
+
comments in [`config.yaml`](/lib/templates/config.yaml).
|
69
|
+
|
70
|
+
## Building your Site
|
71
|
+
|
72
|
+
Once you've added your subscriptions, you can build your Mako site for the first
|
73
|
+
time. By default, Mako only builds the HTML portion of the site with the `mako
|
74
|
+
build` command. Since the CSS has not been generated, use the `--with-sass`
|
75
|
+
flag, like this:
|
76
|
+
|
77
|
+
$ mako build --with-sass
|
78
|
+
|
79
|
+
The built files will be present in the `site` directory after the `build`
|
80
|
+
command has been run.
|
81
|
+
|
82
|
+
At present, Mako only displays the last 2 days worth of content from your feeds.
|
83
|
+
If a feed has not been updated in the last 2 days, it will not be displayed on
|
84
|
+
your Mako site. Similarly, articles that were published > 2 days in the past
|
85
|
+
will not be displayed on your Mako site.
|
86
|
+
|
87
|
+
## Themes
|
88
|
+
|
89
|
+
Mako comes with a simple theme of my own design (and own liking). Perhaps you
|
90
|
+
want something different. Mako's themes are templated with
|
91
|
+
[ERB](https://ruby-doc.org/stdlib-2.4.1/libdoc/erb/rdoc/ERB.html). You have
|
92
|
+
access to the following convenience methods:
|
93
|
+
- `today` - Gives you the current date in Day, `Date Month Year` format.
|
94
|
+
- `last_updated` - Gives you the current date and time in `day month year
|
95
|
+
hour:minute:second` format.
|
96
|
+
|
97
|
+
Within your template, you can access the feed data through the `feeds` array.
|
98
|
+
The `feeds` array contains `feed` objects, which have the following attributes:
|
99
|
+
- `title` - a string of the feed title.
|
100
|
+
- `url` - a string of the feed url.
|
101
|
+
- `articles` - an array of the articles associated with the feed.
|
102
|
+
|
103
|
+
To access the `articles` within a `feed`, you can use:
|
104
|
+
- `articles_desc` - sorts the array of articles by newest first.
|
105
|
+
- `articles_asc` - sorts the array of articles by oldest first.
|
106
|
+
|
107
|
+
`articles` contain the following attributes:
|
108
|
+
- `title` - a string of the article title.
|
109
|
+
- `url` - a string of the article url.
|
110
|
+
- `published` - a `Time` instance of the published date. Can also be accessed
|
111
|
+
by `formatted_published` to get it as formatted string.
|
112
|
+
- `summary` - a string of the article content.
|
113
|
+
|
114
|
+
When in doubt, check out the implementation of [my
|
115
|
+
theme](/lib/templates/themese/simple.html.erb).
|
116
|
+
|
117
|
+
## Contributing
|
118
|
+
|
119
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jonathanpike/mako.
|
120
|
+
|
121
|
+
## License
|
122
|
+
|
123
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
124
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.pattern = 'test/*_test.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
RuboCop::RakeTask.new(:rubocop)
|
12
|
+
|
13
|
+
task default: %i[test rubocop]
|
data/bin/mako
ADDED
data/lib/mako/article.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class Article
|
5
|
+
attr_reader :title, :published, :summary, :url
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@title = args.fetch(:title, '')
|
9
|
+
@published = args.fetch(:published)
|
10
|
+
@summary = sanitize(args.fetch(:summary))
|
11
|
+
@url = args.fetch(:url)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Converts published Time object to formatted string
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
def formatted_published
|
18
|
+
@published.strftime('%A, %d %B %Y at %I:%M %P')
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @private
|
24
|
+
# Removes img tags (if configured) and transforms h1 tags into
|
25
|
+
# p tags with the class bold
|
26
|
+
#
|
27
|
+
# @param [String] html an html document string
|
28
|
+
# @return [String] a sanitized html document string
|
29
|
+
def sanitize(html)
|
30
|
+
doc = Nokogiri::HTML::DocumentFragment.parse(html)
|
31
|
+
doc.css('img').each(&:remove) if Mako.config.sanitize_images
|
32
|
+
doc.css('h1,h2,h3,h4,h5,h6').each { |n| n.name = 'p'; n.set_attribute('class', 'bold') }
|
33
|
+
doc.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/mako/cli.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'commands/build'
|
4
|
+
require_relative 'commands/new'
|
5
|
+
require_relative 'commands/version'
|
6
|
+
|
7
|
+
module Mako
|
8
|
+
class CLI
|
9
|
+
COMMANDS = %w[build new version].freeze
|
10
|
+
|
11
|
+
# Takes ARGV and parses the first element (command) to see if it is
|
12
|
+
# in the commands array. If not, display help.
|
13
|
+
#
|
14
|
+
# @param [Array] argv
|
15
|
+
def self.start(argv)
|
16
|
+
command = argv.shift
|
17
|
+
if COMMANDS.include? command
|
18
|
+
CLI.invoke(command, argv)
|
19
|
+
else
|
20
|
+
help = <<~EOS
|
21
|
+
Usage:
|
22
|
+
mako [subcommand] [path...]
|
23
|
+
|
24
|
+
Subcommands:
|
25
|
+
new Create a new Mako scaffold in PATH. If no PATH provided, defaults to current directory.
|
26
|
+
build Build your Mako site. Default: only build HTML.
|
27
|
+
version Display the version.
|
28
|
+
|
29
|
+
Options:
|
30
|
+
--with-sass When supplied to build, also generates CSS from SCSS files.
|
31
|
+
EOS
|
32
|
+
Mako.logger.info help
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Calls #perform on the provided command class. When the command is done
|
37
|
+
# running, print out any errors that the command had.
|
38
|
+
#
|
39
|
+
# @param [String] command
|
40
|
+
# @param [Array] args the remainder of the ARGV arguments
|
41
|
+
def self.invoke(command, args = [])
|
42
|
+
Object.const_get("Mako::#{command.capitalize}").perform(args)
|
43
|
+
return unless Mako.errors.any?
|
44
|
+
Mako.errors.messages.each do |error_msg|
|
45
|
+
Mako.logger.warn error_msg
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class Build
|
5
|
+
# Calls #build on Mako::Core. This class stores knowledge of all of the
|
6
|
+
# different component classes needed to build the site.
|
7
|
+
#
|
8
|
+
# @param [Array] args the following are accepted arguments:
|
9
|
+
# "--with-sass": builds with SassRenderer
|
10
|
+
def self.perform(args)
|
11
|
+
subscription_list = load_subscription_list
|
12
|
+
if args.include? '--with-sass'
|
13
|
+
Mako::Core.new(requester: FeedRequester,
|
14
|
+
constructor: FeedConstructor,
|
15
|
+
renderers: [HTMLRenderer,
|
16
|
+
SassRenderer],
|
17
|
+
writer: Writer,
|
18
|
+
subscription_list: subscription_list).build
|
19
|
+
else
|
20
|
+
Mako::Core.new(requester: FeedRequester,
|
21
|
+
constructor: FeedConstructor,
|
22
|
+
renderers: [HTMLRenderer],
|
23
|
+
writer: Writer,
|
24
|
+
subscription_list: subscription_list).build
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.load_subscription_list
|
29
|
+
path = File.expand_path(Dir.glob('subscriptions.*').first, Dir.pwd)
|
30
|
+
Mako::SubscriptionListParser.new(list: path).parse
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Mako
|
6
|
+
class New
|
7
|
+
# Copies template files stored in ../lib/templates to specified directory.
|
8
|
+
# If the directory specified doesn't exist, it will be created.
|
9
|
+
# If no directory is specified, it defaults to the current directory.
|
10
|
+
def self.perform(args)
|
11
|
+
location = args.empty? ? Dir.pwd : File.expand_path(args.join(' '), Dir.pwd)
|
12
|
+
create_dir(File.basename(location)) if location != Dir.pwd && File.directory?(location)
|
13
|
+
copy_templates(location)
|
14
|
+
Mako.logger.info "Created new Mako installation in #{location}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# @private
|
18
|
+
# Copies source templates to specified path.
|
19
|
+
def self.copy_templates(path)
|
20
|
+
FileUtils.cp_r "#{Mako.config.source_templates}/.", path
|
21
|
+
end
|
22
|
+
|
23
|
+
# If the directory does not exist, create the specified directory.
|
24
|
+
def self.create_dir(path)
|
25
|
+
FileUtils.mkdir path
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Mako
|
6
|
+
class Configuration
|
7
|
+
DEFAULT_CONFIGURATION = { 'source_templates' => File.expand_path('../templates', File.dirname(__FILE__)),
|
8
|
+
'destination' => File.expand_path('site/', Dir.pwd),
|
9
|
+
'theme' => 'simple',
|
10
|
+
'sanitize_images' => true,
|
11
|
+
'config_file' => '' }.freeze
|
12
|
+
|
13
|
+
include FileOpenUtil
|
14
|
+
|
15
|
+
# Loads default config file and attempts to merge in any user settings.
|
16
|
+
# Creates a new instance of Mako::Configuration.
|
17
|
+
#
|
18
|
+
# @param [String]
|
19
|
+
# @return [Mako::Configuration]
|
20
|
+
def self.load(file)
|
21
|
+
begin
|
22
|
+
user_config_yaml = load_resource(file)
|
23
|
+
rescue SystemCallError
|
24
|
+
config = DEFAULT_CONFIGURATION
|
25
|
+
return new(config)
|
26
|
+
end
|
27
|
+
user_config = YAML.safe_load(user_config_yaml) || {}
|
28
|
+
user_config['config_file'] = file
|
29
|
+
config = DEFAULT_CONFIGURATION.merge(user_config)
|
30
|
+
new(config)
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :source_templates, :theme, :destination, :sanitize_images,
|
34
|
+
:config_file
|
35
|
+
|
36
|
+
def initialize(args)
|
37
|
+
@source_templates = args.fetch('source_templates')
|
38
|
+
@theme = args.fetch('theme')
|
39
|
+
@destination = args.fetch('destination')
|
40
|
+
@sanitize_images = args.fetch('sanitize_images')
|
41
|
+
@config_file = args.fetch('config_file')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/mako/core.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class Core
|
5
|
+
include ERB::Util
|
6
|
+
include ViewHelpers
|
7
|
+
|
8
|
+
attr_reader :feeds, :requester, :constructor, :renderers, :writer,
|
9
|
+
:subscription_list
|
10
|
+
|
11
|
+
def initialize(args)
|
12
|
+
@feeds = []
|
13
|
+
@requester = args.fetch(:requester)
|
14
|
+
@constructor = args.fetch(:constructor)
|
15
|
+
@renderers = args.fetch(:renderers)
|
16
|
+
@writer = args.fetch(:writer)
|
17
|
+
@subscription_list = args.fetch(:subscription_list)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Gets list of feed_urls, requests each of them and uses the constructor to
|
21
|
+
# make Feed and Article objects, then calls to the renderers to render
|
22
|
+
# the page and stylesheets.
|
23
|
+
def build
|
24
|
+
log_configuration_information
|
25
|
+
|
26
|
+
if subscription_list.empty?
|
27
|
+
Mako.logger.warn 'No feeds were found in your subscriptions file. Please add feeds and try again.'
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
log_time do
|
32
|
+
request_and_build_feeds
|
33
|
+
renderers.each do |renderer|
|
34
|
+
renderer_instance = renderer.new(bound: self)
|
35
|
+
writer.new(renderer: renderer_instance,
|
36
|
+
destination: File.expand_path(renderer_instance.file_path, Mako.config.destination)).write
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the Binding of Core for the ERB renderer. Binding encapsulates the
|
42
|
+
# execution context for the Core class, and makes all of the variables
|
43
|
+
# and methods of Core available to the renderer.
|
44
|
+
#
|
45
|
+
# @return [Binding]
|
46
|
+
def get_binding
|
47
|
+
binding
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# @private
|
53
|
+
# Prints configuration file, source, and destination directory to STDOUT.
|
54
|
+
def log_configuration_information
|
55
|
+
Mako.logger.info "Configuration File: #{Mako.config.config_file}"
|
56
|
+
Mako.logger.info "Theme: #{Mako.config.theme}"
|
57
|
+
Mako.logger.info "Destination: #{Mako.config.destination}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Provides build time logging information and writes it to STDOUT.
|
61
|
+
def log_time
|
62
|
+
Mako.logger.info 'Generating...'
|
63
|
+
start_time = Time.now.to_f
|
64
|
+
yield
|
65
|
+
generation_time = Time.now.to_f - start_time
|
66
|
+
Mako.logger.info "done in #{generation_time} seconds"
|
67
|
+
end
|
68
|
+
|
69
|
+
def request_and_build_feeds
|
70
|
+
requesters = subscription_list.map { |feed_url| requester.new(feed_url: feed_url) }
|
71
|
+
requesters.each do |feed_request|
|
72
|
+
feed_response = feed_request.fetch
|
73
|
+
next unless feed_request.ok?
|
74
|
+
constructed_feed = constructor.new(feed_data: feed_response.body,
|
75
|
+
feed_url: feed_response.feed_url)
|
76
|
+
.parse_and_create
|
77
|
+
feeds << constructed_feed if constructed_feed
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/mako/errors.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class Errors
|
5
|
+
attr_accessor :messages
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@messages = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Add an error message to the messages array
|
12
|
+
#
|
13
|
+
# @param [String]
|
14
|
+
def add_error(msg)
|
15
|
+
messages << msg
|
16
|
+
end
|
17
|
+
|
18
|
+
# Predicate method to see if there are any error messages
|
19
|
+
#
|
20
|
+
# @return [Boolean]
|
21
|
+
def any?
|
22
|
+
messages.count.positive?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/mako/feed.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class Feed
|
5
|
+
attr_accessor :feed_url, :url, :title, :articles
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@url = args.fetch(:url)
|
9
|
+
@title = args.fetch(:title)
|
10
|
+
@articles = []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the articles array sorted by date published ascending
|
14
|
+
# (oldest first).
|
15
|
+
#
|
16
|
+
# @return [Array]
|
17
|
+
def articles_asc
|
18
|
+
articles.sort_by(&:published)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the articles array sorted by date published descending
|
22
|
+
# (newest first).
|
23
|
+
#
|
24
|
+
# @return [Array]
|
25
|
+
def articles_desc
|
26
|
+
articles_asc.reverse
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|