voluntary 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/README.rdoc +7 -7
  2. data/app/assets/javascripts/voluntary/base.js.coffee +38 -3
  3. data/app/assets/javascripts/voluntary/likes/list.js.coffee +71 -0
  4. data/app/assets/stylesheets/voluntary/base.css.sass +7 -3
  5. data/app/assets/stylesheets/voluntary/bootstrap_and_overrides.css.sass +11 -1
  6. data/app/controllers/concerns/voluntary/v1/base_controller.rb +9 -1
  7. data/app/controllers/likes_controller.rb +23 -0
  8. data/app/controllers/omniauth_callbacks_controller.rb +22 -0
  9. data/app/controllers/voluntary/application_controller.rb +3 -1
  10. data/app/helpers/voluntary/application_helper.rb +4 -0
  11. data/app/models/ability.rb +2 -2
  12. data/app/models/concerns/likeable.rb +16 -0
  13. data/app/models/concerns/user/liking.rb +11 -0
  14. data/app/models/concerns/user/omniauthable.rb +51 -0
  15. data/app/models/like.rb +22 -0
  16. data/app/models/user.rb +10 -7
  17. data/app/presenters/resources/user/form_presenter.rb +1 -1
  18. data/app/views/devise/shared/_links.erb +25 -0
  19. data/app/views/layouts/application.html.erb +22 -8
  20. data/app/views/shared/_likes_and_dislikes.html.erb +50 -0
  21. data/config/initializers/assets.rb +1 -0
  22. data/config/locales/en.yml +1 -1
  23. data/config/locales/general/en.yml +4 -0
  24. data/config/locales/resources/like/en.yml +7 -0
  25. data/config/routes.rb +6 -1
  26. data/db/migrate/20150119151714_add_provider_to_users.rb +6 -0
  27. data/db/migrate/20150119171210_add_lastfm_user_name_to_users.rb +13 -0
  28. data/db/migrate/20150126185249_create_likes.rb +13 -0
  29. data/lib/generators/voluntary/install/templates/app/views/layouts/application.html.erb +22 -8
  30. data/lib/generators/voluntary/product_dummy/templates/app/views/layouts/application.html.erb +37 -7
  31. data/lib/voluntary/version.rb +1 -1
  32. data/lib/voluntary.rb +2 -1
  33. metadata +45 -47
data/README.rdoc CHANGED
@@ -65,24 +65,24 @@ Run this in your console:
65
65
  cd ..
66
66
  rails plugin new voluntary_product_name --database=postgresql --skip-javascript --skip-test-unit --dummy-path=dummy --full
67
67
  cd voluntary_product_name
68
- # Add voluntary gem as a dependency to gemspec ('0.1.0.rc2').
68
+ # Add voluntary gem as a dependency to gemspec ('~> 0.2.1').
69
+ # Add development dependencies from the following gemspec to product's gemspec: https://github.com/volontariat/voluntary/blob/master/voluntary.gemspec
69
70
  # add "require 'voluntary'" to lib/voluntary_product_name.rb
70
- # Still needed?: Add development dependencies to dummy Gemfile, see voluntary_text_creation.
71
71
  # bundle install
72
72
  cd dummy
73
+ # Add development dependencies to dummy Gemfile, see voluntary_text_creation.
74
+ bundle install
73
75
  # change config/boot.rb to require bundler like here: https://github.com/volontariat/voluntary_scholarship/blob/master/dummy/config/boot.rb
74
76
  # change database names to #{product_name}_#{environment} and customize user credentials in config/database.yml
75
77
  # add gitignore file from voluntary: https://github.com/volontariat/voluntary/blob/master/.gitignore
76
- rake db:create:all && rails g voluntary:product_dummy # confirm all overwrite questions
77
- # Add "gemspec path: File.expand_path(File.dirname(__FILE__) + '/../')" to the top of the dummy's Gemfile
78
- bundle install # if it hangs at Fetching source index stop it and deactivate gems until it works and add them back one by one
78
+ bundle exec rake db:create:all && bundle exec rails g voluntary:product_dummy # confirm all overwrite questions except of Gemfile
79
79
  cd ..
80
80
  rails g migration add_product_name_product
81
81
  # fill migration file with template: https://github.com/volontariat/voluntary_scholarship/blob/master/db/migrate/20140306201232_add_scholarship_product.rb
82
82
  cd dummy
83
- rake railties:install:migrations
83
+ bundle exec rake railties:install:migrations
84
84
  # change database names to #{product_name}_#{environment} and customize user credentials in dummy/config/mongoid.yml
85
- rake db:migrate && rake db:test:clone_structure
85
+ bundle exec rake db:migrate && bundle exec rake db:test:clone_structure
86
86
  # create a class for your new product under app/models/product/product_name.rb like: https://github.com/volontariat/voluntary_scholarship/blob/master/app/models/product/scholarship.rb
87
87
  bundle exec rails s
88
88
 
@@ -9,9 +9,16 @@ $(document).ready ->
9
9
  $('.tabs').each (k, v) ->
10
10
  $(v).tabs
11
11
  autoHeight: false
12
-
12
+ beforeActivate: (event, ui) ->
13
+ unless ui.newTab.find('a').attr('href').indexOf('#') == 0
14
+ ui.newTab.find('.ajax_spinner').show()
15
+ ui.newPanel.empty()
16
+
13
17
  beforeLoad: (event, ui) ->
14
18
  ui.jqXHR.error ->
19
+ unless ui.tab.find('a').attr('href').indexOf('#') == 0
20
+ ui.tab.find('.ajax_spinner').hide()
21
+
15
22
  json = null
16
23
 
17
24
  try
@@ -22,11 +29,17 @@ $(document).ready ->
22
29
 
23
30
  ui.panel.html error
24
31
 
32
+ load: (event, ui) ->
33
+ unless ui.tab.find('a').attr('href').indexOf('#') == 0
34
+ ui.tab.find('.ajax_spinner').hide()
35
+
25
36
  $(document).on "click", ".ui-tabs-panel .pagination a", (event) ->
