rs-rails-base 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +75 -0
  5. data/.travis.yml +5 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE.md +9 -0
  9. data/README.md +61 -0
  10. data/Rakefile +7 -0
  11. data/bin/bundle +3 -0
  12. data/bin/rails +7 -0
  13. data/bin/rake +16 -0
  14. data/bin/rs_rails_base +37 -0
  15. data/bin/setup +8 -0
  16. data/circle.yml +12 -0
  17. data/config.reek +109 -0
  18. data/docs/chat.md +14 -0
  19. data/docs/facebook.md +10 -0
  20. data/docs/twilio.md +21 -0
  21. data/images/chat_flow.png +0 -0
  22. data/images/chat_struct.png +0 -0
  23. data/lib/rs-rails-base/cli_actions.rb +16 -0
  24. data/lib/rs-rails-base/commands.rb +81 -0
  25. data/lib/rs-rails-base/constants.rb +7 -0
  26. data/lib/rs-rails-base/features.rb +16 -0
  27. data/lib/rs-rails-base/features/chat.rb +91 -0
  28. data/lib/rs-rails-base/features/facebook.rb +41 -0
  29. data/lib/rs-rails-base/features/twilio.rb +18 -0
  30. data/lib/rs-rails-base/file_manipulation.rb +55 -0
  31. data/lib/rs-rails-base/git_actions.rb +13 -0
  32. data/lib/rs-rails-base/rails_actions.rb +27 -0
  33. data/lib/rs_rails_base.rb +10 -0
  34. data/lib/templates/chat/channel.rb +4 -0
  35. data/lib/templates/chat/chat_channel.rb +15 -0
  36. data/lib/templates/chat/chat_service.rb +28 -0
  37. data/lib/templates/chat/chats_controller.rb +56 -0
  38. data/lib/templates/chat/connection.rb +24 -0
  39. data/lib/templates/chat/jbuilder/_info.json.jbuilder +2 -0
  40. data/lib/templates/chat/jbuilder/_message.json.jbuilder +2 -0
  41. data/lib/templates/chat/jbuilder/index.json.jbuilder +3 -0
  42. data/lib/templates/chat/jbuilder/messages_create.json.jbuilder +3 -0
  43. data/lib/templates/chat/jbuilder/messages_create_info.json.jbuilder +7 -0
  44. data/lib/templates/chat/jbuilder/show.json.jbuilder +3 -0
  45. data/lib/templates/chat/messages_controller.rb +23 -0
  46. data/lib/templates/chat/migration-models/add_chat.rb +9 -0
  47. data/lib/templates/chat/migration-models/add_message.rb +15 -0
  48. data/lib/templates/chat/migration-models/add_participant.rb +12 -0
  49. data/lib/templates/chat/migration-models/chat.rb +30 -0
  50. data/lib/templates/chat/migration-models/message.rb +43 -0
  51. data/lib/templates/chat/migration-models/participant.rb +28 -0
  52. data/lib/templates/chat/migration-models/user.rb +3 -0
  53. data/lib/templates/chat/routes.rb +6 -0
  54. data/lib/templates/chat/routes_2.rb +1 -0
  55. data/lib/templates/chat/sessions_controller.rb +7 -0
  56. data/lib/templates/chat/specs/chat_channel_spec.rb +25 -0
  57. data/lib/templates/chat/specs/chat_factory.rb +20 -0
  58. data/lib/templates/chat/specs/chat_service_spec.rb +19 -0
  59. data/lib/templates/chat/specs/chat_spec.rb +27 -0
  60. data/lib/templates/chat/specs/connection_spec.rb +10 -0
  61. data/lib/templates/chat/specs/message_factory.rb +7 -0
  62. data/lib/templates/chat/specs/message_spec.rb +40 -0
  63. data/lib/templates/chat/specs/participant_factory.rb +7 -0
  64. data/lib/templates/chat/specs/participant_spec.rb +21 -0
  65. data/lib/templates/chat/specs/rails_helper.rb +1 -0
  66. data/lib/templates/facebook/apiary.apib +28 -0
  67. data/lib/templates/facebook/en.yml +4 -0
  68. data/lib/templates/facebook/facebook_service.rb +13 -0
  69. data/lib/templates/facebook/facebook_spec.rb +146 -0
  70. data/lib/templates/facebook/factories_user.rb +6 -0
  71. data/lib/templates/facebook/routes.rb +3 -0
  72. data/lib/templates/facebook/sessions_controller.rb +9 -0
  73. data/lib/templates/facebook/sessions_controller_2.rb +7 -0
  74. data/lib/templates/facebook/sessions_routing_spec.rb +4 -0
  75. data/lib/templates/facebook/user_spec.rb +5 -0
  76. data/lib/templates/twilio/twilio.rb +4 -0
  77. data/lib/templates/twilio/twilio_service.rb +21 -0
  78. data/rs-rails-base.gemspec +29 -0
  79. data/tasks/code_analysis.rake +4 -0
  80. metadata +206 -0
