caramelize 0.3.0 → 0.4.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.
Files changed (33) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +19 -24
  3. data/bin/caramelize +48 -2
  4. data/caramelize.gemspec +2 -1
  5. data/lib/caramelize.rb +12 -0
  6. data/lib/caramelize/caramel.rb +33 -29
  7. data/lib/caramelize/content_transferer.rb +78 -111
  8. data/lib/caramelize/filter_processor.rb +31 -0
  9. data/lib/caramelize/input_wiki/redmine_wiki.rb +97 -0
  10. data/lib/caramelize/{wiki → input_wiki}/trac_converter.rb +0 -0
  11. data/lib/caramelize/input_wiki/wiki.rb +61 -0
  12. data/lib/caramelize/input_wiki/wikkawiki.rb +57 -0
  13. data/lib/caramelize/output_wiki/gollum.rb +73 -0
  14. data/lib/caramelize/page.rb +10 -4
  15. data/lib/caramelize/services/page_builder.rb +20 -0
  16. data/lib/caramelize/version.rb +1 -1
  17. data/spec/lib/caramelize/content_transferer_spec.rb +9 -0
  18. data/spec/lib/caramelize/filter_processor_spec.rb +32 -0
  19. data/spec/lib/caramelize/filters/wikka_to_markdown_spec.rb +25 -13
  20. data/spec/lib/caramelize/{wiki → input_wiki}/wiki_spec.rb +30 -4
  21. data/spec/lib/caramelize/output_wiki/gollum_spec.rb +113 -0
  22. data/spec/lib/caramelize/page_spec.rb +49 -0
  23. data/spec/lib/caramelize/services/page_builder.rb +29 -0
  24. data/spec/spec_helper.rb +1 -1
  25. metadata +38 -17
  26. data/lib/caramelize/cli.rb +0 -89
  27. data/lib/caramelize/cli/create_command.rb +0 -36
  28. data/lib/caramelize/cli/run_command.rb +0 -33
  29. data/lib/caramelize/gollum_output.rb +0 -79
  30. data/lib/caramelize/wiki/redmine_wiki.rb +0 -88
  31. data/lib/caramelize/wiki/wiki.rb +0 -63
  32. data/lib/caramelize/wiki/wikkawiki.rb +0 -48
  33. data/spec/lib/caramelize/gollum_output_spec.rb +0 -64