26
37
  event.preventDefault()
27
38
 
28
39
  $.get($(this).attr('href'), (data) ->
29
- $($('.ui-tabs-panel[style*="display: block"]')[0]).html(data)
40
+ panel = $('.ui-tabs-panel[style*="display: block"]')[0]
41
+ panel = $('.ui-tabs-panel')[0] unless panel
42
+ $(panel).html(data)
30
43
  ).fail (jqXHR, textStatus, errorThrown) ->
31
44
  json = null
32
45
 
@@ -67,4 +80,26 @@ $(document).ready ->
67
80
  });
68
81
 
69
82
  $( ".datepicker" ).each (k, v) ->
70
- $(v).datepicker({ dateFormat: "yy-mm-dd", changeYear: true, yearRange: "c-100:c+10" });
83
+ $(v).datepicker({ dateFormat: "yy-mm-dd", changeYear: true, yearRange: "c-100:c+10" });
84
+
85
+ $(document.body).on "click", ".remote_links", (event) ->
86
+ $this = $(this)
87
+
88
+ $.ajax(url: $this.attr('href'), type: "GET", dataType: "html").success (data) ->
89
+ $($this.data("replace")).html(data)
90
+
91
+ event.preventDefault()
92
+
93
+ $(document.body).on "click", ".remote_modal_link", (event) ->
94
+ $this = $(this)
95
+
96
+ $.ajax(url: $this.attr('href'), type: "GET", dataType: "html").success (data) ->
97
+ $('#bootstrap_modal').html(data)
98
+ $('#bootstrap_modal').modal('show')
99
+
100
+ event.preventDefault()
101
+
102
+ $(document.body).on "click", "#close_bootstrap_modal_button", (event) ->
103
+ $('#bootstrap_modal').modal('hide')
104
+ event.preventDefault()
105
+
@@ -0,0 +1,71 @@
1
+ window.Likes or= {}
2
+
3
+ window.Likes.List = class List
4
+ constructor: ->
5
+ $(document.body).on "click", ".like_link", (event) ->
6
+ event.preventDefault()
7
+ table = $(this).closest('table')
8
+
9
+ $.post("/like/" + table.data('target_type') + "/" + table.data('target_id')).done(=>
10
+ $(this).hide()
11
+ $(this).closest('table').find('.undo_like_link').show()
12
+ likes_count = parseInt($(this).closest('table').find('.likes_counter_column').text()) + 1
13
+ $(this).closest('table').find('.likes_counter_column').html(likes_count)
14
+ $(this).closest('table').find('.dislike_link').data('liked', true)
15
+
16
+ if $(this).data('disliked')
17
+ $(this).closest('table').find('.undo_dislike_link').hide()
18
+ $(this).closest('table').find('.dislike_link').show()
19
+ dislikes_count = parseInt($(this).closest('table').find('.dislikes_counter_column').text()) - 1
20
+ $(this).closest('table').find('.dislikes_counter_column').html(dislikes_count)
21
+ $(this).data('disliked', false)
22
+ )
23
+ $(document.body).on "click", ".undo_like_link", (event) ->
24
+ event.preventDefault()
25
+ table = $(this).closest('table')
26
+
27
+ $.post("/unlike/" + table.data('target_type') + "/" + table.data('target_id')).done(=>
28
+ $(this).hide()
29
+ $(this).closest('table').find('.like_link').show()
30
+ $(this).closest('table').find('.dislike_link').data('liked', false)
31
+ likes_count = parseInt($(this).closest('table').find('.likes_counter_column').text()) - 1
32
+ $(this).closest('table').find('.likes_counter_column').html(likes_count)
33
+ ).fail(->
34
+ alert "Undoing like failed!"
35
+ )
36
+
37
+ $(document.body).on "click", ".dislike_link", (event) ->
38
+ event.preventDefault()
39
+ table = $(this).closest('table')
40
+
41
+ $.post("/dislike/" + table.data('target_type') + "/" + table.data('target_id')).done(=>
42
+ event.preventDefault()
43
+ $(this).hide()
44
+ $(this).closest('table').find('.undo_dislike_link').show()
45
+ dislikes_count = parseInt($(this).closest('table').find('.dislikes_counter_column').text()) + 1
46
+ $(this).closest('table').find('.dislikes_counter_column').html(dislikes_count)
47
+ $(this).closest('table').find('.like_link').data('disliked', true)
48
+
49
+ if $(this).data('liked')
50
+ $(this).closest('table').find('.undo_like_link').hide()
51
+ $(this).closest('table').find('.like_link').show()
52
+ likes_count = parseInt($(this).closest('table').find('.likes_counter_column').text()) - 1
53
+ $(this).closest('table').find('.likes_counter_column').html(likes_count)
54
+ $(this).data('liked', false)
55
+ ).fail(->
56
+ alert "Disliking failed!"
57
+ )
58
+
59
+ $(document.body).on "click", ".undo_dislike_link", (event) ->
60
+ event.preventDefault()
61
+ table = $(this).closest('table')
62
+
63
+ $.post("/unlike/" + table.data('target_type') + "/" + table.data('target_id')).done(=>
64
+ $(this).hide()
65
+ $(this).closest('table').find('.dislike_link').show()
66
+ $(this).closest('table').find('.like_link').data('disliked', false)
67
+ dislikes_count = parseInt($(this).closest('table').find('.dislikes_counter_column').text()) - 1
68
+ $(this).closest('table').find('.dislikes_counter_column').html(dislikes_count)
69
+ ).fail(->
70
+ alert "Undoing dislike failed!"
71
+ )
@@ -41,11 +41,11 @@ code
41
41
 
42
42
  html, body, div
43
43
  font-family: Arial
44
- font-size: 10px
44
+ font-size: 12px
45
45
 
46
46
  .nav a
47
47
  font-family: Arial
48
- font-size: 10px
48
+ font-size: 12px
49
49
 
50
50
  .nested_comments
51
51
  margin-left: 30px
