bujo 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 +7 -0
- data/assets/bujo/bujo.yaml +7 -0
- data/assets/bujo/plugins/collection/template.adoc +6 -0
- data/assets/bujo/plugins/day/template.adoc +21 -0
- data/assets/bujo/plugins/init/template.adoc +9 -0
- data/assets/bujo/plugins/month/template.adoc +21 -0
- data/assets/bujo/plugins/project/template.adoc +15 -0
- data/bin/bujo +5 -0
- data/lib/bujo.rb +18 -0
- data/lib/bujo/configuration/configuration.rb +28 -0
- data/lib/bujo/configuration/editor.rb +11 -0
- data/lib/bujo/configuration/globals.rb +13 -0
- data/lib/bujo/configuration/structure.rb +76 -0
- data/lib/bujo/options/option.rb +52 -0
- data/lib/bujo/plugins/build_plugin.rb +42 -0
- data/lib/bujo/plugins/collection_plugin.rb +38 -0
- data/lib/bujo/plugins/day_plugin.rb +67 -0
- data/lib/bujo/plugins/edit_plugin.rb +35 -0
- data/lib/bujo/plugins/init_plugin.rb +44 -0
- data/lib/bujo/plugins/month_plugin.rb +64 -0
- data/lib/bujo/plugins/plugin.rb +23 -0
- data/lib/bujo/plugins/plugin_register.rb +53 -0
- data/lib/bujo/plugins/plugin_repository.rb +61 -0
- data/lib/bujo/plugins/project_plugin.rb +38 -0
- data/lib/bujo/shortcuts/shortcut.rb +22 -0
- data/lib/bujo/shortcuts/this_month_shortcut.rb +13 -0
- data/lib/bujo/shortcuts/today_shortcut.rb +13 -0
- data/lib/bujo/templates/template_renderer.rb +16 -0
- data/lib/bujo/utils/converter.rb +28 -0
- data/lib/bujo/utils/dates.rb +33 -0
- data/lib/bujo/utils/files.rb +11 -0
- data/lib/bujo/utils/names.rb +13 -0
- metadata +73 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: db114b7765cb7b390f7c01cfdd3cae455fa1f998b2c42f7e45298edf3cd93430
|
|
4
|
+
data.tar.gz: 72d2787dbca51e517925ce46ec021fd24767b0bc8b2569ee2ff60dfed0318597
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: '09ee709e124846d65c8c11b1d9deb663039f7a38d3eb22ddbed7afb218eb885a2c851ab980b420b3c651268cf9a8e417c7e8e8f97f346ce2eb2a1dfe8922e5df'
|
|
7
|
+
data.tar.gz: 2451d60ae3f052bfc464f8f424dfd3f5a802b47c0b6420b69bffe55ee6c35bafe2603aeb8380b938236130bbb515a77392cb956c47a8f8334a0eac0a984d9b2c
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
:stylesheet: https://darshandsoni.com/asciidoctor-skins/css/notebook.css
|
|
2
|
+
|
|
3
|
+
= Log du ${hr_day_long}
|
|
4
|
+
|
|
5
|
+
<<../index.adoc#, Index>> > Logs > <<${cr_month}.adoc#, ${hr_month}>> > ${hr_day_short}
|
|
6
|
+
|
|
7
|
+
[cols="2*a", options="header"]
|
|
8
|
+
|===
|
|
9
|
+
| Tâches ponctuelles | Tâches récurrentes
|
|
10
|
+
|
|
|
11
|
+
|
|
12
|
+
|
|
|
13
|
+
|
|
14
|
+
2+h| Notes
|
|
15
|
+
|
|
16
|
+
2+|
|
|
17
|
+
|
|
18
|
+
|===
|
|
19
|
+
|
|
20
|
+
[.text-center]
|
|
21
|
+
<<${cr_previous_day}.adoc#, <= Jour précédent>> | <<${cr_next_day}.adoc#, Jour suivant =>>>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
:stylesheet: https://darshandsoni.com/asciidoctor-skins/css/notebook.css
|
|
2
|
+
|
|
3
|
+
= Log du ${hr_month}
|
|
4
|
+
|
|
5
|
+
<<../index.adoc#, Index>> > Logs > ${hr_month}
|
|
6
|
+
|
|
7
|
+
[cols="2*a", options="header"]
|
|
8
|
+
|===
|
|
9
|
+
| Calendrier | Tâches
|
|
10
|
+
|
|
|
11
|
+
|
|
12
|
+
|
|
|
13
|
+
|
|
14
|
+
2+h| Notes
|
|
15
|
+
|
|
16
|
+
2+|
|
|
17
|
+
|
|
18
|
+
|===
|
|
19
|
+
|
|
20
|
+
[.text-center]
|
|
21
|
+
<<${cr_previous_month}.adoc#, <= Mois précédent>> | <<${cr_next_month}.adoc#, Mois suivant =>>>
|
data/bin/bujo
ADDED
data/lib/bujo.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'bujo/configuration/configuration'
|
|
2
|
+
require 'bujo/configuration/structure'
|
|
3
|
+
require 'bujo/plugins/plugin_repository'
|
|
4
|
+
require 'bujo/plugins/plugin_register'
|
|
5
|
+
require 'bujo/plugins/init_plugin'
|
|
6
|
+
require 'bujo/templates/template_renderer'
|
|
7
|
+
|
|
8
|
+
def parse(args = [])
|
|
9
|
+
if File.exists?(Configuration::Structure.local_path("bujo.yaml"))
|
|
10
|
+
configuration = Configuration::Configuration.load
|
|
11
|
+
plugin_repository = Plugins::PluginRepository.new(configuration)
|
|
12
|
+
Plugins::PluginRegister.new(plugin_repository.find_all).parse(args)
|
|
13
|
+
else
|
|
14
|
+
Plugins::PluginRegister
|
|
15
|
+
.new([Plugins::InitPlugin.new({template_renderer: Templates::TemplateRenderer.new})])
|
|
16
|
+
.parse(args)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Configuration
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'psych'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/plugins/plugin'
|
|
7
|
+
require 'bujo/configuration/editor'
|
|
8
|
+
|
|
9
|
+
class Configuration
|
|
10
|
+
attr_reader :mandatory_plugins, :extra_plugins, :editor
|
|
11
|
+
|
|
12
|
+
private def initialize(plugins, editor)
|
|
13
|
+
@mandatory_plugins = %w[init build]
|
|
14
|
+
@extra_plugins = plugins
|
|
15
|
+
@editor = editor
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def plugins
|
|
19
|
+
[@mandatory_plugins, @extra_plugins].flatten
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.load(configuration_file = "bujo.yaml")
|
|
23
|
+
yaml = Psych.load_file(configuration_file)
|
|
24
|
+
plugins = (yaml['plugins'] || [])
|
|
25
|
+
Configuration.new(plugins, Editor.new(yaml['editor']))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Configuration
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
class Structure
|
|
6
|
+
# Global
|
|
7
|
+
def self.global_plugin_path(plugin_relative_path)
|
|
8
|
+
File.join(global_plugins_path, plugin_relative_path)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.global_asset_path(relative_path)
|
|
12
|
+
File.join(global_assets_path, relative_path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.global_plugin_asset_path(relative_path)
|
|
16
|
+
global_asset_path(File.join("bujo/plugins", relative_path))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.global_stylesheet_path(relative_path)
|
|
20
|
+
global_asset_path(File.join("bujo/stylesheets", relative_path))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Local
|
|
24
|
+
def self.local_path(relative_path)
|
|
25
|
+
File.join(local_home, relative_path)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.sources_path
|
|
29
|
+
local_path("src")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.source_path(relative_path)
|
|
33
|
+
File.join(sources_path, relative_path)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.targets_path
|
|
37
|
+
local_path("target")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.target_path(relative_path)
|
|
41
|
+
File.join(targets_path, relative_path)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.local_plugin_path(plugin_relative_path)
|
|
45
|
+
File.join(local_plugins_path, plugin_relative_path)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.create_source_directory(directory_relative_path)
|
|
49
|
+
FileUtils.mkdir_p(File.join(sources_path, directory_relative_path))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# Global
|
|
55
|
+
def self.global_home
|
|
56
|
+
File.join(File.dirname(File.expand_path(__FILE__)), "../../../")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.global_plugins_path
|
|
60
|
+
File.join(global_home, "lib/bujo/plugins")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.global_assets_path
|
|
64
|
+
File.join(global_home, 'assets')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Local
|
|
68
|
+
def self.local_home
|
|
69
|
+
Dir.pwd
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.local_plugins_path
|
|
73
|
+
local_path("plugins")
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Options
|
|
2
|
+
class Option
|
|
3
|
+
attr_reader :short_name, :long_name, :description, :value_type, :action
|
|
4
|
+
|
|
5
|
+
private def initialize(short_name, long_name, description, value_type, action)
|
|
6
|
+
@short_name = short_name
|
|
7
|
+
@long_name = long_name
|
|
8
|
+
@description = description
|
|
9
|
+
@value_type = value_type
|
|
10
|
+
@action = action
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.builder
|
|
14
|
+
Builder.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def valued
|
|
18
|
+
not @value_type.nil?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class Builder
|
|
22
|
+
def initialize
|
|
23
|
+
@shortcuts = []
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def with_name(short_name = nil, long_name)
|
|
27
|
+
@short_name = short_name
|
|
28
|
+
@long_name = long_name
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def with_description(description)
|
|
33
|
+
@description = description
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def valued(value_type = String)
|
|
38
|
+
@value_type = value_type
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def with_action(action)
|
|
43
|
+
@action = action
|
|
44
|
+
self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def build
|
|
48
|
+
Option.new(@short_name, @long_name, @description, @value_type, @action)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'asciidoctor'
|
|
5
|
+
|
|
6
|
+
# Own
|
|
7
|
+
require 'bujo/configuration/globals'
|
|
8
|
+
require 'bujo/plugins/plugin'
|
|
9
|
+
require 'bujo/options/option'
|
|
10
|
+
require 'bujo/utils/converter'
|
|
11
|
+
|
|
12
|
+
class BuildPlugin < Plugin
|
|
13
|
+
def initialize(dependencies = [])
|
|
14
|
+
super("build", [
|
|
15
|
+
Options::Option.builder
|
|
16
|
+
.with_name("b", "build")
|
|
17
|
+
.with_description("Build HTML representation of the journal")
|
|
18
|
+
.with_action(-> { build_journal })
|
|
19
|
+
.build
|
|
20
|
+
])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def build_journal
|
|
24
|
+
clean_target
|
|
25
|
+
convert_files
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def clean_target
|
|
31
|
+
puts "Cleaning target..."
|
|
32
|
+
FileUtils.rm_rf(Configuration::Structure.targets_path)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def convert_files
|
|
36
|
+
puts "Converting to HTML..."
|
|
37
|
+
Dir.glob(File.join(Configuration::Structure.sources_path, "**/*"))
|
|
38
|
+
.select { |file| file =~ /.*\.adoc$/ }
|
|
39
|
+
.each { |asciidoctor_file| Utils::Converter.convert_file(asciidoctor_file) }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/plugins/plugin'
|
|
7
|
+
require 'bujo/options/option'
|
|
8
|
+
require 'bujo/utils/names'
|
|
9
|
+
require 'bujo/utils/files'
|
|
10
|
+
|
|
11
|
+
class CollectionPlugin < Plugin
|
|
12
|
+
def initialize(dependencies = [])
|
|
13
|
+
super("collections", [
|
|
14
|
+
Options::Option.builder
|
|
15
|
+
.with_name("c", "collection")
|
|
16
|
+
.with_description("Create an entry for a collection in the journal")
|
|
17
|
+
.valued
|
|
18
|
+
.with_action(lambda { |collection| create_collection(collection) })
|
|
19
|
+
.build,
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
@template_renderer = dependencies[:template_renderer]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def directory
|
|
26
|
+
"collections"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create_collection(collection_name)
|
|
30
|
+
puts "Creating an entry for collection #{collection_name} in the journal"
|
|
31
|
+
rendered_template = @template_renderer.render("collection/template.adoc", {
|
|
32
|
+
:collection_name => collection_name
|
|
33
|
+
})
|
|
34
|
+
collection_source_path = Configuration::Structure.source_path("collections/#{Utils::NameUtils.computerize(collection_name)}.adoc")
|
|
35
|
+
Utils::Files.write(collection_source_path, rendered_template)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Own
|
|
3
|
+
require 'bujo/plugins/plugin'
|
|
4
|
+
require 'bujo/options/option'
|
|
5
|
+
require 'bujo/utils/dates'
|
|
6
|
+
require 'bujo/utils/files'
|
|
7
|
+
|
|
8
|
+
class DayPlugin < Plugin
|
|
9
|
+
def initialize(dependencies = [])
|
|
10
|
+
super("day", [
|
|
11
|
+
Options::Option.builder
|
|
12
|
+
.with_name("today")
|
|
13
|
+
.with_description("Create an entry for today in the journal")
|
|
14
|
+
.with_action(-> { create_today })
|
|
15
|
+
.build,
|
|
16
|
+
Options::Option.builder
|
|
17
|
+
.with_name("tomorrow")
|
|
18
|
+
.with_description("Create an entry for tomorrow in the journal")
|
|
19
|
+
.with_action(-> { create_tomorrow })
|
|
20
|
+
.build,
|
|
21
|
+
Options::Option.builder
|
|
22
|
+
.with_name("date")
|
|
23
|
+
.with_description("Create an entry for the given date in the journal")
|
|
24
|
+
.valued
|
|
25
|
+
.with_action(lambda { |value| create_day(value) })
|
|
26
|
+
.build
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
@template_renderer = dependencies[:template_renderer]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def directory
|
|
33
|
+
"logs"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def create_today
|
|
37
|
+
puts "Creating an entry for today (#{Utils::DateUtils.human_readable_date}) in the journal"
|
|
38
|
+
do_create_day
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create_tomorrow
|
|
42
|
+
puts "Creating an entry for tomorrow (#{Utils::DateUtils.human_readable_date(Date.today.next_day)}) in the journal"
|
|
43
|
+
do_create_day(Date.today.next_day)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_day(date_as_string)
|
|
47
|
+
date = Utils::DateUtils.parse_human_readable_date(date_as_string)
|
|
48
|
+
puts "Creating an entry for #{date_as_string} in the journal"
|
|
49
|
+
do_create_day(date)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def do_create_day(date = Date.today)
|
|
55
|
+
rendered_template = @template_renderer.render("day/template.adoc", {
|
|
56
|
+
:hr_day_long => Utils::DateUtils.human_readable_date(date),
|
|
57
|
+
:hr_day_short => Utils::DateUtils.day(date),
|
|
58
|
+
:hr_month => Utils::DateUtils.human_readable_month(date),
|
|
59
|
+
:cr_previous_day => Utils::DateUtils.computer_readable_date(date.prev_day),
|
|
60
|
+
:cr_next_day => Utils::DateUtils.computer_readable_date(date.next_day),
|
|
61
|
+
:cr_month => Utils::DateUtils.computer_readable_month(date)
|
|
62
|
+
})
|
|
63
|
+
day_source_path = Configuration::Structure.source_path("logs/#{Utils::DateUtils.computer_readable_date(date)}.adoc")
|
|
64
|
+
Utils::Files.write(day_source_path, rendered_template)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/plugins/plugin'
|
|
7
|
+
require 'bujo/options/option'
|
|
8
|
+
require 'bujo/configuration/configuration'
|
|
9
|
+
require 'bujo/utils/converter'
|
|
10
|
+
|
|
11
|
+
class EditPlugin < Plugin
|
|
12
|
+
def initialize(dependencies = [], editor = nil)
|
|
13
|
+
super("edition", [
|
|
14
|
+
Options::Option.builder
|
|
15
|
+
.with_name("e", "edit")
|
|
16
|
+
.with_description("Init the structure of the journal")
|
|
17
|
+
.valued
|
|
18
|
+
.with_action(lambda { |file| edit_entry(file) })
|
|
19
|
+
.build
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
# TODO C'mon, you're better than that
|
|
23
|
+
@editor = editor.nil? ? Configuration::Configuration.load.editor : editor
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def edit_entry(relative_path)
|
|
27
|
+
puts "Editing entry..."
|
|
28
|
+
@editor.call(relative_path)
|
|
29
|
+
|
|
30
|
+
puts "Converting to HTML..."
|
|
31
|
+
Utils::Converter.convert_file(relative_path)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/configuration/configuration'
|
|
7
|
+
require 'bujo/configuration/structure'
|
|
8
|
+
require 'bujo/plugins/plugin'
|
|
9
|
+
require 'bujo/plugins/plugin_repository'
|
|
10
|
+
require 'bujo/options/option'
|
|
11
|
+
require 'bujo/utils/files'
|
|
12
|
+
|
|
13
|
+
class InitPlugin < Plugin
|
|
14
|
+
def initialize(dependencies = [])
|
|
15
|
+
super("init", [
|
|
16
|
+
Options::Option.builder
|
|
17
|
+
.with_name("i", "init")
|
|
18
|
+
.with_description("Init the structure of the journal")
|
|
19
|
+
.with_action(-> { init_journal })
|
|
20
|
+
.build
|
|
21
|
+
])
|
|
22
|
+
|
|
23
|
+
@template_renderer = dependencies[:template_renderer]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def init_journal
|
|
27
|
+
puts "Initializing a new BuJo..."
|
|
28
|
+
FileUtils.copy(Configuration::Structure.global_asset_path("bujo/bujo.yaml"), Configuration::Structure.local_path("bujo.yaml"))
|
|
29
|
+
Dir.mkdir(Configuration::Structure.sources_path)
|
|
30
|
+
|
|
31
|
+
rendered_template = @template_renderer.render("init/template.adoc", {})
|
|
32
|
+
index_source_path = Configuration::Structure.source_path("index.adoc")
|
|
33
|
+
Utils::Files.write(index_source_path, rendered_template)
|
|
34
|
+
|
|
35
|
+
configuration = Configuration::Configuration.load
|
|
36
|
+
plugin_repository = PluginRepository.new(configuration, @template_renderer)
|
|
37
|
+
plugin_repository.find_all
|
|
38
|
+
.map { |plugin| plugin.directory }
|
|
39
|
+
.select { |directory| not directory.nil? }
|
|
40
|
+
.uniq
|
|
41
|
+
.each { |directory| Configuration::Structure.create_source_directory(directory)}
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Own
|
|
3
|
+
require 'bujo/plugins/plugin'
|
|
4
|
+
require 'bujo/options/option'
|
|
5
|
+
require 'bujo/utils/dates'
|
|
6
|
+
require 'bujo/utils/files'
|
|
7
|
+
|
|
8
|
+
class MonthPlugin < Plugin
|
|
9
|
+
def initialize(dependencies = [])
|
|
10
|
+
super("month", [
|
|
11
|
+
Options::Option.builder
|
|
12
|
+
.with_name("this-month")
|
|
13
|
+
.with_description("Create an entry for this month in the journal")
|
|
14
|
+
.with_action(-> { create_this_month })
|
|
15
|
+
.build,
|
|
16
|
+
Options::Option.builder
|
|
17
|
+
.with_name("next-month")
|
|
18
|
+
.with_description("Create an entry for next month in the journal")
|
|
19
|
+
.with_action(-> { create_next_month })
|
|
20
|
+
.build,
|
|
21
|
+
Options::Option.builder
|
|
22
|
+
.with_name("month")
|
|
23
|
+
.with_description("Create an entry for the given month in the journal")
|
|
24
|
+
.valued
|
|
25
|
+
.with_action(lambda { |month| create_month(month) })
|
|
26
|
+
.build
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
@template_renderer = dependencies[:template_renderer]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def directory
|
|
33
|
+
"logs"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def create_this_month
|
|
37
|
+
puts "Creating an entry for this month (#{Utils::DateUtils.human_readable_month}) in the journal"
|
|
38
|
+
do_create_month
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create_next_month
|
|
42
|
+
puts "Creating an entry for next month (#{Utils::DateUtils.human_readable_month(Date.today.next_month)}) in the journal"
|
|
43
|
+
do_create_month(Date.today.next_month)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_month(month_as_string)
|
|
47
|
+
date = Utils::DateUtils.parse_human_readable_month(month_as_string)
|
|
48
|
+
puts "Creating an entry for #{month_as_string} in the journal"
|
|
49
|
+
do_create_month(date)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def do_create_month(date = Date.today)
|
|
55
|
+
rendered_template = @template_renderer.render("month/template.adoc", {
|
|
56
|
+
:hr_month => Utils::DateUtils.human_readable_month(date),
|
|
57
|
+
:cr_previous_month => Utils::DateUtils.computer_readable_month(date.prev_month),
|
|
58
|
+
:cr_next_month => Utils::DateUtils.computer_readable_month(date.next_month)
|
|
59
|
+
})
|
|
60
|
+
month_source_path = Configuration::Structure.source_path("logs/#{Utils::DateUtils.computer_readable_month(date)}.adoc")
|
|
61
|
+
Utils::Files.write(month_source_path, rendered_template)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
class Plugin
|
|
3
|
+
attr_reader :name, :options
|
|
4
|
+
|
|
5
|
+
protected def initialize(name, options)
|
|
6
|
+
@name = name
|
|
7
|
+
@options = options
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def directory
|
|
11
|
+
nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def shortcuts
|
|
15
|
+
[]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# TODO Not sure about this
|
|
19
|
+
def ==(other)
|
|
20
|
+
self.class == other.class
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'optparse'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/configuration/globals'
|
|
7
|
+
|
|
8
|
+
class PluginRegister
|
|
9
|
+
def initialize(plugins = [])
|
|
10
|
+
@plugins = plugins
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def register(plugin)
|
|
14
|
+
puts "Registering #{plugin.name} plugin..."
|
|
15
|
+
@plugins << plugin
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def parse(options)
|
|
20
|
+
OptionParser.new do |parser|
|
|
21
|
+
parser.banner = "Usage: bujo [options]"
|
|
22
|
+
|
|
23
|
+
parser.on("-v", "--verbose", "Show more log messages") do ||
|
|
24
|
+
Configuration::Globals.set_verbose(true)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@plugins.each { |mod|
|
|
28
|
+
mod.options.each { |option|
|
|
29
|
+
parser.on("--" + option.long_name + " VALUE", option.description) do |value|
|
|
30
|
+
option.action.call(value)
|
|
31
|
+
end if option.short_name.nil? && option.valued
|
|
32
|
+
|
|
33
|
+
parser.on("-" + option.short_name, "--" + option.long_name + " VALUE", option.description) do |value|
|
|
34
|
+
option.action.call(value)
|
|
35
|
+
end if !option.short_name.nil? && option.valued
|
|
36
|
+
|
|
37
|
+
parser.on("--" + option.long_name, option.description) do ||
|
|
38
|
+
option.action.call
|
|
39
|
+
end if option.short_name.nil? && !option.valued
|
|
40
|
+
|
|
41
|
+
parser.on("-" + option.short_name, "--" + option.long_name, option.description) do ||
|
|
42
|
+
option.action.call
|
|
43
|
+
end if !option.short_name.nil? && !option.valued
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
parser.on("-h", "--help", "Show this help message") do ||
|
|
48
|
+
puts parser
|
|
49
|
+
end
|
|
50
|
+
end.parse!(options)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Own
|
|
3
|
+
require 'bujo/configuration/configuration'
|
|
4
|
+
require 'bujo/configuration/structure'
|
|
5
|
+
|
|
6
|
+
class PluginRepository
|
|
7
|
+
def initialize(configuration, template_renderer)
|
|
8
|
+
@configuration = configuration
|
|
9
|
+
@template_renderer = template_renderer
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def find_all
|
|
13
|
+
local_plugins = find_local_plugins
|
|
14
|
+
global_plugins = find_global_plugins(local_plugins)
|
|
15
|
+
|
|
16
|
+
mandatory_plugins = find_mandatory_plugins
|
|
17
|
+
if local_plugins.any? { |plugin| mandatory_plugins.include?(plugin) }
|
|
18
|
+
raise StandardError "Mandatory plugins shouldn't be overridden"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
[global_plugins, local_plugins].flatten
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def find_local_plugins
|
|
27
|
+
@configuration.plugins
|
|
28
|
+
.select { |plugin_name| File.exists?("#{to_local_plugin_file(plugin_name)}.rb") }
|
|
29
|
+
.each { |plugin_name| require_relative to_local_plugin_file(plugin_name) }
|
|
30
|
+
.map { |plugin_name| to_plugin_instance(plugin_name) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def to_local_plugin_file(plugin_name)
|
|
34
|
+
Configuration::Structure.local_plugin_path(to_plugin_file_name(plugin_name))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def find_global_plugins(local_plugins)
|
|
38
|
+
@configuration.plugins
|
|
39
|
+
.each { |plugin_name| require_relative to_global_plugin_file(plugin_name) }
|
|
40
|
+
.map { |plugin_name| to_plugin_instance(plugin_name) }
|
|
41
|
+
.select { |plugin| not local_plugins.include?(plugin) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_global_plugin_file(plugin_name)
|
|
45
|
+
Configuration::Structure.global_plugin_path(to_plugin_file_name(plugin_name))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def find_mandatory_plugins
|
|
49
|
+
@configuration.mandatory_plugins
|
|
50
|
+
.map { |plugin_name| to_plugin_instance(plugin_name) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_plugin_file_name(plugin_name)
|
|
54
|
+
"#{plugin_name}_plugin"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_plugin_instance(plugin_name)
|
|
58
|
+
Object.const_get("Plugins::#{plugin_name.capitalize}Plugin").new({template_renderer: @template_renderer})
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Plugins
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/plugins/plugin'
|
|
7
|
+
require 'bujo/options/option'
|
|
8
|
+
require 'bujo/utils/names'
|
|
9
|
+
require 'bujo/utils/files'
|
|
10
|
+
|
|
11
|
+
class ProjectPlugin < Plugin
|
|
12
|
+
def initialize(dependencies = [])
|
|
13
|
+
super("projects", [
|
|
14
|
+
Options::Option.builder
|
|
15
|
+
.with_name("p", "project")
|
|
16
|
+
.with_description("Create an entry for a project in the journal")
|
|
17
|
+
.valued
|
|
18
|
+
.with_action(lambda { |project| create_project(project) })
|
|
19
|
+
.build,
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
@template_renderer = dependencies[:template_renderer]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def directory
|
|
26
|
+
"projects"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create_project(project_name)
|
|
30
|
+
puts "Creating an entry for project #{project_name} in the journal"
|
|
31
|
+
rendered_template = @template_renderer.render("project/template.adoc", {
|
|
32
|
+
:project_name => project_name
|
|
33
|
+
})
|
|
34
|
+
project_source_path = Configuration::Structure.source_path("projects/#{Utils::NameUtils.computerize(project_name)}.adoc")
|
|
35
|
+
Utils::Files.write(project_source_path, rendered_template)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Shortcuts
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
|
|
4
|
+
class Shortcut
|
|
5
|
+
attr_reader :name, :source, :target
|
|
6
|
+
|
|
7
|
+
def initialize(name, source, target)
|
|
8
|
+
@name = name
|
|
9
|
+
@source = source
|
|
10
|
+
@target = target
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create
|
|
14
|
+
puts("* #{@name} link: #{@source} --> #{@target}")
|
|
15
|
+
FileUtils.copy("target/#{@source}", "target/#{@target}") if (File.exist?("target/#{@source}"))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
"#{@name}: #{@source} --> #{@target}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Shortcuts
|
|
2
|
+
# Own
|
|
3
|
+
require_relative 'shortcut'
|
|
4
|
+
require_relative '../utils/dates'
|
|
5
|
+
|
|
6
|
+
include Utils
|
|
7
|
+
|
|
8
|
+
class ThisMonthShortcut < Shortcut
|
|
9
|
+
def initialize
|
|
10
|
+
super("This month", "logs/#{computer_readable_month}.html", "logs/this_month.html")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Shortcuts
|
|
2
|
+
# Own
|
|
3
|
+
require_relative 'shortcut'
|
|
4
|
+
require_relative '../utils/dates'
|
|
5
|
+
|
|
6
|
+
include Utils
|
|
7
|
+
|
|
8
|
+
class TodayShortcut < Shortcut
|
|
9
|
+
def initialize
|
|
10
|
+
super("Today", "logs/#{computer_readable_date}.html", "logs/today.html")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Templates
|
|
2
|
+
# Own
|
|
3
|
+
require 'bujo/configuration/structure'
|
|
4
|
+
|
|
5
|
+
class TemplateRenderer
|
|
6
|
+
def render(template_relative_path, placeholders_replacements)
|
|
7
|
+
template_path = Configuration::Structure.global_plugin_asset_path(template_relative_path)
|
|
8
|
+
template = File.read(template_path)
|
|
9
|
+
|
|
10
|
+
placeholders_replacements
|
|
11
|
+
.each { |placeholder, replacement| template = template.gsub(/\${#{placeholder}}/, replacement) }
|
|
12
|
+
|
|
13
|
+
template
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Utils
|
|
2
|
+
# Ruby
|
|
3
|
+
require 'asciidoctor'
|
|
4
|
+
|
|
5
|
+
# Own
|
|
6
|
+
require 'bujo/configuration/structure'
|
|
7
|
+
require 'bujo/configuration/globals'
|
|
8
|
+
|
|
9
|
+
class Converter
|
|
10
|
+
def self.convert_file(source_path)
|
|
11
|
+
begin
|
|
12
|
+
source_relative_path = Pathname.new(File.expand_path(source_path)).relative_path_from(Pathname.new(Configuration::Structure.sources_path))
|
|
13
|
+
source_file = File.open(source_path)
|
|
14
|
+
target_path = File.join(Configuration::Structure.targets_path, source_relative_path.to_s.gsub(/\.adoc/, ".html"))
|
|
15
|
+
puts "Converting #{source_path} to #{target_path}..." if Configuration::Globals.verbose
|
|
16
|
+
Asciidoctor.convert(
|
|
17
|
+
source_file,
|
|
18
|
+
{
|
|
19
|
+
:to_file => target_path,
|
|
20
|
+
:mkdirs => true
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
ensure
|
|
24
|
+
source_file.close unless source_file.nil?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Utils
|
|
2
|
+
require 'date'
|
|
3
|
+
|
|
4
|
+
class DateUtils
|
|
5
|
+
def self.day(date = Date.today)
|
|
6
|
+
date.strftime("%d")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.human_readable_date(date = Date.today)
|
|
10
|
+
date.strftime("%d/%m/%Y")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.human_readable_month(date = Date.today)
|
|
14
|
+
date.strftime("%m/%Y")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.computer_readable_date(date = Date.today)
|
|
18
|
+
date.strftime("%Y-%m-%d")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.computer_readable_month(date = Date.today)
|
|
22
|
+
date.strftime("%Y-%m")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.parse_human_readable_date(date_as_string)
|
|
26
|
+
Date.strptime(date_as_string, "%d/%m/%Y")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.parse_human_readable_month(month_as_string)
|
|
30
|
+
Date.strptime("01/#{month_as_string}", "%d/%m/%Y")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bujo
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- François Dupire
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2020-08-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description:
|
|
14
|
+
email: dupire.francois+pro@gmail.com
|
|
15
|
+
executables:
|
|
16
|
+
- bujo
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- assets/bujo/bujo.yaml
|
|
21
|
+
- assets/bujo/plugins/collection/template.adoc
|
|
22
|
+
- assets/bujo/plugins/day/template.adoc
|
|
23
|
+
- assets/bujo/plugins/init/template.adoc
|
|
24
|
+
- assets/bujo/plugins/month/template.adoc
|
|
25
|
+
- assets/bujo/plugins/project/template.adoc
|
|
26
|
+
- bin/bujo
|
|
27
|
+
- lib/bujo.rb
|
|
28
|
+
- lib/bujo/configuration/configuration.rb
|
|
29
|
+
- lib/bujo/configuration/editor.rb
|
|
30
|
+
- lib/bujo/configuration/globals.rb
|
|
31
|
+
- lib/bujo/configuration/structure.rb
|
|
32
|
+
- lib/bujo/options/option.rb
|
|
33
|
+
- lib/bujo/plugins/build_plugin.rb
|
|
34
|
+
- lib/bujo/plugins/collection_plugin.rb
|
|
35
|
+
- lib/bujo/plugins/day_plugin.rb
|
|
36
|
+
- lib/bujo/plugins/edit_plugin.rb
|
|
37
|
+
- lib/bujo/plugins/init_plugin.rb
|
|
38
|
+
- lib/bujo/plugins/month_plugin.rb
|
|
39
|
+
- lib/bujo/plugins/plugin.rb
|
|
40
|
+
- lib/bujo/plugins/plugin_register.rb
|
|
41
|
+
- lib/bujo/plugins/plugin_repository.rb
|
|
42
|
+
- lib/bujo/plugins/project_plugin.rb
|
|
43
|
+
- lib/bujo/shortcuts/shortcut.rb
|
|
44
|
+
- lib/bujo/shortcuts/this_month_shortcut.rb
|
|
45
|
+
- lib/bujo/shortcuts/today_shortcut.rb
|
|
46
|
+
- lib/bujo/templates/template_renderer.rb
|
|
47
|
+
- lib/bujo/utils/converter.rb
|
|
48
|
+
- lib/bujo/utils/dates.rb
|
|
49
|
+
- lib/bujo/utils/files.rb
|
|
50
|
+
- lib/bujo/utils/names.rb
|
|
51
|
+
homepage:
|
|
52
|
+
licenses: []
|
|
53
|
+
metadata: {}
|
|
54
|
+
post_install_message:
|
|
55
|
+
rdoc_options: []
|
|
56
|
+
require_paths:
|
|
57
|
+
- lib
|
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
requirements: []
|
|
69
|
+
rubygems_version: 3.1.2
|
|
70
|
+
signing_key:
|
|
71
|
+
specification_version: 4
|
|
72
|
+
summary: support CLI to maintain Bullet Journal using AsciiDoctor
|
|
73
|
+
test_files: []
|