alondra 0.0.3

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 (117) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +22 -0
  3. data/Gemfile.lock +166 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +177 -0
  6. data/Rakefile +34 -0
  7. data/alondra.gemspec +23 -0
  8. data/app/assets/javascripts/alondra-client.js.coffee.erb +71 -0
  9. data/app/assets/javascripts/moz_websocket.js +5 -0
  10. data/app/assets/javascripts/vendor/jquery.json-2.2.js +178 -0
  11. data/app/assets/javascripts/vendor/json2.js +480 -0
  12. data/app/assets/javascripts/vendor/swfobject.js +4 -0
  13. data/app/assets/javascripts/vendor/web_socket.js +379 -0
  14. data/app/assets/swf/WebSocketMain.swf +0 -0
  15. data/app/helpers/alondra_helper.rb +24 -0
  16. data/lib/alondra/changes_callbacks.rb +52 -0
  17. data/lib/alondra/changes_push.rb +23 -0
  18. data/lib/alondra/channel.rb +84 -0
  19. data/lib/alondra/command.rb +38 -0
  20. data/lib/alondra/command_dispatcher.rb +22 -0
  21. data/lib/alondra/connection.rb +52 -0
  22. data/lib/alondra/event.rb +74 -0
  23. data/lib/alondra/event_listener.rb +86 -0
  24. data/lib/alondra/event_router.rb +27 -0
  25. data/lib/alondra/listener_callback.rb +37 -0
  26. data/lib/alondra/message.rb +35 -0
  27. data/lib/alondra/message_queue.rb +70 -0
  28. data/lib/alondra/message_queue_client.rb +71 -0
  29. data/lib/alondra/push_controller.rb +53 -0
  30. data/lib/alondra/pushing.rb +14 -0
  31. data/lib/alondra/server.rb +44 -0
  32. data/lib/alondra/session_parser.rb +57 -0
  33. data/lib/alondra.rb +80 -0
  34. data/lib/generators/alondra/USAGE +8 -0
  35. data/lib/generators/alondra/alondra_generator.rb +7 -0
  36. data/lib/generators/alondra/templates/alondra +33 -0
  37. data/lib/tasks/alondra_tasks.rake +4 -0
  38. data/script/rails +6 -0
  39. data/test/dummy/Rakefile +7 -0
  40. data/test/dummy/app/assets/javascripts/application.js +9 -0
  41. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  42. data/test/dummy/app/controllers/application_controller.rb +14 -0
  43. data/test/dummy/app/controllers/chats_controller.rb +85 -0
  44. data/test/dummy/app/controllers/messages_controller.rb +12 -0
  45. data/test/dummy/app/controllers/sessions_controller.rb +20 -0
  46. data/test/dummy/app/controllers/users_controller.rb +30 -0
  47. data/test/dummy/app/helpers/application_helper.rb +2 -0
  48. data/test/dummy/app/helpers/chats_helper.rb +6 -0
  49. data/test/dummy/app/helpers/error_messages_helper.rb +23 -0
  50. data/test/dummy/app/helpers/layout_helper.rb +22 -0
  51. data/test/dummy/app/mailers/.gitkeep +0 -0
  52. data/test/dummy/app/models/.gitkeep +0 -0
  53. data/test/dummy/app/models/chat.rb +5 -0
  54. data/test/dummy/app/models/message.rb +4 -0
  55. data/test/dummy/app/models/user.rb +37 -0
  56. data/test/dummy/app/views/chats/_form.html.erb +21 -0
  57. data/test/dummy/app/views/chats/edit.html.erb +6 -0
  58. data/test/dummy/app/views/chats/index.html.erb +23 -0
  59. data/test/dummy/app/views/chats/new.html.erb +5 -0
  60. data/test/dummy/app/views/chats/show.html.erb +49 -0
  61. data/test/dummy/app/views/layouts/application.html.erb +19 -0
  62. data/test/dummy/app/views/sessions/new.html.erb +15 -0
  63. data/test/dummy/app/views/shared/_message.js.erb +1 -0
  64. data/test/dummy/app/views/users/_form.html.erb +20 -0
  65. data/test/dummy/app/views/users/edit.html.erb +3 -0
  66. data/test/dummy/app/views/users/index.html.erb +25 -0
  67. data/test/dummy/app/views/users/new.html.erb +5 -0
  68. data/test/dummy/app/views/users/show.html.erb +15 -0
  69. data/test/dummy/config/application.rb +42 -0
  70. data/test/dummy/config/boot.rb +10 -0
  71. data/test/dummy/config/database.yml +31 -0
  72. data/test/dummy/config/environment.rb +5 -0
  73. data/test/dummy/config/environments/development.rb +27 -0
  74. data/test/dummy/config/environments/production.rb +54 -0
  75. data/test/dummy/config/environments/test.rb +39 -0
  76. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  77. data/test/dummy/config/initializers/inflections.rb +10 -0
  78. data/test/dummy/config/initializers/mime_types.rb +5 -0
  79. data/test/dummy/config/initializers/secret_token.rb +7 -0
  80. data/test/dummy/config/initializers/session_store.rb +9 -0
  81. data/test/dummy/config/initializers/wrap_parameters.rb +12 -0
  82. data/test/dummy/config/locales/en.yml +5 -0
  83. data/test/dummy/config/routes.rb +19 -0
  84. data/test/dummy/config.ru +4 -0
  85. data/test/dummy/db/migrate/20110719090458_create_chats.rb +9 -0
  86. data/test/dummy/db/migrate/20110719090538_create_messages.rb +10 -0
  87. data/test/dummy/db/migrate/20110720193249_create_users.rb +16 -0
  88. data/test/dummy/db/schema.rb +38 -0
  89. data/test/dummy/lib/controller_authentication.rb +48 -0
  90. data/test/dummy/log/.gitkeep +0 -0
  91. data/test/dummy/public/404.html +26 -0
  92. data/test/dummy/public/422.html +26 -0
  93. data/test/dummy/public/500.html +26 -0
  94. data/test/dummy/public/favicon.ico +0 -0
  95. data/test/dummy/public/stylesheets/application.css +75 -0
  96. data/test/dummy/script/rails +6 -0
  97. data/test/integration/push_changes_test.rb +41 -0
  98. data/test/integration/push_messages_test.rb +40 -0
  99. data/test/models/channel_test.rb +49 -0
  100. data/test/models/command_test.rb +29 -0
  101. data/test/models/configuration_test.rb +22 -0
  102. data/test/models/connection_test.rb +18 -0
  103. data/test/models/event_listener_test.rb +217 -0
  104. data/test/models/event_router_test.rb +7 -0
  105. data/test/models/message_queue_client_test.rb +26 -0
  106. data/test/models/message_queue_test.rb +70 -0
  107. data/test/models/pushing_test.rb +34 -0
  108. data/test/performance/message_queue_performance.rb +66 -0
  109. data/test/support/factories.rb +19 -0
  110. data/test/support/integration_helper.rb +18 -0
  111. data/test/support/integration_test.rb +6 -0
  112. data/test/support/mocks/bogus_event.rb +15 -0
  113. data/test/support/mocks/mock_connection.rb +24 -0
  114. data/test/support/mocks/mock_event_router.rb +12 -0
  115. data/test/support/mocks/mock_listener.rb +9 -0
  116. data/test/test_helper.rb +14 -0
  117. metadata +316 -0
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # Set up gems listed in the Gemfile.
3
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', File.dirname(__FILE__))
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
7
+ require 'daemons'
8
+
9
+
10
+ log_dir = File.expand_path('../log', File.dirname(__FILE__))
11
+
12
+ options = {
13
+ :app_name => 'alondra',
14
+ :dir_mode => :script,
15
+ :dir => 'log',
16
+ :log_dir => log_dir
17
+ }
18
+
19
+ Daemons.run_proc 'alondra', options do
20
+
21
+ ENV["ALONDRA_SERVER"] = 'true'
22
+ require_relative File.join('..', 'config', 'environment')
23
+
24
+ log_path = File.join(log_path, 'alondra.log')
25
+ Rails.logger = ActiveSupport::BufferedLogger.new(log_path)
26
+
27
+ Alondra::Alondra.start_server!
28
+
29
+ Rails.logger.info "Started alondra server... #{EM.reactor_running?}"
30
+
31
+ EM.reactor_thread.join
32
+ Rails.logger.info 'Alondra server terminated'
33
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :alondra do
3
+ # # Task goes here
4
+ # end
data/script/rails ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ #!/usr/bin/env ruby
3
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
4
+
5
+ ENGINE_PATH = File.expand_path('../..', __FILE__)
6
+ load File.expand_path('../../test/dummy/script/rails', __FILE__)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,9 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require_tree .
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
@@ -0,0 +1,14 @@
1
+ class ApplicationController < ActionController::Base
2
+ include ControllerAuthentication
3
+ protect_from_forgery
4
+
5
+ def current_user
6
+ @current_user ||= find_current_user
7
+ end
8
+
9
+ private
10
+
11
+ def find_current_user
12
+ User.find(session[:user_id]) if session[:user_id].present?
13
+ end
14
+ end
@@ -0,0 +1,85 @@
1
+ class ChatsController < ApplicationController
2
+ before_filter :login_required
3
+
4
+ # GET /chats
5
+ # GET /chats.json
6
+ def index
7
+ @chats = Chat.all
8
+
9
+ respond_to do |format|
10
+ format.html # index.html.erb
11
+ format.json { render json: @chats }
12
+ end
13
+ end
14
+
15
+ # GET /chats/1
16
+ # GET /chats/1.json
17
+ def show
18
+ @chat = Chat.find(params[:id])
19
+
20
+ respond_to do |format|
21
+ format.html # show.html.erb
22
+ format.json { render json: @chat }
23
+ end
24
+ end
25
+
26
+ # GET /chats/new
27
+ # GET /chats/new.json
28
+ def new
29
+ @chat = Chat.new
30
+
31
+ respond_to do |format|
32
+ format.html # new.html.erb
33
+ format.json { render json: @chat }
34
+ end
35
+ end
36
+
37
+ # GET /chats/1/edit
38
+ def edit
39
+ @chat = Chat.find(params[:id])
40
+ end
41
+
42
+ # POST /chats
43
+ # POST /chats.json
44
+ def create
45
+ @chat = Chat.new(params[:chat])
46
+
47
+ respond_to do |format|
48
+ if @chat.save
49
+ format.html { redirect_to @chat, notice: 'Chat was successfully created.' }
50
+ format.json { render json: @chat, status: :created, location: @chat }
51
+ else
52
+ format.html { render action: "new" }
53
+ format.json { render json: @chat.errors, status: :unprocessable_entity }
54
+ end
55
+ end
56
+ end
57
+
58
+ # PUT /chats/1
59
+ # PUT /chats/1.json
60
+ def update
61
+ @chat = Chat.find(params[:id])
62
+
63
+ respond_to do |format|
64
+ if @chat.update_attributes(params[:chat])
65
+ format.html { redirect_to @chat, notice: 'Chat was successfully updated.' }
66
+ format.json { head :ok }
67
+ else
68
+ format.html { render action: "edit" }
69
+ format.json { render json: @chat.errors, status: :unprocessable_entity }
70
+ end
71
+ end
72
+ end
73
+
74
+ # DELETE /chats/1
75
+ # DELETE /chats/1.json
76
+ def destroy
77
+ @chat = Chat.find(params[:id])
78
+ @chat.destroy
79
+
80
+ respond_to do |format|
81
+ format.html { redirect_to chats_url }
82
+ format.json { head :ok }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,12 @@
1
+ class MessagesController < ApplicationController
2
+ respond_to :html, :js, :json
3
+
4
+ def create
5
+ @chat = Chat.find(params[:chat_id])
6
+ @message = @chat.messages.build(params[:message])
7
+
8
+ @message.save
9
+
10
+ respond_with @message, :location => @chat
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ class SessionsController < ApplicationController
2
+ def new
3
+ end
4
+
5
+ def create
6
+ user = User.authenticate(params[:login], params[:password])
7
+ if user
8
+ session[:user_id] = user.id
9
+ redirect_to_target_or_default root_url, :notice => "Logged in successfully."
10
+ else
11
+ flash.now[:alert] = "Invalid login or password."
12
+ render :action => 'new'
13
+ end
14
+ end
15
+
16
+ def destroy
17
+ session[:user_id] = nil
18
+ redirect_to root_url, :notice => "You have been logged out."
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ class UsersController < ApplicationController
2
+ before_filter :login_required, :except => [:new, :create]
3
+
4
+ def new
5
+ @user = User.new
6
+ end
7
+
8
+ def create
9
+ @user = User.new(params[:user])
10
+ if @user.save
11
+ session[:user_id] = @user.id
12
+ redirect_to root_url, :notice => "Thank you for signing up! You are now logged in."
13
+ else
14
+ render :action => 'new'
15
+ end
16
+ end
17
+
18
+ def edit
19
+ @user = current_user
20
+ end
21
+
22
+ def update
23
+ @user = current_user
24
+ if @user.update_attributes(params[:user])
25
+ redirect_to root_url, :notice => "Your profile has been updated."
26
+ else
27
+ render :action => 'edit'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,6 @@
1
+ module ChatsHelper
2
+
3
+ def present_users
4
+ @present_users = [] #||= Alondra::Channel['/messages/'].users
5
+ end
6
+ end
@@ -0,0 +1,23 @@
1
+ module ErrorMessagesHelper
2
+ # Render error messages for the given objects. The :message and :header_message options are allowed.
3
+ def error_messages_for(*objects)
4
+ options = objects.extract_options!
5
+ options[:header_message] ||= I18n.t(:"activerecord.errors.header", :default => "Invalid Fields")
6
+ options[:message] ||= I18n.t(:"activerecord.errors.message", :default => "Correct the following errors and try again.")
7
+ messages = objects.compact.map { |o| o.errors.full_messages }.flatten
8
+ unless messages.empty?
9
+ content_tag(:div, :class => "error_messages") do
10
+ list_items = messages.map { |msg| content_tag(:li, msg) }
11
+ content_tag(:h2, options[:header_message]) + content_tag(:p, options[:message]) + content_tag(:ul, list_items.join.html_safe)
12
+ end
13
+ end
14
+ end
15
+
16
+ module FormBuilderAdditions
17
+ def error_messages(options = {})
18
+ @template.error_messages_for(@object, options)
19
+ end
20
+ end
21
+ end
22
+
23
+ ActionView::Helpers::FormBuilder.send(:include, ErrorMessagesHelper::FormBuilderAdditions)
@@ -0,0 +1,22 @@
1
+ # These helper methods can be called in your template to set variables to be used in the layout
2
+ # This module should be included in all views globally,
3
+ # to do so you may need to add this line to your ApplicationController
4
+ # helper :layout
5
+ module LayoutHelper
6
+ def title(page_title, show_title = true)
7
+ content_for(:title) { h(page_title.to_s) }
8
+ @show_title = show_title
9
+ end
10
+
11
+ def show_title?
12
+ @show_title
13
+ end
14
+
15
+ def stylesheet(*args)
16
+ content_for(:head) { stylesheet_link_tag(*args) }
17
+ end
18
+
19
+ def javascript(*args)
20
+ content_for(:head) { javascript_include_tag(*args) }
21
+ end
22
+ end
File without changes
File without changes
@@ -0,0 +1,5 @@
1
+ class Chat < ActiveRecord::Base
2
+ has_many :messages
3
+ push :changes
4
+
5
+ end
@@ -0,0 +1,4 @@
1
+ class Message < ActiveRecord::Base
2
+ belongs_to :chat
3
+ push :changes, :to => :chat
4
+ end
@@ -0,0 +1,37 @@
1
+ require 'digest'
2
+ require 'securerandom'
3
+
4
+ class User < ActiveRecord::Base
5
+ # new columns need to be added here to be writable through mass assignment
6
+ attr_accessible :username, :email, :password, :password_confirmation
7
+
8
+ attr_accessor :password
9
+ before_save :prepare_password
10
+
11
+ validates_presence_of :username
12
+ validates_uniqueness_of :username, :email, :allow_blank => true
13
+ validates_format_of :username, :with => /^[-\w\._@]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@"
14
+ validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
15
+ validates_presence_of :password, :on => :create
16
+ validates_confirmation_of :password
17
+ validates_length_of :password, :minimum => 4, :allow_blank => true
18
+
19
+ # login can be either username or email address
20
+ def self.authenticate(login, pass)
21
+ user = find_by_username(login) || find_by_email(login)
22
+ return user if user && user.password_hash == user.encrypt_password(pass)
23
+ end
24
+
25
+ def encrypt_password(pass)
26
+ Digest::SHA2.hexdigest(pass + password_salt)
27
+ end
28
+
29
+ private
30
+
31
+ def prepare_password
32
+ unless password.blank?
33
+ self.password_salt = SecureRandom.hex(16)
34
+ self.password_hash = encrypt_password(password)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ <%= form_for(@chat) do |f| %>
2
+ <% if @chat.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@chat.errors.count, "error") %> prohibited this chat from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @chat.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %><br />
16
+ <%= f.text_field :name %>
17
+ </div>
18
+ <div class="actions">
19
+ <%= f.submit %>
20
+ </div>
21
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing chat</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @chat %> |
6
+ <%= link_to 'Back', chats_path %>
@@ -0,0 +1,23 @@
1
+ <h1>Listing chats</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th></th>
7
+ <th></th>
8
+ <th></th>
9
+ </tr>
10
+
11
+ <% @chats.each do |chat| %>
12
+ <tr>
13
+ <td><%= chat.name %></td>
14
+ <td><%= link_to 'Show', chat %></td>
15
+ <td><%= link_to 'Edit', edit_chat_path(chat) %></td>
16
+ <td><%= link_to 'Destroy', chat, confirm: 'Are you sure?', method: :delete %></td>
17
+ </tr>
18
+ <% end %>
19
+ </table>
20
+
21
+ <br />
22
+
23
+ <%= link_to 'New Chat', new_chat_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New chat</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', chats_path %>
@@ -0,0 +1,49 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <b>Chat name:</b>
5
+ <span id="chat_name"><%= @chat.name %></span>
6
+ </p>
7
+
8
+ <ul id="users">
9
+ <h3>Present users</h3>
10
+ <% present_users.each do |user| %>
11
+ <%= user.username %>
12
+ <% end %>
13
+ </ul>
14
+
15
+ <div id="messages">
16
+ <h3>Messages</h3>
17
+ <% @chat.messages.each do |msg| %>
18
+ <div class="message">
19
+ <%= simple_format msg.text %>
20
+ </div>
21
+ <hr/>
22
+ <% end %>
23
+ </div>
24
+
25
+ <%= form_for [@chat, @chat.messages.build] do |f| %>
26
+ <h3>New Message</h3>
27
+ <%= f.text_area :text, :rows => 5 %>
28
+
29
+ <p>
30
+ <%= f.submit 'send' %>
31
+ </p>
32
+ <% end %>
33
+
34
+ <%= link_to 'Back', chats_path %>
35
+
36
+ <%= javascript_include_tag 'alondra-client' %>
37
+
38
+ <script type="text/javascript">
39
+ var client = new AlondraClient('localhost', <%= Alondra::Alondra.config.port %>, '<%= chat_path(@path) %>', '<%= encrypted_token %>');
40
+
41
+ $(client).bind('subscribed.Chat', function(event, resource){
42
+ console.log('Received subscribed event!');
43
+ $('#messages').append('<div class="message">Subscribed to channel</div>');
44
+ })
45
+
46
+ $(client).bind('updated.Chat', function(event, resource){
47
+ $('#chat_name').text(resource.name);
48
+ })
49
+ </script>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= content_for?(:title) ? yield(:title) : "Untitled" %></title>
5
+ <%= stylesheet_link_tag "application" %>
6
+ <%= javascript_include_tag "application" %>
7
+ <%= csrf_meta_tag %>
8
+ <%= yield(:head) %>
9
+ </head>
10
+ <body>
11
+ <div id="container">
12
+ <% flash.each do |name, msg| %>
13
+ <%= content_tag :div, msg, :id => "flash_#{name}" %>
14
+ <% end %>
15
+ <%= content_tag :h1, yield(:title) if show_title? %>
16
+ <%= yield %>
17
+ </div>
18
+ </body>
19
+ </html>
@@ -0,0 +1,15 @@
1
+ <% title "Log in" %>
2
+
3
+ <p>Don't have an account? <%= link_to "Sign up!", signup_path %></p>
4
+
5
+ <%= form_tag sessions_path do %>
6
+ <p>
7
+ <%= label_tag :login, "Username or Email Address" %><br />
8
+ <%= text_field_tag :login, params[:login] %>
9
+ </p>
10
+ <p>
11
+ <%= label_tag :password %><br />
12
+ <%= password_field_tag :password %>
13
+ </p>
14
+ <p><%= submit_tag "Log in" %></p>
15
+ <% end %>
@@ -0,0 +1 @@
1
+ $('#messages').append('<div class="rendered_message"> <%= @user.username %> says <%= @text %></div>');
@@ -0,0 +1,20 @@
1
+ <%= form_for @user do |f| %>
2
+ <%= f.error_messages %>
3
+ <p>
4
+ <%= f.label :username %><br />
5
+ <%= f.text_field :username %>
6
+ </p>
7
+ <p>
8
+ <%= f.label :email, "Email Address" %><br />
9
+ <%= f.text_field :email %>
10
+ </p>
11
+ <p>
12
+ <%= f.label :password %><br />
13
+ <%= f.password_field :password %>
14
+ </p>
15
+ <p>
16
+ <%= f.label :password_confirmation, "Confirm Password" %><br />
17
+ <%= f.password_field :password_confirmation %>
18
+ </p>
19
+ <p><%= f.submit (@user.new_record? ? "Sign up" : "Update") %></p>
20
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% title "Update Profile" %>
2
+
3
+ <%= render 'form' %>
@@ -0,0 +1,25 @@
1
+ <h1>Listing users</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Email</th>
6
+ <th>Access token</th>
7
+ <th></th>
8
+ <th></th>
9
+ <th></th>
10
+ </tr>
11
+
12
+ <% @users.each do |user| %>
13
+ <tr>
14
+ <td><%= user.email %></td>
15
+ <td><%= user.access_token %></td>
16
+ <td><%= link_to 'Show', user %></td>
17
+ <td><%= link_to 'Edit', edit_user_path(user) %></td>
18
+ <td><%= link_to 'Destroy', user, confirm: 'Are you sure?', method: :delete %></td>
19
+ </tr>
20
+ <% end %>
21
+ </table>
22
+
23
+ <br />
24
+
25
+ <%= link_to 'New User', new_user_path %>
@@ -0,0 +1,5 @@
1
+ <% title "Sign up" %>
2
+
3
+ <p>Already have an account? <%= link_to "Log in", login_path %>.</p>
4
+
5
+ <%= render 'form' %>
@@ -0,0 +1,15 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <b>Email:</b>
5
+ <%= @user.email %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>Access token:</b>
10
+ <%= @user.access_token %>
11
+ </p>
12
+
13
+
14
+ <%= link_to 'Edit', edit_user_path(@user) %> |
15
+ <%= link_to 'Back', users_path %>
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require
6
+ require "alondra"
7
+
8
+ module Dummy
9
+ class Application < Rails::Application
10
+ config.autoload_paths << "#{config.root}/lib" # Settings in config/environments/* take precedence over those specified here.
11
+ # Application configuration should go into files in config/initializers
12
+ # -- all .rb files in that directory are automatically loaded.
13
+
14
+ # Custom directories with classes and modules you want to be autoloadable.
15
+ # config.autoload_paths += %W(#{config.root}/extras)
16
+
17
+ # Only load the plugins named here, in the order given (default is alphabetical).
18
+ # :all can be used as a placeholder for all plugins not explicitly named.
19
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
20
+
21
+ # Activate listeners that should always be running.
22
+ # config.active_record.listeners = :cacher, :garbage_collector, :forum_observer
23
+
24
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
25
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
26
+ # config.time_zone = 'Central Time (US & Canada)'
27
+
28
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
29
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
30
+ # config.i18n.default_locale = :de
31
+
32
+ # Configure the default encoding used in templates for Ruby 1.9.
33
+ config.encoding = "utf-8"
34
+
35
+ # Configure sensitive parameters which will be filtered from the log file.
36
+ config.filter_parameters += [:password]
37
+
38
+ # Enable the asset pipeline
39
+ config.assets.enabled = true
40
+ end
41
+ end
42
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift File.expand_path('../../../../lib', __FILE__)