coltrane 3.4.2 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.DS_Store +0 -0
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile.lock +15 -4
  6. data/bin/old-coltrane +29 -0
  7. data/coltrane.gemspec +4 -4
  8. data/exe/coltrane +77 -47
  9. data/lib/.DS_Store +0 -0
  10. data/lib/coltrane/.DS_Store +0 -0
  11. data/lib/coltrane/commands.rb +4 -9
  12. data/lib/coltrane/commands/available_chord_representations.rb +9 -0
  13. data/lib/coltrane/commands/available_classic_scales.rb +9 -0
  14. data/lib/coltrane/commands/available_notable_progressions.rb +9 -0
  15. data/lib/coltrane/commands/available_representations.rb +9 -0
  16. data/lib/coltrane/commands/command.rb +3 -54
  17. data/lib/coltrane/commands/find_chord_by_notes.rb +9 -0
  18. data/lib/coltrane/commands/find_common_chords.rb +9 -0
  19. data/lib/coltrane/commands/find_progressions_from_chords.rb +9 -0
  20. data/lib/coltrane/commands/find_scale_by_chords.rb +9 -0
  21. data/lib/coltrane/commands/find_scale_by_notes.rb +9 -0
  22. data/lib/coltrane/commands/get_chords_from_notable_progression.rb +9 -0
  23. data/lib/coltrane/commands/get_chords_from_progression.rb +9 -0
  24. data/lib/coltrane/commands/get_chords_from_scale.rb +9 -0
  25. data/lib/coltrane/commands/get_chords_from_string.rb +11 -0
  26. data/lib/coltrane/commands/get_classic_scale.rb +9 -0
  27. data/lib/coltrane/commands/get_notes.rb +9 -0
  28. data/lib/coltrane/commands/get_notes_from_string.rb +9 -0
  29. data/lib/coltrane/commands/get_representation_chords.rb +18 -0
  30. data/lib/coltrane/commands/get_representation_notes.rb +12 -0
  31. data/lib/coltrane/commands/render.rb +9 -0
  32. data/lib/coltrane/renderers/text_renderer/hash_drawer.rb +1 -0
  33. data/lib/coltrane/renderers/text_renderer/theory_chord_drawer.rb +1 -2
  34. data/lib/coltrane/theory/classic_scales.rb +1 -1
  35. data/lib/coltrane/ui.rb +9 -0
  36. data/lib/coltrane/ui/.DS_Store +0 -0
  37. data/lib/coltrane/ui/router.rb +87 -0
  38. data/lib/coltrane/ui/views.rb +4 -0
  39. data/lib/coltrane/ui/views/chords.rb +19 -0
  40. data/lib/coltrane/ui/views/custom_progression.rb +27 -0
  41. data/lib/coltrane/ui/views/find_chord_by_notes.rb +16 -0
  42. data/lib/coltrane/ui/views/find_chords_in_scale.rb +34 -0
  43. data/lib/coltrane/ui/views/find_common_chords_in_scales.rb +40 -0
  44. data/lib/coltrane/ui/views/find_progressions_from_chords.rb +14 -0
  45. data/lib/coltrane/ui/views/find_scale.rb +14 -0
  46. data/lib/coltrane/ui/views/find_scale_by_chords.rb +16 -0
  47. data/lib/coltrane/ui/views/find_scale_by_notes.rb +16 -0
  48. data/lib/coltrane/ui/views/index.rb +14 -0
  49. data/lib/coltrane/ui/views/notes.rb +20 -0
  50. data/lib/coltrane/ui/views/progressions.rb +18 -0
  51. data/lib/coltrane/ui/views/scales.rb +17 -0
  52. data/lib/coltrane/ui/views/show_chord.rb +21 -0
  53. data/lib/coltrane/ui/views/show_progression.rb +26 -0
  54. data/lib/coltrane/ui/views/show_scale.rb +26 -0
  55. data/lib/coltrane/ui/views/view.rb +47 -0
  56. data/lib/coltrane/version.rb +1 -1
  57. metadata +64 -28
  58. data/lib/coltrane/commands/chords.rb +0 -93
  59. data/lib/coltrane/commands/common_chords.rb +0 -33
  60. data/lib/coltrane/commands/errors.rb +0 -44
  61. data/lib/coltrane/commands/find_guitar_chord.rb +0 -25
  62. data/lib/coltrane/commands/find_progression.rb +0 -28
  63. data/lib/coltrane/commands/find_scale.rb +0 -39
  64. data/lib/coltrane/commands/notes.rb +0 -50
  65. data/lib/coltrane/commands/progression.rb +0 -28
  66. data/lib/coltrane/commands/scale.rb +0 -46
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class FindScaleByNotes < Command
4
+ def run(notes)
5
+ Theory::Scale.having_notes(*notes)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetChordsFromNotableProgression < Command
4
+ def run(progression, key)
5
+ Theory::Progression.send(progression.underscore, key).chords
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetChordsFromProgression < Command
4
+ def run(notation, key)
5
+ Theory::Progression.new(notation, key: key).chords
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetChordsFromScale < Command
4
+ def run(scale, type, size)
5
+ scale.send(type == 'tertians' ? :tertians : :chords)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetChordsFromString < Command
4
+ def run(string)
5
+ string.split(' ').map do |chord|
6
+ Theory::Chord.new(name: chord)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetClassicScale < Command
4
+ def run(scale, tone)
5
+ Theory::Scale.fetch(scale, tone)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetNotes < Command
4
+ def run(*notes)
5
+ Theory::NoteSet[*notes]
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetNotesFromString < Command
4
+ def run(string)
5
+ GetNotes.run(*string.split(' '))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetRepresentationChords < Command
4
+ def run(representation, chords)
5
+ chords.map do |chord|
6
+ if representation == 'GuitarChordChart'
7
+ {
8
+ chord.name => Representation::Guitar.find_chords(chord).first(4),
9
+ options: { layout: :horizontal, per_row: 4 }
10
+ }
11
+ else
12
+ { chord.name => GetRepresentationNotes.run(representation, chord.notes) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ module Coltrane
2
+ module Commands
3
+ class GetRepresentationNotes < Command
4
+ def run(representation, notes)
5
+ return notes if representation == 'Text'
6
+ Object
7
+ .const_get("Coltrane::Representation::#{representation}")
8
+ .find_notes(notes)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ module Coltrane
2
+ module Commands
3
+ class Render < Command
4
+ def run(object)
5
+ Renderers::TextRenderer.render(object)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -5,6 +5,7 @@ module Coltrane
5
5
  alias hash model
6
6
 
7
7
  def render
8
+ options = hash.delete(:options) || {}
8
9
  hash.map { |k, v|
9
10
  "#{k}: \n\n" +
10
11
  TextRenderer.render(v, **options)
@@ -5,8 +5,7 @@ module Coltrane
5
5
  alias chord model
6
6
 
7
7
  def render
8
- "#{chord.name}: ".ljust(5) +
9
- TextRenderer.render(chord.notes, **options)
8
+ "#{chord.name}: ".ljust(5) + TextRenderer.render(chord.notes)
10
9
  end
11
10
  end
12
11
  end
@@ -45,7 +45,7 @@ module Coltrane
45
45
  alias blues blues_major
46
46
 
47
47
  def known_scales
48
- SCALES.keys + ['Major', 'Natural Minor']
48
+ ['Major', 'Natural Minor'] + SCALES.keys
49
49
  end
50
50
 
51
51
  # List of scales appropriate for search
@@ -0,0 +1,9 @@
1
+ require 'active_support/inflector'
2
+ require 'paint'
3
+ require 'color'
4
+ require 'cli/ui' # shopify cli
5
+
6
+ require 'coltrane'
7
+ require 'coltrane/commands'
8
+ require 'coltrane/ui/views'
9
+ require 'coltrane/ui/router'
Binary file
@@ -0,0 +1,87 @@
1
+ module Coltrane
2
+ module UI
3
+ class Router
4
+
5
+ class Route
6
+ attr_reader :path, :view, :last
7
+ attr_accessor :params
8
+
9
+ def initialize(path, to:, with: {})
10
+ @path = path
11
+ @view = to
12
+ @params = with
13
+ end
14
+
15
+ def render(**other_params)
16
+ view.render(**params, **other_params)
17
+ end
18
+ end
19
+
20
+ class History
21
+ attr_reader :routes
22
+
23
+ def initialize
24
+ @routes = []
25
+ end
26
+
27
+ def add(route)
28
+ @routes << route
29
+ end
30
+
31
+ def previous
32
+ routes[-2]&.path || ''
33
+ end
34
+
35
+ def current_route
36
+ routes[-1]
37
+ end
38
+
39
+ def back
40
+ routes.pop.render
41
+ end
42
+
43
+ def refresh(params={})
44
+ current_route.render(params)
45
+ end
46
+ end
47
+
48
+ attr_reader :path, :params, :routes, :history, :url
49
+
50
+ def initialize
51
+ @routes = []
52
+ @history = History.new
53
+
54
+ draw_route '', to: Coltrane::UI::Views::Index
55
+ Views.constants.each do |view|
56
+ draw_route view.to_s.underscore.humanize.downcase, to: "Coltrane::UI::Views::#{view}".constantize
57
+ end
58
+ end
59
+
60
+ def get(**params)
61
+ path = params.delete(:path)
62
+ @url = build_url(path || history.current_route.path, **params)
63
+ route = @routes.detect { |route| route.path == path }
64
+ return history.refresh(params) unless route
65
+ history.add(route)
66
+ route.render(**params)
67
+ end
68
+
69
+ def build_url(path, params)
70
+ [
71
+ path,
72
+ (params || {}).map do |k,v|
73
+ [k,v.gsub(' ', '-')].join(':')
74
+ end
75
+ ].compact.join(' ')
76
+ end
77
+
78
+ def previous_path
79
+ history.previous
80
+ end
81
+
82
+ def draw_route(*args, **keyword_args, &block)
83
+ @routes << Route.new(*args, **keyword_args, &block)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,4 @@
1
+ require 'coltrane/ui/views/view'
2
+ Dir[File.expand_path('../views/*', __FILE__)].map do |f|
3
+ require(f)
4
+ end
@@ -0,0 +1,19 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class Chords < View
5
+ questions({
6
+ path: {
7
+ statement: 'What do you need',
8
+ options: [
9
+ 'show chord',
10
+ 'find chord by notes',
11
+ 'find chords in scale',
12
+ 'find common chords in scales'
13
+ ]
14
+ }
15
+ })
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class CustomProgression < View
5
+ questions({
6
+ progression_notation: {
7
+ statement: 'What is the progression? (Ex: I-vi-IV-V)'
8
+ },
9
+
10
+ representation: {
11
+ statement: 'How do you wanna see the chords?',
12
+ options: Commands::AvailableChordRepresentations.run
13
+ },
14
+
15
+ key: {
16
+ statement: 'What is the key?'
17
+ },
18
+ })
19
+
20
+ def render
21
+ chords = Commands::GetChordsFromProgression.run(*params.values_at(:progression_notation, :key))
22
+ Commands::GetRepresentationChords.run(params[:representation], chords)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class FindChordByNotes < View
5
+ questions({
6
+ notes: { statement: 'Which Notes?' }
7
+ })
8
+
9
+ def render
10
+ notes = Commands::GetNotesFromString.run(params[:notes])
11
+ Commands::FindChordByNotes.run(*notes)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ require 'coltrane/ui/views/show_scale'
2
+
3
+ module Coltrane
4
+ module UI
5
+ module Views
6
+ class FindChordsInScale < ShowScale
7
+ questions({
8
+ chord_type: {
9
+ statement: 'Which kind of chords?',
10
+ options: ['tertian', 'all']
11
+ },
12
+
13
+ chord_size: {
14
+ statement: 'What is the size of the chords',
15
+ options: (3..7).to_a.map(&:to_s)
16
+ },
17
+
18
+ chord_representation: {
19
+ statement: 'How do you wanna see this',
20
+ options: Commands::AvailableChordRepresentations.run
21
+ }
22
+ })
23
+ def render
24
+ scale = Commands::GetClassicScale.run(*params.values_at(:scale, :tone))
25
+ chords = Commands::GetChordsFromScale.run(
26
+ scale,
27
+ *params.values_at(:chord_type, :chord_size)
28
+ )
29
+ Commands::GetRepresentationChords.run(params[:chord_representation], chords)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class FindCommonChordsInScales < View
5
+ questions({
6
+ first_scale: {
7
+ statement: 'Choose the first scale',
8
+ options: Commands::AvailableClassicScales.run
9
+ },
10
+
11
+ first_scale_root: {
12
+ statement: 'Type the tone (note)'
13
+ },
14
+
15
+ second_scale: {
16
+ statement: 'Choose the second scale',
17
+ options: Commands::AvailableClassicScales.run
18
+ },
19
+
20
+ second_scale_root: {
21
+ statement: 'Type the tone (note)'
22
+ },
23
+
24
+ representation: {
25
+ statement: 'How do you wanna see the results?',
26
+ options: Commands::AvailableChordRepresentations.run
27
+ }
28
+ })
29
+
30
+ def render
31
+ scale_a = Commands::GetClassicScale.run(*params.values_at(:first_scale, :first_scale_root))
32
+ scale_b = Commands::GetClassicScale.run(*params.values_at(:second_scale, :second_scale_root))
33
+ chords = Commands::FindCommonChords.run(scale_a, scale_b)
34
+ rep_chords = Commands::GetRepresentationChords.run(params[:representation], chords)
35
+ { "Chords that exist in #{scale_a.full_name} and #{scale_b.full_name}" => rep_chords }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class FindProgressionsFromChords < View
5
+ questions chords: { statement: 'Type the chords? (Ex: CM EM GM)' }
6
+
7
+ def render
8
+ chords = Commands::GetChordsFromString.run(params[:chords])
9
+ Commands::FindProgressionsFromChords.run(*chords)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class FindScale < View
5
+ questions({
6
+ path: {
7
+ statement: 'How do you wanna search',
8
+ options: ['find scale by chords', 'find scale by notes']
9
+ },
10
+ })
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Coltrane
2
+ module UI
3
+ module Views
4
+ class FindScaleByChords < View
5
+ questions({
6
+ chords: { statement: 'Which Chords?' }
7
+ })
8
+
9
+ def render
10
+ chords = Commands::GetChordsFromString.run(params[:chords])
11
+ Commands::FindScaleByChords.run(*chords)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end