@@ -59,4 +59,8 @@ html, body, div
59
59
  .floating_form fieldset .control-group
60
60
  float: left
61
61
  margin-right: 10px
62
- margin-bottom: 0px
62
+ margin-bottom: 0px
63
+
64
+ .likes_and_dislikes_table td
65
+ background-color: transparent !important
66
+ border-top: 0px !important
@@ -1,4 +1,14 @@
1
1
  @import "twitter/bootstrap/responsive"
2
2
 
3
+ .list-striped
4
+ li:nth-child(odd)
5
+ background-color: #F9F9F9
6
+
3
7
  .nav a
4
- font-size: 14px !important
8
+ font-size: 14px !important
9
+
10
+ .modal-body
11
+ overflow-y: visible
12
+
13
+ .scrollable-modal-body
14
+ overflow-y: auto
@@ -8,9 +8,17 @@ module Voluntary
8
8
  rescue_from ActiveRecord::RecordNotFound, with: :not_found
9
9
  rescue_from Mongoid::Errors::DocumentNotFound, with: :not_found
10
10
 
11
- helper_method :parent, :application_navigation, :navigation_product_path, :navigation_product_name
11
+ helper_method :parent, :application_navigation, :navigation_product_path, :navigation_product_name, :voluntary_application_stylesheets, :voluntary_application_javascripts
12
12
  end
13
13
 
14
+ def voluntary_application_stylesheets
15
+ ['voluntary/application', 'application']
16
+ end
17
+
18
+ def voluntary_application_javascripts
19
+ ['voluntary/application', 'application']
20
+ end
21
+
14
22
  def parent
15
23
  @parent
16
24
  end
@@ -0,0 +1,23 @@
1
+ class LikesController < ApplicationController
2
+ def create
3
+ positive = request.original_url.match('/like/') ? true : false
4
+ like_or_dislike = current_user.likes_or_dislikes.where(target_type: params[:target_type], target_id: params[:target_id]).first
5
+
6
+ if like_or_dislike
7
+ like_or_dislike.update_attribute(:positive, positive)
8
+ else
9
+ current_user.likes_or_dislikes.create!(positive: positive, target_type: params[:target_type], target_id: params[:target_id])
10
+ end
11
+
12
+ render nothing: true
13
+ end
14
+
15
+ def destroy
16
+ like_or_dislike = current_user.likes_or_dislikes.where(target_type: params[:target_type], target_id: params[:target_id]).first
17
+
18
+ raise ActiveRecord::RecordNotFound unless like_or_dislike
19
+
20
+ like_or_dislike.destroy!
21
+ render nothing: true
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
2
+ def all
3
+ user = User.from_omniauth(request.env['omniauth.auth'])
4
+
5
+ if user.persisted?
6
+ kind = case request.env['omniauth.auth']['provider']
7
+ when 'google_oauth2' then 'Google'
8
+ else request.env['omniauth.auth']['provider'].titleize
9
+ end
10
+
11
+ flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: kind
12
+ sign_in_and_redirect user, event: :authentication
13
+ else
14
+ session['devise.user_attributes'] = user.attributes
15
+ redirect_to new_user_registration_url
16
+ end
17
+ end
18
+
19
+ alias_method :facebook, :all
20
+ alias_method :google_oauth2, :all
21
+ alias_method :lastfm, :all
22
+ end
@@ -13,7 +13,9 @@ class Voluntary::ApplicationController < ActionController::Base
13
13
  protected
14
14
 
15
15
  def after_sign_in_path_for(resource_or_scope)
16
- if resource_or_scope.main_role.is_a? Role::ProjectOwner
16
+ if resource_or_scope.provider == 'lastfm'
17
+ music_path
18
+ elsif resource_or_scope.main_role.is_a? Role::ProjectOwner
17
19
  workflow_project_owner_index_path
18
20
  elsif resource_or_scope.main_role.is_a? Role::User
19
21
  workflow_user_index_path
@@ -75,5 +75,9 @@ module Voluntary
75
75
  klass = ::Voluntary::ApplicationHelper.root_model_class_name_helper(record)
76
76
  eval("#{klass.tableize.singularize}_path(record)")
77
77
  end
78
+
79
+ def name_with_apostrophe(value)
80
+ value =~ /s$/i ? "#{value}'" : "#{value}'s"
81
+ end
78
82
  end
79
83
  end
@@ -27,9 +27,9 @@ class Ability
27
27
  if user.present?
28
28
  can :destroy, User, id: user.id
29
29
 
30
- can [:new, :create], [Area, Profession, Project, Vacancy, Candidature, Comment]
30
+ can [:new, :create], [Area, Profession, Project, Vacancy, Candidature, Comment, Like]
31
31
  can :assign, Task
32
- can [:update, :cancel, :review], Task, user_id: user.id
32
+ can [:update, :cancel, :review], [Task, Like], user_id: user.id
33
33
 