data/docs/chat.md ADDED
@@ -0,0 +1,14 @@
1
+ Chat documentation
2
+ ======
3
+
4
+ The chat solution uses Action Cable, for more information please visit: [ActionCable Doc](http://edgeguides.rubyonrails.org/action_cable_overview.html), and to know how to write tests for your solution refer to [ActionCableTesting Gem](https://github.com/palkan/action-cable-testing)
5
+
6
+ ### Chat model diagram
7
+
8
+ ![Chat struct](../images/chat_struct.png "Chat structure")
9
+
10
+ First you need to register users as participants of a chat, then you can start chatting. The purpose of the participant model is to not only store which user is in each chat, but also store chat common data like "last_message", "last_connection" so queries are on a lightweight table (compared to messages, which is the usual approach).
11
+
12
+ ### Chat flow
13
+
14
+ ![Chat flow](../images/chat_flow.png "Chat flow")
data/docs/facebook.md ADDED
@@ -0,0 +1,10 @@
1
+ FACEBOOK DOCUMENTATION
2
+ ======
3
+
4
+ Simple facebook solution is initialized. To learn more about how to work on it please visit: [Koala Doc](https://github.com/arsduo/koala)
5
+
6
+ ### How it works
7
+
8
+ This is really simple, it just adds a service that wraps all the logic to interact with Facebook, and modifies routes & session to work with new session data.
9
+
10
+ You can check and test the generated endpoints in apiary!
data/docs/twilio.md ADDED
@@ -0,0 +1,21 @@
1
+ SMS & Calls documentations
2
+ ======
3
+
4
+ The call & messaging solution uses Twilio, for more information please visit: [Twilio Doc](https://github.com/twilio/twilio-ruby), and if you are completely new with twilio, you can take a look at [Twilio quickstart](https://www.twilio.com/docs/sms/quickstart/ruby).
5
+
6
+ ### Getting started (SMS)
7
+
8
+ There are just a few things to be done:
9
+ * Sign up on Twilio
10
+ * Configure ENV vars in project
11
+ * TWILIO_ACCOUNT_SID
12
+ * TWILIO_ACCOUNT_TOKEN
13
+ * TWILIO_PHONE_FROM
14
+ * Start coding your service call
15
+
16
+ ```
17
+ TwilioService.send_text_message(some_user.phone_number, your_awesome_message)
18
+ ```
19
+
20
+ ### Getting started (Calls)
21
+ This will come soon
Binary file
Binary file
@@ -0,0 +1,16 @@
1
+ require 'commander/import'
2
+
3
+ module RailsBase
4
+ # This module provides help to interact with client terminal
5
+ module CliActions
6
+ def say_something(message, style = 'BOLD')
7
+ cli = HighLine.new
8
+ cli.say("<%= color('#{message}', #{style}) %>")
9
+ end
10
+
11
+ def self.ask_for_something(ask)
12
+ cli = HighLine.new
13
+ cli.ask ask
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,81 @@
1
+ require 'fileutils'
2
+
3
+ module RailsBase
4
+ # This module provides commands implementation
5
+ module Commands
6
+ extend RailsBase::CliActions
7
+
8
+ def self.new_project
9
+ say_something('Getting ready to get an amazing project')
10
+ answer = RailsBase::CliActions.ask_for_something('What would be the name for project folder?')
11
+ if Dir.exist?(answer)
12
+ say_something('Please dont use same project again and again')
13
+ else
14
+ final_version = manage_tags
15
+ RailsBase::GitActions.fetch_from_remote(final_version)
16
+ clone_project(final_version, RailsBase::REMOTE_URI, answer)
17
+ remove_git_configuration(answer)
18
+ end
19
+ FileUtils.cd("#{Dir.pwd}/#{answer}")
20
+ say_something('Download complete')
21
+ end
22
+
23
+ def self.add_feature(feature)
24
+ if feature.nil?
25
+ display_menu
26
+ else
27
+ feature_case(feature)
28
+ end
29
+ end
30
+
31
+ def self.feature_case(feature)
32
+ case feature
33
+ when FEATURE_OPTIONS[:facebook]
34
+ RailsBase::Features.facebook
35
+ puts 'Mark is happy'
36
+ when FEATURE_OPTIONS[:twilio]
37
+ RailsBase::Features.twilio
38
+ puts 'now start messaging'
39
+ when FEATURE_OPTIONS[:chat]
40
+ RailsBase::Features.chat
41
+ puts 'now go and start talking'
42
+ when 'all', 'All'
43
+ FEATURE_OPTIONS.each do |k, v|
44
+ puts "Installing #{v}"
45
+ RailsBase::Features.send(k)
46
+ puts "Feature #{v} installed"
47
+ end
48
+ puts 'All set'
49
+ else
50
+ puts 'Please select a valid option'
51
+ end
52
+ end
53
+
54
+ def self.manage_tags
55
+ filters = "awk '{print $2}'| cut -d '/' -f 3 | cut -d '^' -f 1 | uniq"
56
+ tags = "git ls-remote -t #{RailsBase::REMOTE_URI} | #{filters}"
57
+ reference_tag = RailsBase::API_BASE_VERSION
58
+ tag_numbers = reference_tag.split('.')
59
+ major = tag_numbers[0]
60
+ minor = tag_numbers[1]
61
+ `#{tags} | grep '#{major}.#{minor}.[0-9]' | tail -n 1 `
62
+ end
63
+
64
+ def self.clone_project(version, uri, to_folder)
65
+ command = "git clone -b #{version.strip!} --depth 1 #{uri} #{to_folder} &> /dev/null 2>&1"
66
+ system(command)
67
+ end
68
+
69
+ def self.remove_git_configuration(project_folder)
70
+ git_config = project_folder + '/.git'
71
+ FileUtils.rm_rf(git_config)
72
+ end
73
+
74
+ def self.display_menu
75
+ say_something('FEATURE OPTIONS:')
76
+ RailsBase::FEATURE_OPTIONS.merge(all: 'All').each_value do |feature|
77
+ say_something(" #{feature}")
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,7 @@
1
+ module RailsBase
2
+ VERSION = '0.1.0'.freeze
3
+ API_BASE_VERSION = '1.1.0'.freeze
4
+ REMOTE_URI = 'git://github.com/rootstrap/rails_api_base.git'.freeze
5
+ FEATURE_OPTIONS = { facebook: 'Facebook', twilio: 'SMS',
6
+ chat: 'Chat' }.freeze
7
+ end
@@ -0,0 +1,16 @@
1
+ module RailsBase
2
+ # This module handle specific functionalities
3
+ module Features
4
+ def self.facebook
5
+ Facebook.install
6
+ end
7
+
8
+ def self.chat
9
+ Chat.install
10
+ end
11
+
12
+ def self.twilio
13
+ Twilio.install
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,91 @@
1
+ module RailsBase
2
+ # This module handle specific functionalities
3
+ module Features
4
+ class Chat
5
+ extend RailsBase::FileManipulation
6
+ extend RailsBase::RailsActions
7
+ extend RailsBase::CliActions
8
+ TEMPLATES_PATH = '../templates/chat/'.freeze
9
+ VIEWS_PATH = 'app/views/api/v1/'.freeze
10
+
11
+ def self.install
12
+ install_gem('action-cable-testing', '0.3.1')
13
+ migrations("#{TEMPLATES_PATH}migration-models/")
14
+ create_files(TEMPLATES_PATH)
15
+ create_jbuilder_files("#{TEMPLATES_PATH}jbuilder/")
16
+ create_spec_files("#{TEMPLATES_PATH}specs/")
17
+ inject_into_files(TEMPLATES_PATH)
18
+ replace_in_files
19
+ end
20
+
21
+ def self.migrations(templates_path)
22
+ new_migration(templates_path, 'add_chat.rb')
23
+ new_migration(templates_path, 'add_participant.rb')
24
+ new_migration(templates_path, 'add_message.rb')
25
+ run_migrations
26
+ create_file('app/models/chat.rb', "#{templates_path}chat.rb")
27
+ create_file('app/models/message.rb', "#{templates_path}message.rb")
28
+ create_file('app/models/participant.rb', "#{templates_path}participant.rb")
29
+ end
30
+
31
+ def self.create_files(templates_path)
32
+ create_file('app/channels/application_cable/channel.rb',
33
+ "#{templates_path}channel.rb")
34
+ create_file('app/channels/application_cable/connection.rb',
35
+ "#{templates_path}connection.rb")
36
+ create_file('app/services/chat_service.rb',
37
+ "#{templates_path}chat_service.rb")
38
+ create_file('app/channels/chat_channel.rb',
39
+ "#{templates_path}chat_channel.rb")
40
+ create_file('app/controllers/api/v1/chats_controller.rb',
41
+ "#{templates_path}/chats_controller.rb")
42
+ create_file('app/controllers/api/v1/messages_controller.rb',
43
+ "#{templates_path}/messages_controller.rb")
44
+ end
45
+
46
+ def self.create_spec_files(templates_path)
47
+ create_file('spec/models/chat.rb', "#{templates_path}chat_spec.rb")
48
+ create_file('spec/models/participant.rb', "#{templates_path}participant_spec.rb")
49
+ create_file('spec/models/message.rb', "#{templates_path}message_spec.rb")
50
+ create_file('spec/services/chat_service_spec.rb', "#{templates_path}chat_service_spec.rb")
51
+ create_file('spec/factories/chat.rb', "#{templates_path}chat_factory.rb")
52
+ create_file('spec/factories/participant.rb', "#{templates_path}participant_factory.rb")
53
+ create_file('spec/factories/message.rb', "#{templates_path}message_factory.rb")
54
+ create_file('spec/channels/chat_channel_spec.rb', "#{templates_path}chat_channel_spec.rb")
55
+ create_file('spec/channels/connection_spec.rb', "#{templates_path}connection_spec.rb")
56
+ end
57
+
58
+ def self.create_jbuilder_files(templates_path)
59
+ create_file("#{VIEWS_PATH}chats/index.json.jbuilder",
60
+ "#{templates_path}/index.json.jbuilder")
61
+ create_file("#{VIEWS_PATH}chats/show.json.jbuilder",
62
+ "#{templates_path}/show.json.jbuilder")
63
+ create_file("#{VIEWS_PATH}chats/_info.json.jbuilder",
64
+ "#{templates_path}/_info.json.jbuilder")
65
+ create_file("#{VIEWS_PATH}chats/_message.json.jbuilder",
66
+ "#{templates_path}/_message.json.jbuilder")
67
+ create_file("#{VIEWS_PATH}messages/_info.json.jbuilder",
68
+ "#{templates_path}/messages_create_info.json.jbuilder")
69
+ create_file("#{VIEWS_PATH}messages/create.json.jbuilder",
70
+ "#{templates_path}/messages_create.json.jbuilder")
71
+ end
72
+
73
+ def self.inject_into_files(templates_path)
74
+ inject_into_file('config/routes.rb', ":profile\n end", "#{templates_path}routes.rb")
75
+ inject_into_file('config/routes.rb', " end\n end", "#{templates_path}routes_2.rb")
76
+ inject_into_file('app/models/user.rb', "include DeviseTokenAuth::Concerns::User\n",
77
+ "#{templates_path}migration-models/user.rb")
78
+ inject_into_file('app/controllers/api/v1/sessions_controller.rb',
79
+ "include Api::Concerns::ActAsApiRequest\n",
80
+ "#{templates_path}sessions_controller.rb", true)
81
+ inject_into_file('spec/rails_helper.rb', "require 'simplecov'",
82
+ "#{templates_path}specs/rails_helper.rb")
83
+ end
84
+
85
+ def self.replace_in_files
86
+ replace_in_file('config/cable.yml', "test:\n adapter: async",
87
+ "test:\n adapter: test")
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,41 @@
1
+ module RailsBase
2
+ # This module handle specific functionalities
3
+ module Features
4
+ class Facebook
5
+ extend RailsBase::FileManipulation
6
+ extend RailsBase::CliActions
7
+
8
+ def self.install
9
+ templates_path = '../templates/facebook/'
10
+ inject_files(templates_path)
11
+ install_gem('koala', '3.0.0')
12
+ create_file('spec/requests/api/v1/sessions/facebook_spec.rb',
13
+ "#{templates_path}facebook_spec.rb")
14
+ create_file('app/services/facebook_service.rb',
15
+ "#{templates_path}facebook_service.rb")
16
+ append_to_file('apiary.apib', "#{templates_path}apiary.apib")
17
+ append_to_file('config/locales/en.yml', "#{templates_path}en.yml")
18
+ end
19
+
20
+ def self.inject_files(templates_path)
21
+ inject_into_file('config/routes.rb', 'resource :user, only: :update do',
22
+ "#{templates_path}routes.rb")
23
+ inject_into_file('app/controllers/api/v1/sessions_controller.rb',
24
+ "include Api::Concerns::ActAsApiRequest\n",
25
+ "#{templates_path}sessions_controller.rb", true)
26
+ inject_into_file('app/controllers/api/v1/sessions_controller.rb',
27
+ 'private',
28
+ "#{templates_path}sessions_controller_2.rb")
29
+ inject_into_file('spec/factories/user.rb',
30
+ "number(10) }\n end",
31
+ "#{templates_path}factories_user.rb")
32
+ inject_into_file('spec/models/user_spec.rb',
33
+ "it { should validate_uniqueness_of(:uid).scoped_to(:provider) }\n",
34
+ "#{templates_path}user_spec.rb")
35
+ inject_into_file('spec/routing/sessions_routing_spec.rb',
36
+ "sessions#create'\)\n end",
37
+ "#{templates_path}sessions_routing_spec.rb")
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ module RailsBase
2
+ # This module handle specific functionalities
3
+ module Features
4
+ class Twilio
5
+ extend RailsBase::FileManipulation
6
+ extend RailsBase::CliActions
7
+
8
+ def self.install
9
+ templates_path = '../templates/twilio/'
10
+ install_gem('twilio-ruby', '5.10.5')
11
+ create_file('app/services/twilio_service.rb',
12
+ "#{templates_path}twilio_service.rb")
13
+ create_file('config/initializers/twilio.rb',
14
+ "#{templates_path}twilio.rb")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ require 'commander/import'
2
+ require 'pathname'
3
+ require 'tty-file'
4
+
5
+ module RailsBase
6
+ # This module provides help to file manipulation
7
+ module FileManipulation
8
+ extend RailsBase::CliActions
9
+
10
+ def append_to_file(file_name, from)
11
+ from_file = File.expand_path("#{__dir__}/#{from}")
12
+ TTY::File.append_to_file(file_name, read_all_content(from_file))
13
+ end
14
+
15
+ def create_file(file_name, from)
16
+ from_file = File.expand_path("#{__dir__}/#{from}")
17
+ TTY::File.create_file(file_name, read_all_content(from_file))
18
+ end
19
+
20
+ def inject_into_file(file_name, after, from, extra_line_flag = false)
21
+ from_file = File.expand_path("#{__dir__}/#{from}")
22
+ content = read_all_content(from_file)
23
+ content += "\n" if extra_line_flag
24
+ begin
25
+ TTY::File.inject_into_file(file_name, content, after: "#{after}\n")
26
+ rescue StandardError => ex
27
+ say_something('Make sure you are on the root of your project please')
28
+ puts ex
29
+ end
30
+ end
31
+
32
+ def replace_in_file(file_name, old_content, new_content)
33
+ TTY::File.replace_in_file(file_name, old_content, new_content)
34
+ end
35
+
36
+ def read_all_content(file_name)
37
+ file = File.open(file_name, 'rb')
38
+ content = file.read
39
+ file.close
40
+ content
41
+ end
42
+
43
+ def install_gem(name, version)
44
+ if File.exist?('Gemfile')
45
+ unless read_all_content('Gemfile').include? name
46
+ gem_line = "gem '#{name}', '~> #{version}' \n"
47
+ TTY::File.append_to_file('Gemfile', gem_line)
48
+ system('bundle install')
49
+ end
50
+ else
51
+ say_something('Please go to your root folder :)')
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,13 @@
1
+ require 'commander/import'
2
+ require 'pathname'
3
+
4
+ module RailsBase
5
+ # This module provides help to interact with git
6
+ module GitActions
7
+ extend RailsBase::CliActions
8
+
9
+ def self.fetch_from_remote(version)
10
+ say_something("Fetching api version ... #{version}")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ module RailsBase
2
+ # This module provides help to deal with rails migrations
3
+ module RailsActions
4
+ extend RailsBase::FileManipulation
5
+
6
+ def new_migration(template_path, name)
7
+ migration = next_migration_number
8
+ create_file("db/migrate/#{migration}_#{name}",
9
+ "#{template_path}#{name}")
10
+ sleep(0.1)
11
+ end
12
+
13
+ def run_migrations
14
+ if File.exist?('config/database.yml')
15
+ `rake db:migrate`
16
+ else
17
+ say_something('Please now create a database.yml file and run `rake db:migrate`')
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def next_migration_number
24
+ Time.now.utc.strftime('%Y%m%d%H%M%S%L')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ require 'rs-rails-base/constants'
2
+ require 'rs-rails-base/cli_actions'
3
+ require 'rs-rails-base/file_manipulation'
4
+ require 'rs-rails-base/git_actions'
5
+ require 'rs-rails-base/rails_actions'
6
+ require 'rs-rails-base/commands'
7
+ require 'rs-rails-base/features'
8
+ require 'rs-rails-base/features/chat'
9
+ require 'rs-rails-base/features/facebook'
10
+ require 'rs-rails-base/features/twilio'