@@ -0,0 +1,31 @@
1
+ require 'gollum-lib'
2
+ require 'grit'
3
+ require 'ruby-progressbar'
4
+
5
+ module Caramelize
6
+ class FilterProcessor
7
+ attr_reader :filters, :input_wiki
8
+
9
+ def initialize(input_wiki)
10
+ @filters = []
11
+ @input_wiki = input_wiki
12
+
13
+ initialize_wiki_filters
14
+ end
15
+
16
+ def run(body)
17
+ body_new = body
18
+ filters.each do |filter|
19
+ body_new = filter.run(body_new)
20
+ end
21
+ body_new
22
+ end
23
+
24
+ private
25
+
26
+ def initialize_wiki_filters
27
+ filters << input_wiki.filters
28
+ filters.flatten!
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,97 @@
1
+ require 'caramelize/input_wiki/wiki'
2
+ require 'caramelize/filters/swap_wiki_links'
3
+ require 'caramelize/filters/remove_table_tab_line_endings'
4
+
5
+ module Caramelize
6
+ module InputWiki
7
+ class RedmineWiki < Wiki
8
+ include DatabaseConnector
9
+
10
+ def initialize options={}
11
+ super(options)
12
+ @options[:markup] = :textile
13
+ @options[:filters] << Caramelize::SwapWikiLinks.new
14
+ @options[:filters] << Caramelize::RemoveTableTabLineEndings.new
15
+ @options[:create_namespace_overview] = true
16
+ end
17
+
18
+ # after calling this action, I expect the titles and revisions to be filled
19
+ def read_pages
20
+ # get all projects
21
+ results_projects = database.query("SELECT id, identifier, name FROM projects;")
22
+ results_projects.each do |row_project|
23
+ #collect all namespaces
24
+ namespaces << OpenStruct.new(identifier: row_project["identifier"], name: row_project["name"])
25
+ end
26
+
27
+ # get all wikis
28
+ results_wikis = database.query("SELECT id, project_id FROM wikis;")
29
+
30
+ # get all lemmas
31
+ results_pages = database.query("SELECT id, title, wiki_id FROM wiki_pages;")
32
+ results_pages.each do |row_page|
33
+ results_contents = database.query("SELECT * FROM wiki_content_versions WHERE page_id='#{row_page["id"]}' ORDER BY updated_on;")
34
+
35
+ # get wiki for page
36
+ wiki_row = nil
37
+ project_row = nil
38
+ results_wikis.each do |wiki|
39
+ wiki_row = wiki if wiki["id"] == row_page["wiki_id"]
40
+ end
41
+
42
+ if wiki_row
43
+ # get project from wiki-id
44
+ results_projects.each do |project|
45
+ project_row = project if project["id"] == wiki_row["project_id"]
46
+ end
47
+ end
48
+
49
+ project_identifier = project_row ? project_row["identifier"] + '/' : ""
50
+
51
+ title = project_identifier + row_page["title"]
52
+ titles << title
53
+
54
+ @latest_revisions = {}
55
+ results_contents.each do |row_content|
56
+ page = Page.new(build_properties(title, row_content))
57
+ revisions << page
58
+ @latest_revisions[title] = page
59
+ end
60
+ end
61
+ titles.uniq!
62
+ @latest_revisions.each { |rev| rev[1].set_latest }
63
+ revisions.sort! { |a,b| a.time <=> b.time }
64
+
65
+ # TODO find latest revision for each limit
66
+
67
+ revisions
68
+ end
69
+
70
+ def read_authors
71
+ results = database.query("SELECT id, login, mail FROM users;")
72
+ results.each do |row|
73
+ authors[row["id"]] = OpenStruct.new(id: row["id"],
74
+ name: row["login"],
75
+ email: row["mail"])
76
+ end
77
+ authors
78
+ end
79
+
80
+ private
81
+
82
+ def build_properties(title, row_content)
83
+ author = authors[row_content["author_id"]] ? authors[row_content["author_id"]] : nil
84
+ { id: row_content["id"],
85
+ title: title,
86
+ body: row_content["data"],
87
+ markup: :textile,
88
+ latest: false,
89
+ time: row_content["updated_on"],
90
+ message: row_content["comments"],
91
+ author: author,
92
+ author_name: author.name
93
+ }
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,61 @@
1
+ module Caramelize
2
+ module InputWiki
3
+ class Wiki
4
+ include DatabaseConnector
5
+
6
+ attr_accessor :revisions, :wiki_title, :titles, :description, :namespaces, :options
7
+
8
+ def initialize(options={})
9
+ @options = options
10
+ @options[:filters] = []
11
+ @namespaces = []
12
+ end
13
+
14
+ def revisions_by_title(title)
15
+ # new array only containing pages by this name sorted by time asc
16
+ # this does not support renamed pages
17
+ return revisions
18
+ .select { |revision| revision.title == title }
19
+ .sort { |x,y| x.time <=> y.time }
20
+ end
21
+
22
+ # return an empty array in case this action was not overridden
23
+ def read_authors
24
+ []
25
+ end
26
+
27
+ def namespaces
28
+ @namespaces ||= {}
29
+ end
30
+
31
+ def authors
32
+ @authors ||= {}
33
+ end
34
+
35
+ def revisions
36
+ @revisions ||= []
37
+ end
38
+
39
+ def titles
40
+ @titles ||= []
41
+ end
42
+
43
+ def convert_markup?(to_markup)
44
+ markup != to_markup
45
+ end
46
+
47
+ def filters
48
+ @options[:filters]
49
+ end
50
+
51
+ def latest_revisions
52
+ titles.map { |title| revisions_by_title(title).last }.compact
53
+ end
54
+
55
+ def markup
56
+ @options[:markup]
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,57 @@
1
+ require 'caramelize/input_wiki/wiki'
2
+ require 'caramelize/database_connector'
3
+ require 'caramelize/filters/wikka_to_markdown'
4
+
5
+ module Caramelize
6
+ module InputWiki
7
+ class WikkaWiki < Wiki
8
+ include DatabaseConnector
9
+
10
+ def initialize options={}
11
+ super(options)
12
+ @options[:markup] = :wikka
13
+ @options[:filters] << Caramelize::Wikka2Markdown.new
14
+ end
15
+
16
+ # after calling this action, titles and @revisions are expected to be filled
17
+ def read_pages
18
+ sql = "SELECT id, tag, body, time, latest, user, note FROM wikka_pages ORDER BY time;"
19
+ results = database.query(sql)
20
+ results.each do |row|
21
+ titles << row["tag"]
22
+ page = Page.new(build_properties(row))
23
+ revisions << page
24
+ end
25
+ titles.uniq!
26
+ #revisions.sort! { |a,b| a.time <=> b.time }
27
+
28
+ revisions
29
+ end
30
+
31
+ def read_authors
32
+ sql = "SELECT name, email FROM wikka_users;"
33
+ results = database.query(sql)
34
+ results.each do |row|
35
+ authors[row["name"]] = OpenStruct.new(name: row["name"],
36
+ email: row["email"] )
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def build_properties(row)
43
+ author = authors[row["user"]]
44
+ { id: row["id"],
45
+ title: row["tag"],
46
+ body: row["body"],
47
+ markup: :wikka,
48
+ latest: row["latest"] == "Y",
49
+ time: row["time"],
50
+ message: row["note"],
51
+ author: author,
52
+ author_name: row["user"]
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,73 @@
1
+ require 'caramelize/ext'
2
+ module Caramelize
3
+ module OutputWiki
4
+ class Gollum
5
+
6
+ attr_reader :wiki_path
7
+
8
+ SUPPORTED_TARGET_MARKUP =
9
+ %i[markdown textile rdoc creole media_wiki org pod re_structured_text ascii_doc].freeze
10
+
11
+ # Initialize a new gollum-wiki-repository at the given path.
12
+ def initialize(new_wiki_path)
13
+ # TODO use sanitized name as wiki-repository-title
14
+ @wiki_path = new_wiki_path
15
+ initialize_repository
16
+ end
17
+
18
+ # Commit the given page into the gollum-wiki-repository.
19
+ # Make sure the target markup is correct before calling this method.
20
+ def commit_revision(page, markup)
21
+ gollum_page = gollum.page(page.title)
22
+
23
+ if gollum_page
24
+ gollum.update_page(gollum_page, gollum_page.name, gollum_page.format, page.body, build_commit(page))
25
+ else
26
+ gollum.write_page(page.title, markup, page.body, build_commit(page))
27
+ end
28
+ end
29
+
30
+ # Commit all revisions of the given history into this gollum-wiki-repository.
31
+ def commit_history(revisions, options = {}, &block)
32
+ revisions.each_with_index do |page, index|
33
+ # call debug output from outside
34
+ block.call(page, index) if block_given?
35
+ commit_revision(page, options.fetch(:markup, :markdown))
36
+ end
37
+ end
38
+
39
+ def commit_namespace_overview(namespaces)
40
+ commit_revision(build_namespace_overview(namespaces), :markdown)
41
+ end
42
+
43
+ def supported_markup
44
+ SUPPORTED_TARGET_MARKUP
45
+ end
46
+
47
+ def build_commit(page)
48
+ {
49
+ message: page.commit_message,
50
+ name: page.author_name,
51
+ email: page.author_email,
52
+ authored_date: page.time,
53
+ committed_date: page.time
54
+ }
55
+ end
56
+
57
+ private
58
+
59
+ def build_namespace_overview(namespaces)
60
+ ::Caramelize::Services::PageBuilder.build_namespace_overview(namespaces)
61
+ end
62
+
63
+ def gollum
64
+ @gollum ||= ::Gollum::Wiki.new(wiki_path)
65
+ end
66
+
67
+ def initialize_repository
68
+ return if File.exists?(wiki_path)
69
+ Grit::Repo.init(wiki_path)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,9 +1,10 @@
1
1
  module Caramelize
2
2
  class Page
3
3
 
4
- attr_accessor :title, :body, :id, :markup, :latest, :time, :message, :author, :author_name
4
+ attr_accessor :title, :body, :id, :markup, :latest, :time, :message,
5
+ :author, :author_name
5
6
 
6
- def initialize page={}
7
+ def initialize(page={})
7
8
  @id = page[:id]
8
9
  @title = page[:title] || ""
9
10
  @body = page[:body] || ""
@@ -12,7 +13,7 @@ module Caramelize
12
13
  @time = page[:time] || Time.now
13
14
  @message = page[:message] || ""
14
15
  @author = page[:author]
15
- @author_name = page[:author_name]
16
+ @author_name = page[:author_name]
16
17
  end
17
18
 
18
19
  def author_email
@@ -39,5 +40,10 @@ module Caramelize
39
40
  def to_s
40
41
  @title
41
42
  end
43
+
44
+ def commit_message
45
+ return "Edit in page #{title}" if message.empty?
46
+ message
47
+ end
42
48
  end
43
- end
49
+ end
@@ -0,0 +1,20 @@
1
+ module Caramelize
2
+ module Services
3
+ class PageBuilder
4
+ def self.build_namespace_overview(namespaces)
5
+ body = "## Overview of namespaces\n\n"
6
+
7
+ namespaces.each do |namespace|
8
+ # TODO change wiki as configurable default home
9
+ # TODO support other markup syntaxes
10
+ body << "* [[#{namespace[:name]}|#{namespace[:identifier]}/Wiki]] \n"
11
+ end
12
+
13
+ Page.new(title: "Home",
14
+ body: body,
15
+ message: 'Create Namespace Overview',
16
+ latest: true)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Caramelize
2
- VERSION = "0.3.0"
2
+ VERSION = '0.4.0'
3
3
  end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Caramelize::ContentTransferer do
4
+ describe '#execute' do
5
+ context 'with original_wiki' do
6
+ pending
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Caramelize::FilterProcessor do
4
+ let(:filters) { [] }
5
+ let(:input_wiki) { double(filters: filters) }
6
+ let(:body) { 'body' }
7
+ subject(:processor) { described_class.new(input_wiki) }
8
+
9
+ class ReverseFilter
10
+ def run(body)
11
+ body.reverse
12
+ end
13
+ end
14
+
15
+ describe '#run' do
16
+ context 'without any filters' do
17
+ it 'returns same revision body' do
18
+ expect(processor.run(body)).to eql body
19
+ end
20
+ end
21
+
22
+ context 'with reverse filter' do
23
+ let(:filters) do
24
+ [ReverseFilter.new]
25
+ end
26
+
27
+ it 'returns reversed body' do
28
+ expect(processor.run(body)).to eql body.reverse
29
+ end
30
+ end
31
+ end
32
+ end
@@ -5,81 +5,93 @@ describe Caramelize::Wikka2Markdown do
5
5
  describe :run do
6
6
  let(:filter) { Caramelize::Wikka2Markdown.new }
7
7
  context 'headline h1' do
8
- it 'should convert to markdown' do
8
+ it 'converts to markdown' do
9
9
  body = '======Headline======'
10
10
  expect(filter.run(body)).to eq '# Headline'
11
11
  end
12
12
  end
13
+
13
14
  context 'headline h2' do
14
- it 'should convert to markdown' do
15
+ it 'converts to markdown' do
15
16
  body = '=====Headline====='
16
17
  expect(filter.run(body)).to eq '## Headline'
17
18
  end
18
19
  end
20
+
19
21
  context 'headline h3' do
20
- it 'should convert to markdown' do
22
+ it 'converts to markdown' do
21
23
  body = '====Headline===='
22
24
  expect(filter.run(body)).to eq '### Headline'
23
25
  end
24
26
  end
27
+
25
28
  context 'headline h4' do
26
- it 'should convert to markdown' do
29
+ it 'converts to markdown' do
27
30
  body = '===Headline==='
28
31
  expect(filter.run(body)).to eq '#### Headline'
29
32
  end
30
33
  end
34
+
31
35
  context 'headline h1' do
32
- it 'should convert to markdown' do
36
+ it 'converts to markdown' do
33
37
  body = '======Headline======'
34
38
  expect(filter.run(body)).to eq '# Headline'
35
39
  end
36
40
  end
41
+
37
42
  context 'bold' do
38
- it 'should convert to markdown' do
43
+ it 'converts to markdown' do
39
44
  body = '**Text is bold**'
40
45
  expect(filter.run(body)).to eq '**Text is bold**'
41
46
  end
42
47
  end
48
+
43
49
  context 'italic' do
44
- it 'should convert to markdown' do
50
+ it 'converts to markdown' do
45
51
  body = '//Text is italic//'
46
52
  expect(filter.run(body)).to eq '_Text is italic_'
47
53
  end
48
54
  end
55
+
49
56
  context 'underline' do
50
- it 'should convert to markdown' do
57
+ it 'converts to markdown' do
51
58
  body = '__Text is underlined__'
52
59
  expect(filter.run(body)).to eq '<u>Text is underlined</u>'
53
60
  end
54
61
  end
62
+
55
63
  context 'line break' do
56
- it 'should convert to markdown' do
64
+ it 'converts to markdown' do
57
65
  body = 'Text is---\nbroken to two lines.'
58
66
  expect(filter.run(body)).to eq 'Text is \nbroken to two lines.'
59
67
  end
60
68
  end
69
+
61
70
  context 'unordered list entry' do
62
71
  context 'tab based' do
63
- it 'should convert to markdown' do
72
+ it 'converts to markdown' do
64
73
  body = "\t-unordered list entry"
65
74
  expect(filter.run(body)).to eq '*unordered list entry'
66
75
  end
67
76
  end
77
+
68
78
  context 'also tab based' do
69
- it 'should convert to markdown' do
79
+ it 'converts to markdown' do
70
80
  body = "~-unordered list entry"
71
81
  expect(filter.run(body)).to eq '*unordered list entry'
72
82
  end
73
83
  end
84
+
74
85
  context 'space based' do
75
- it 'should convert to markdown' do
86
+ it 'converts to markdown' do
76
87
  body = " -unordered list entry"
77
88
  expect(filter.run(body)).to eq '*unordered list entry'
78
89
  end
79
90
  end
80
91
  end
92
+
81
93
  context 'hyperlink' do
82
- it 'should convert to markdown' do
94
+ it 'converts to markdown' do
83
95
  body = '[[Title http://target]]'
84
96
  expect(filter.run(body)).to eq '[[http://target|Title]]'
85
97
  end