34
34
  {
35
35
  user_id: [Product, Organization, Project, Comment, ProjectUser, Result],
@@ -0,0 +1,16 @@
1
+ module Likeable
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ belongs_to :target, polymorphic: true
6
+
7
+ has_many :likes, -> { where(positive: true) }, dependent: :delete_all, as: :target
8
+ has_many :likers, class_name: 'User', through: :likes, source: :user
9
+ has_many :dislikes, -> { where(positive: false) }, class_name: 'Like', dependent: :delete_all, as: :target
10
+ has_many :dislikers, class_name: 'User', through: :dislikes, source: :user
11
+ end
12
+
13
+ def update_likes_counter
14
+ self.class.where(id: self.id).update_all likes_count: self.likes.count, dislikes_count: self.dislikes.count
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ class User
2
+ module Liking
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ has_many :likes_or_dislikes, class_name: 'Like', dependent: :destroy
7
+ has_many :likes, -> { where(positive: true) }, dependent: :destroy
8
+ has_many :dislikes, -> { where(positive: false) }, class_name: 'Like', dependent: :destroy
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,51 @@
1
+ class User
2
+ module Omniauthable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def from_omniauth(auth)
7
+ user = User.where(provider: auth.provider, uid: auth.uid).first
8
+
9
+ unless user
10
+ user = User.new
11
+ user.provider = auth.provider
12
+ user.uid = auth.uid
13
+ user.first_name = auth.info.first_name
14
+ user.last_name = auth.info.last_name
15
+ user.email = auth.info.email
16
+ user.lastfm_user_name = auth.info.nickname if user.provider == 'lastfm'
17
+ user.save
18
+ end
19
+
20
+ user
21
+ end
22
+
23
+ def new_with_session(params, session)
24
+ if session["devise.user_attributes"]
25
+ new(session["devise.user_attributes"], without_protection: true) do |user|
26
+ user.attributes = params
27
+ user.valid?
28
+ end
29
+ else
30
+ super
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def password_required?
37
+ super && provider.blank?
38
+ end
39
+
40
+ def email_required?
41
+ super && provider.blank?
42
+ end
43
+
44
+ def update_with_password(params, *options)
45
+ if encrypted_password.blank?
46
+ update_attributes(params, *options)
47
+ else
48
+ super
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ class Like < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :target, polymorphic: true
4
+
5
+ scope :for_targets, ->(type, ids) do
6
+ where('target_type = :type AND target_id IN(:ids)', type: type, ids: ids)
7
+ end
8
+
9
+ validates :target_id, presence: true, uniqueness: { scope: [:target_type, :user_id] }
10
+ validates :target_type, presence: true
11
+ validates :user_id, presence: true
12
+
13
+ attr_accessible :positive, :target_id, :target_type
14
+
15
+ after_save do
16
+ self.target.update_likes_counter
17
+ end
18
+
19
+ after_destroy do
20
+ self.target.update_likes_counter
21
+ end
22
+ end
data/app/models/user.rb CHANGED
@@ -2,6 +2,8 @@ class User < ActiveRecord::Base
2
2
  include ::Applicat::Mvc::Model::Resource::Base
3
3
  include User::Listable
4
4
  include User::Extensions
5
+ include User::Omniauthable
6
+ include User::Liking
5
7
 
6
8
  belongs_to :main_role, class_name: 'Role'
7
9
  belongs_to :profession
@@ -19,12 +21,12 @@ class User < ActiveRecord::Base
19
21
 
20
22
  serialize :foreign_languages
21
23
 
22
- validates :name, presence: true, uniqueness: true
23
- validates :first_name, presence: true
24
- validates :last_name, presence: true
25
- validates :language, presence: true
26
- validates :country, presence: true
27
- validates :interface_language, presence: true
24
+ validates :name, presence: true, uniqueness: true, if: 'provider.blank?'
25
+ validates :first_name, presence: true, if: 'provider.blank?'
26
+ validates :last_name, presence: true, if: 'provider.blank?'
27
+ validates :language, presence: true, if: 'provider.blank?'
28
+ validates :country, presence: true, if: 'provider.blank?'
29
+ validates :interface_language, presence: true, if: 'provider.blank?'
28
30
 
29
31
  attr_accessible :name, :password, :password_confirmation, :remember_me, :text, :language, :first_name, :last_name,
30
32
  :salutation, :marital_status, :family_status, :date_of_birth, :place_of_birth, :citizenship,
@@ -36,7 +38,8 @@ class User < ActiveRecord::Base
36
38
  # :timeoutable, :token_authenticatable, :lockable,
37
39
  # :lock_strategy => :none, :unlock_strategy => :nones
38
40
  devise :database_authenticatable, :registerable,# :confirmable,
39
- :recoverable, :rememberable, :trackable, :validatable
41
+ :recoverable, :rememberable, :trackable, :validatable
42
+ devise :omniauthable, omniauth_providers: [:facebook, :google_oauth2, :lastfm]
40
43
 
41
44
  extend FriendlyId
42
45
 
@@ -4,7 +4,7 @@ class Resources::User::FormPresenter < ResourcePresenter
4
4
  :name, :first_name, :last_name, :email,
5
5
  ]
6
6
 
7
- list += [:password, :password_confirmation] if resource.new_record?
7
+ list += [:password, :password_confirmation] if resource.new_record? && resource.provider.blank?
8
8
 
9
9
  list += [
10
10
  :country, :language, :interface_language, :foreign_language_tokens, :profession,
@@ -0,0 +1,25 @@
1
+ <%- if controller_name != 'sessions' %>
2
+ <%= link_to "Sign in", new_session_path(resource_name) %><br />
3
+ <% end -%>
4
+
5
+ <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6
+ <%= link_to "Sign up", new_registration_path(resource_name) %><br />
7
+ <% end -%>
8
+
9
+ <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
10
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
11
+ <% end -%>
12
+
13
+ <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14
+ <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
15
+ <% end -%>
16
+
17
+ <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18
+ <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
19
+ <% end -%>
20
+
21
+ <%- if devise_mapping.omniauthable? %>
22
+ <%- resource_class.omniauth_providers.each do |provider| %>
23
+ <%= link_to "Sign in with #{provider.to_s.titleize}", user_omniauth_authorize_path(provider) %><br />
24
+ <% end -%>
25
+ <% end -%>
@@ -1,15 +1,16 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= t('layout.title') %></title>
4
+ <title><%= (yield(:title).blank? ? '' : yield(:title) + ' - ') + t('layout.title') %></title>
5
5
  <meta charset='utf-8'>
6
6
  <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
- <%= stylesheet_link_tag 'voluntary/application', media: 'all' %>
9
- <%= stylesheet_link_tag 'application', media: 'all' %>
8
+ <%= stylesheet_link_tag *voluntary_application_stylesheets, media: 'all' %>
10
9
  <link href="//netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.css" rel="stylesheet"/>
11
10
  </head>
12
11
  <body>
12
+ <div id="bootstrap_modal" class="modal hide fade"></div>
13
+
13
14
  <%= render 'layouts/shared/navigation' %>
14
15
 
15
16
  <section id="dialog">
@@ -26,18 +27,32 @@
26
27
  </div>
27
28
  <% end %>
28
29
  <div class="row-fluid">
29
- <% if sidenav(@sidenav_links_count).present? %>
30
+ <% if sidenav(@sidenav_links_count).present? || content_for?(:search) %>
30
31
  <div class="span9">
31
- <%= breadcrumbs %>
32
+ <% if content_for?(:breadcrumbs) %>
33
+ <div class="nav">
34
+ <%= yield :breadcrumbs %>
35
+ </div>
36
+ <% else %>
37
+ <%= breadcrumbs %>
38
+ <% end %>
32
39
 
33
40
  <%= yield %>
34
41
  </div>
35
42
  <div class="span3">
43
+ <%= yield :search %>
44
+
36
45
  <%= sidenav(@sidenav_links_count) %>
37
46
  </div>
38
47
  <% else %>
39
48
  <div class="span12">
40
- <%= breadcrumbs %>
49
+ <% if content_for?(:breadcrumbs) %>
50
+ <div class="nav">
51
+ <%= yield :breadcrumbs %>
52
+ </div>
53
+ <% else %>
54
+ <%= breadcrumbs %>
55
+ <% end %>
41
56
 
42
57
  <%= yield %>
43
58
  </div>
@@ -51,8 +66,7 @@
51
66
  </div>
52
67
  </div>
53
68
  </div>
54
- <%= javascript_include_tag 'voluntary/application' %>
55
- <%= javascript_include_tag 'application' %>
69
+ <%= javascript_include_tag *voluntary_application_javascripts %>
56
70
  <%= yield :javascript_includes %>
57
71
  <%= csrf_meta_tags %>
58
72
  <%= javascript_tag do %>
@@ -0,0 +1,50 @@
1
+ <table class="likes_and_dislikes_table" data-target_type="<%= target.class.name %>" data-target_id="<%= target.id %>">
2
+ <tr>
3
+ <% if user_signed_in? %>
4
+ <td style="padding-right: 5px">
5
+ <a
6
+ href="#" class="like_link"
7
+ data-disliked="<%= (likes[target.id].present? && !likes[target.id].positive?).inspect %>"
8
+ style="<%= likes[target.id].present? && likes[target.id].positive? ? 'display:none;' : '' %>"
9
+ >
10
+ <%= t('likes.actions.like') %>
11
+ </a>
12
+ <a
13
+ href="#" class="undo_like_link"
14
+ style="<%= likes[target.id].present? && likes[target.id].positive? ? '' : 'display:none;' %>"
15
+ >
16
+ <%= t('likes.actions.undo_like') %>
17
+ </a>
18
+ </td>
19
+ <% end %>
20
+ <td>
21
+ <i class="icon-thumbs-up"></i>
22
+ </td>
23
+ <td class="likes_counter_column" style="padding-right: 5px">
24
+ <%= target.likes_count %>
25
+ </td>
26
+ <% if user_signed_in? %>
27
+ <td style="padding-right: 5px">
28
+ <a
29
+ href="#" class="dislike_link"
30
+ data-liked="<%= (likes[target.id].present? && likes[target.id].positive?).inspect %>"
31
+ style="<%= likes[target.id].present? && !likes[target.id].positive? ? 'display:none;' : '' %>"
32
+ >
33
+ <%= t('likes.actions.dislike') %>
34
+ </a>
35
+ <a
36
+ href="#" class="undo_dislike_link"
37
+ style="<%= likes[target.id].present? && !likes[target.id].positive? ? '' : 'display:none;' %>"
38
+ >
39
+ <%= t('likes.actions.undo_dislike') %>
40
+ </a>
41
+ </td>
42
+ <% end %>
43
+ <td>
44
+ <i class="icon-thumbs-down"></i>
45
+ </td>
46
+ <td class="dislikes_counter_column">
47
+ <%= target.dislikes_count %>
48
+ </td>
49
+ </tr>
50
+ </table>
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/
@@ -11,7 +11,7 @@ en:
11
11
  title: About Us
12
12
 
13
13
  layout:
14
- title: Volontari.at - Creative Open Crowdsource Platform
14
+ title: Volontari.at (Open Source Crowdsourcing Platform)
15
15
 
16
16
  home:
17
17
  index:
@@ -2,17 +2,20 @@ en:
2
2
  general:
3
3
  index:
4
4
  title: Home
5
+ search: Search
5
6
  new: New
6
7
  denied: Denied
7
8
  accepted: Accepted
8
9
  edit: Edit
9
10
  destroy: Destroy
10
11
  remove: Remove
12
+ close: Close
11
13
  not_available: n/a
12
14
  steps: Steps
13
15
  error: Error
14
16
  list_action: Back to the overview
15
17
  details: Details
18
+ export: Export
16
19
  form:
17
20
  errors_count: '%{count} prohibited this object from being saved:'
18
21
  successfully_created: Creation successful
@@ -39,6 +42,7 @@ en:
39
42
  user_id: User
40
43
  vacancy_id: Vacancy
41
44
  roles: Roles
45
+ position: Position
42
46
 
43
47
  activerecord:
44
48
  models:
@@ -0,0 +1,7 @@
1
+ en:
2
+ likes:
3
+ actions:
4
+ like: Like
5
+ dislike: Dislike
6
+ undo_like: Unlike
7
+ undo_dislike: Undo Dislike
data/config/routes.rb CHANGED
@@ -9,6 +9,7 @@ end
9
9
  Rails.application.routes.draw do
10
10
  devise_for :users, controllers: {
11
11
  registrations: 'devise_extensions/registrations',
12
+ omniauth_callbacks: 'omniauth_callbacks'
12
13
  }
13
14
 
14
15
  resources :areas do
@@ -132,7 +133,7 @@ Rails.application.routes.draw do
132
133
  resources :comments, only: [:new, :edit, :create, :update, :destroy]
133
134
 
134
135
  resources :users do
135
- resources :projects, only: :index
136
+ resources :projects, only: [:index, :new]
136
137
  resources :candidatures, only: :index
137
138
 
138
139
  collection do
@@ -154,4 +155,8 @@ Rails.application.routes.draw do
154
155
  get :autocomplete
155
156
  end
156
157
  end
158
+
159
+ post 'like/:target_type/:target_id' => 'likes#create'
160
+ post 'dislike/:target_type/:target_id' => 'likes#create'
161
+ post 'unlike/:target_type/:target_id' => 'likes#destroy'
157
162
  end
@@ -0,0 +1,6 @@
1
+ class AddProviderToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :provider, :string
4
+ add_column :users, :uid, :string
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ class AddLastfmUserNameToUsers < ActiveRecord::Migration
2
+ def up
3
+ add_column :users, :lastfm_user_name, :string
4
+
5
+ change_column :users, :email, :string, null: true
6
+ end
7
+
8
+ def down
9
+ remove_column :users, :lastfm_user_name
10
+
11
+ change_column :users, :email, :string, null: false
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateLikes < ActiveRecord::Migration
2
+ def change
3
+ create_table :likes do |t|
4
+ t.boolean :positive, default: true
5
+ t.integer :target_id
6
+ t.string :target_type, limit: 60, null: false
7
+ t.integer :user_id
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :likes, [:target_id, :user_id, :target_type], unique: true
12
+ end
13
+ end
@@ -1,15 +1,16 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= t('layout.title') %></title>
4
+ <title><%= (yield(:title).blank? ? '' : yield(:title) + ' - ') + t('layout.title') %></title>
5
5
  <meta charset='utf-8'>
6
6
  <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
- <%= stylesheet_link_tag 'voluntary/application', media: 'all' %>
9
- <%= stylesheet_link_tag 'application', media: 'all' %>
8
+ <%= stylesheet_link_tag *voluntary_application_stylesheets, media: 'all' %>
10
9
  <link href="//netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.css" rel="stylesheet"/>
11
10
  </head>
12
11
  <body>
12
+ <div id="bootstrap_modal" class="modal hide fade"></div>
13
+
13
14
  <%= render 'layouts/shared/navigation' %>
14
15
 
15
16
  <section id="dialog">
@@ -26,18 +27,32 @@
26
27
  </div>
27
28
  <% end %>
28
29
  <div class="row-fluid">
29
- <% if sidenav(@sidenav_links_count).present? %>
30
+ <% if sidenav(@sidenav_links_count).present? || content_for?(:search) %>
30
31
  <div class="span9">
31
- <%= breadcrumbs %>
32
+ <% if content_for?(:breadcrumbs) %>
33
+ <div class="nav">
34
+ <%= yield :breadcrumbs %>
35
+ </div>
36
+ <% else %>
37
+ <%= breadcrumbs %>
38
+ <% end %>
32
39
 
33
40
  <%= yield %>
34
41
  </div>
35
42
  <div class="span3">
43
+ <%= yield :search %>
44
+
36
45
  <%= sidenav(@sidenav_links_count) %>
37
46
  </div>
38
47
  <% else %>
39
48
  <div class="span12">
40
- <%= breadcrumbs %>
49
+ <% if content_for?(:breadcrumbs) %>
50
+ <div class="nav">
51
+ <%= yield :breadcrumbs %>
52
+ </div>
53
+ <% else %>
54
+ <%= breadcrumbs %>
55
+ <% end %>
41
56
 
42
57
  <%= yield %>
43
58
  </div>
@@ -51,8 +66,7 @@
51
66
  </div>
52
67
  </div>
53
68
  </div>
54
- <%= javascript_include_tag 'voluntary/application' %>
55
- <%= javascript_include_tag 'application' %>
69
+ <%= javascript_include_tag *voluntary_application_javascripts %>
56
70
  <%= yield :javascript_includes %>
57
71
  <%= csrf_meta_tags %>
58
72
  <%= javascript_tag do %>
@@ -1,15 +1,23 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= t('layout.title') %></title>
4
+ <title><%= (yield(:title).blank? ? '' : yield(:title) + ' - ') + t('layout.title') %></title>
5
5
  <meta charset='utf-8'>
6
6
  <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
7
- <%= stylesheet_link_tag 'voluntary/application', media: 'all' %>
8
- <%= stylesheet_link_tag 'application', media: 'all' %>
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <%= stylesheet_link_tag *voluntary_application_stylesheets, media: 'all' %>
9
+ <link href="//netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.css" rel="stylesheet"/>
9
10
  </head>
10
11
  <body>
12
+ <div id="bootstrap_modal" class="modal hide fade"></div>
13
+
11
14
  <%= render 'layouts/shared/navigation' %>
12
15
 
16
+ <section id="dialog">
17
+ <img alt="Ajax-loader-small" class="hide " id="dialog_body_spinner" src="<%=image_path('voluntary/spinner.gif')%>"/>
18
+ <div id="dialog_body"/>
19
+ </section>
20
+
13
21
  <div class="container-fluid">
14
22
  <% unless flash.empty? %>
15
23
  <div class="row-fluid">
@@ -19,14 +27,36 @@
19
27
  </div>
20
28
  <% end %>
21
29
  <div class="row-fluid">
30
+ <% if sidenav(@sidenav_links_count).present? || content_for?(:search) %>
22
31
  <div class="span9">
23
- <%= breadcrumbs %>
32
+ <% if content_for?(:breadcrumbs) %>
33
+ <div class="nav">
34
+ <%= yield :breadcrumbs %>
35
+ </div>
36
+ <% else %>
37
+ <%= breadcrumbs %>
38
+ <% end %>
24
39
 
25
40
  <%= yield %>
26
41
  </div>
27
42
  <div class="span3">
28
- <%= sidenav %>
43
+ <%= yield :search %>
44
+
45
+ <%= sidenav(@sidenav_links_count) %>
29
46
  </div>
47
+ <% else %>
48
+ <div class="span12">
49
+ <% if content_for?(:breadcrumbs) %>
50
+ <div class="nav">
51
+ <%= yield :breadcrumbs %>
52
+ </div>
53
+ <% else %>
54
+ <%= breadcrumbs %>
55
+ <% end %>
56
+
57
+ <%= yield %>
58
+ </div>
59
+ <% end %>
30
60
  </div>
31
61
  </div>
32
62
  <div class="container-fluid">
@@ -36,8 +66,8 @@
36
66
  </div>
37
67
  </div>
38
68
  </div>
39
- <%= javascript_include_tag 'voluntary/application' %>
40
- <%= javascript_include_tag 'application' %>
69
+ <%= javascript_include_tag *voluntary_application_javascripts %>
70
+ <%= yield :javascript_includes %>
41
71
  <%= csrf_meta_tags %>
42
72
  <%= javascript_tag do %>
43
73
  <%= yield :top_javascript %>
@@ -1,3 +1,3 @@
1
1
  module Voluntary
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
data/lib/voluntary.rb CHANGED
@@ -11,7 +11,8 @@ require 'messagebus_ruby_api'
11
11
  require 'devise'
12
12
  require 'omniauth'
13
13
  require 'omniauth-facebook'
14
- require 'omniauth-tumblr'
14
+ require 'omniauth-google-oauth2'
15
+ require 'omniauth-lastfm'
15
16
  require 'cancan'
16
17
  require 'foreigner'
17
18
  require 'ancestry'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voluntary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-06 00:00:00.000000000 Z
12
+ date: 2015-02-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -242,7 +242,7 @@ dependencies:
242
242
  requirements:
243
243
  - - ~>
244
244
  - !ruby/object:Gem::Version
245
- version: 1.0.3
245
+ version: 1.2.2
246
246
  type: :runtime
247
247
  prerelease: false
248
248
  version_requirements: !ruby/object:Gem::Requirement
@@ -250,7 +250,7 @@ dependencies:
250
250
  requirements:
251
251
  - - ~>
252
252
  - !ruby/object:Gem::Version
253
- version: 1.0.3
253
+ version: 1.2.2
254
254
  - !ruby/object:Gem::Dependency
255
255
  name: omniauth-facebook
256
256
  requirement: !ruby/object:Gem::Requirement
@@ -258,7 +258,7 @@ dependencies:
258
258
  requirements:
259
259
  - - ~>
260
260
  - !ruby/object:Gem::Version
261
- version: 1.6.0
261
+ version: 2.0.0
262
262
  type: :runtime
263
263
  prerelease: false
264
264
  version_requirements: !ruby/object:Gem::Requirement
@@ -266,15 +266,15 @@ dependencies:
266
266
  requirements:
267
267
  - - ~>
268
268
  - !ruby/object:Gem::Version
269
- version: 1.6.0
269
+ version: 2.0.0
270
270
  - !ruby/object:Gem::Dependency
271
- name: omniauth-tumblr
271
+ name: omniauth-google-oauth2
272
272
  requirement: !ruby/object:Gem::Requirement
273
273
  none: false
274
274
  requirements:
275
275
  - - ~>
276
276
  - !ruby/object:Gem::Version
277
- version: '1.1'
277
+ version: 0.2.6
278
278
  type: :runtime
279
279
  prerelease: false
280
280
  version_requirements: !ruby/object:Gem::Requirement
@@ -282,7 +282,23 @@ dependencies:
282
282
  requirements:
283
283
  - - ~>
284
284
  - !ruby/object:Gem::Version
285
- version: '1.1'
285
+ version: 0.2.6
286
+ - !ruby/object:Gem::Dependency
287
+ name: omniauth-lastfm
288
+ requirement: !ruby/object:Gem::Requirement
289
+ none: false
290
+ requirements:
291
+ - - ~>
292
+ - !ruby/object:Gem::Version
293
+ version: 0.0.6
294
+ type: :runtime
295
+ prerelease: false
296
+ version_requirements: !ruby/object:Gem::Requirement
297
+ none: false
298
+ requirements:
299
+ - - ~>
300
+ - !ruby/object:Gem::Version
301
+ version: 0.0.6
286
302
  - !ruby/object:Gem::Dependency
287
303
  name: foreigner
288
304
  requirement: !ruby/object:Gem::Requirement
@@ -907,22 +923,6 @@ dependencies:
907
923
  - - ! '>='
908
924
  - !ruby/object:Gem::Version
909
925
  version: '0'
910
- - !ruby/object:Gem::Dependency
911
- name: auto_html
912
- requirement: !ruby/object:Gem::Requirement
913
- none: false
914
- requirements:
915
- - - ! '>='
916
- - !ruby/object:Gem::Version
917
- version: '0'
918
- type: :runtime
919
- prerelease: false
920
- version_requirements: !ruby/object:Gem::Requirement
921
- none: false
922
- requirements:
923
- - - ! '>='
924
- - !ruby/object:Gem::Version
925
- version: '0'
926
926
  - !ruby/object:Gem::Dependency
927
927
  name: jquery-rails
928
928
  requirement: !ruby/object:Gem::Requirement
@@ -976,17 +976,17 @@ dependencies:
976
976
  requirement: !ruby/object:Gem::Requirement
977
977
  none: false
978
978
  requirements:
979
- - - ! '>='
979
+ - - ~>
980
980
  - !ruby/object:Gem::Version
981
- version: '0'
981
+ version: 1.6.4
982
982
  type: :runtime
983
983
  prerelease: false
984
984
  version_requirements: !ruby/object:Gem::Requirement
985
985
  none: false
986
986
  requirements:
987
- - - ! '>='
987
+ - - ~>
988
988
  - !ruby/object:Gem::Version
989
- version: '0'
989
+ version: 1.6.4
990
990
  - !ruby/object:Gem::Dependency
991
991
  name: jquery-rails
992
992
  requirement: !ruby/object:Gem::Requirement
@@ -1035,22 +1035,6 @@ dependencies:
1035
1035
  - - ~>
1036
1036
  - !ruby/object:Gem::Version
1037
1037
  version: 2.3.2.1
1038
- - !ruby/object:Gem::Dependency
1039
- name: auto_html
1040
- requirement: !ruby/object:Gem::Requirement
1041
- none: false
1042
- requirements:
1043
- - - ~>
1044
- - !ruby/object:Gem::Version
1045
- version: 1.5.3
1046
- type: :runtime
1047
- prerelease: false
1048
- version_requirements: !ruby/object:Gem::Requirement
1049
- none: false
1050
- requirements:
1051
- - - ~>
1052
- - !ruby/object:Gem::Version
1053
- version: 1.5.3
1054
1038
  - !ruby/object:Gem::Dependency
1055
1039
  name: simple-navigation-bootstrap
1056
1040
  requirement: !ruby/object:Gem::Requirement
@@ -1479,6 +1463,7 @@ files:
1479
1463
  - app/assets/javascripts/voluntary/application.js
1480
1464
  - app/assets/javascripts/voluntary/base.js.coffee
1481
1465
  - app/assets/javascripts/voluntary/functions.js
1466
+ - app/assets/javascripts/voluntary/likes/list.js.coffee
1482
1467
  - app/assets/javascripts/voluntary/users.js.coffee
1483
1468
  - app/assets/stylesheets/voluntary/application.css
1484
1469
  - app/assets/stylesheets/voluntary/base.css.sass
@@ -1489,6 +1474,8 @@ files:
1489
1474
  - app/controllers/concerns/voluntary/v1/base_controller.rb
1490
1475
  - app/controllers/devise_extensions/registrations_controller.rb
1491
1476
  - app/controllers/home_controller.rb
1477
+ - app/controllers/likes_controller.rb
1478
+ - app/controllers/omniauth_callbacks_controller.rb
1492
1479
  - app/controllers/organizations_controller.rb
1493
1480
  - app/controllers/pages_controller.rb
1494
1481
  - app/controllers/products_controller.rb
@@ -1526,9 +1513,13 @@ files:
1526
1513
  - app/models/candidature.rb
1527
1514
  - app/models/column.rb
1528
1515
  - app/models/comment.rb
1516
+ - app/models/concerns/likeable.rb
1529
1517
  - app/models/concerns/user/extensions.rb
1518
+ - app/models/concerns/user/liking.rb
1530
1519
  - app/models/concerns/user/listable.rb
1520
+ - app/models/concerns/user/omniauthable.rb
1531
1521
  - app/models/history_tracker.rb
1522
+ - app/models/like.rb
1532
1523
  - app/models/list.rb
1533
1524
  - app/models/list_item.rb
1534
1525
  - app/models/mongo_db_document.rb
@@ -1584,6 +1575,7 @@ files:
1584
1575
  - app/views/comments/new.html.erb
1585
1576
  - app/views/devise/mailer/confirmation_instructions.html.erb
1586
1577
  - app/views/devise/registrations/new.html.erb
1578
+ - app/views/devise/shared/_links.erb
1587
1579
  - app/views/general/wizard.html.erb
1588
1580
  - app/views/kaminari/_first_page.html.erb
1589
1581
  - app/views/kaminari/_gap.html.erb
@@ -1617,6 +1609,7 @@ files:
1617
1609
  - app/views/projects/new.html.erb
1618
1610
  - app/views/projects/show.html.erb
1619
1611
  - app/views/shared/_comments.html.erb
1612
+ - app/views/shared/_likes_and_dislikes.html.erb
1620
1613
  - app/views/shared/collection/_list.html.erb
1621
1614
  - app/views/shared/collection/_table.html.erb
1622
1615
  - app/views/shared/form/_error_messages.html.erb
@@ -1663,6 +1656,7 @@ files:
1663
1656
  - app/views/workflow/user/product/areas/show.html.erb
1664
1657
  - app/views/workflow/user/projects/show.html.erb
1665
1658
  - config/initializers/1_initialize_app_config.rb
1659
+ - config/initializers/assets.rb
1666
1660
  - config/initializers/devise.rb
1667
1661
  - config/initializers/filter_parameters_logging.rb
1668
1662
  - config/initializers/friendly_id.rb
@@ -1678,6 +1672,7 @@ files:
1678
1672
  - config/locales/resources/area/en.yml
1679
1673
  - config/locales/resources/candidature/en.yml
1680
1674
  - config/locales/resources/comment/en.yml
1675
+ - config/locales/resources/like/en.yml
1681
1676
  - config/locales/resources/organization/en.yml
1682
1677
  - config/locales/resources/page/en.yml
1683
1678
  - config/locales/resources/product/en.yml
@@ -1706,6 +1701,9 @@ files:
1706
1701
  - db/migrate/20130817090734_create_lists.rb
1707
1702
  - db/migrate/20131018143613_replace_user_by_polymorphic_resource_in_candidatures.rb
1708
1703
  - db/migrate/20140307113214_add_user_id_to_organizations.rb
1704
+ - db/migrate/20150119151714_add_provider_to_users.rb
1705
+ - db/migrate/20150119171210_add_lastfm_user_name_to_users.rb
1706
+ - db/migrate/20150126185249_create_likes.rb
1709
1707
  - db/seeds.rb
1710
1708
  - lib/api_constraints.rb
1711
1709
  - lib/applicat/mvc/controller/error_handling.rb
@@ -1852,7 +1850,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
1852
1850
  version: '0'
1853
1851
  segments:
1854
1852
  - 0
1855
- hash: 1000069296358120593
1853
+ hash: 1073244219484482667
1856
1854
  required_rubygems_version: !ruby/object:Gem::Requirement
1857
1855
  none: false
1858
1856
  requirements:
@@ -1861,7 +1859,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1861
1859
  version: '0'
1862
1860
  segments:
1863
1861
  - 0
1864
- hash: 1000069296358120593
1862
+ hash: 1073244219484482667
1865
1863
  requirements: []
1866
1864
  rubyforge_project:
1867
1865
  rubygems_version: 1.8.23