dog_ears 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 709c098d8cff2b4bc02746ea114aeca43e94ec35
4
+ data.tar.gz: 01728ee8bdc68c526b421a11d0011a12dee9b72d
5
+ SHA512:
6
+ metadata.gz: 0b4d0b5e1168aff07808acac3773a4ca4bfbe44e77212c6ec8ac47fdbd257872f121127e6f227adea64a17e3235ea4701b99afc4d0f9558e62fd264f5247d241
7
+ data.tar.gz: b16a5362c48123887315fec8e2c6b13c4f66932ae145cee8e54e2b62374d596366fc9e0a611bd47b8be6fa785ab6dacf49c5579f9d42e46345d56b83f4eb848e
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,46 @@
1
+ = DogEars
2
+
3
+ Gem for generic in-app-bookmarks and bookmark-sharing between users. Slightly WIP.
4
+
5
+ == Gemfile
6
+
7
+ <pre>
8
+ gem 'dog_ears'
9
+ </pre>
10
+
11
+
12
+ == routes.rb
13
+
14
+ Add <tt>dog_ears</tt> in the appropriate place
15
+
16
+ == controller
17
+
18
+ Add a BookmarksController at the appropriate place. This needs to inherit fro your apps controllers, such that <tt>current_user</tt> is available:
19
+
20
+ <pre>
21
+ class Admin::...::BookmarksController < Admin::...::ApplicationController
22
+ include DogEars::Controller
23
+ end
24
+ </pre>
25
+
26
+ == views/layout
27
+
28
+ In you layout, use <tt><%= dog_ears admin_..._bookmarks_path %></tt> to inject the required html-code
29
+
30
+ == stylesheets/javascript
31
+
32
+ <tt>//= require dog_ears/application</tt> as usual :)
33
+
34
+ == Migrations
35
+
36
+ <tt>rake dog_ears:install:migrations</tt>
37
+
38
+ and then
39
+
40
+ <tt>rake db:migrate</tt>
41
+
42
+ == License
43
+
44
+ This project rocks and uses MIT-LICENSE.
45
+
46
+ Copyright (c) 2013 by Peter Horn, Provideal GmbH
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'DogEars'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,148 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+
14
+ jQuery(function($){
15
+ function init_dog_ears(url) {
16
+ var dog_ears = $('#dog-ears')
17
+ var listbox = dog_ears.find("#bookmark-list");
18
+ var form = dog_ears.find('form#bookmark-form');
19
+ var shareform = dog_ears.find('form#bookmark-transfer-form');
20
+ var path = dog_ears.data('path');
21
+ var method = dog_ears.data('method');
22
+ var title = dog_ears.data('title');
23
+ var id = dog_ears.data('id');
24
+ var pinned = dog_ears.hasClass('pinned');
25
+
26
+ dog_ears.find('#bookmark-pin').click(function(e) {
27
+ e.stopPropagation();
28
+ if(!pinned) {
29
+ $('#dog-ears-bookmark-level').val(0);
30
+ $('#dog-ears-bookmark-name').val(document.title);
31
+ form.show();
32
+ } else {
33
+ $.ajax(url + "/" + id, {
34
+ type: 'delete',
35
+ success: new_component
36
+ })
37
+ }
38
+ return false;
39
+ });
40
+
41
+ dog_ears.find('.bookmark-title').click(function(e) {
42
+ e.stopPropagation();
43
+ $('#dog-ears-bookmark-level').val(0);
44
+ $('#dog-ears-bookmark-name').val(title);
45
+ form.show();
46
+ return false;
47
+ });
48
+
49
+
50
+ function new_component(data) {
51
+ dog_ears.replaceWith(data);
52
+ init_dog_ears(url);
53
+ }
54
+
55
+ dog_ears.find('span.level').click(function(e) {
56
+ e.stopPropagation();
57
+ var span = $(this);
58
+ $.ajax(url, {
59
+ type: 'get',
60
+ data: { level: span.data('level') },
61
+ success: show_bookmarks
62
+ });
63
+ listbox.css('background-color', span.css('background-color'));
64
+ listbox.css('color', span.css('color'));
65
+ });
66
+
67
+ function show_bookmarks(data) {
68
+ listbox.html();
69
+ var ul = $("<ul/>");
70
+ $.each(data, function(i,bm) {
71
+ var a = $("<a/>").attr('href', bm.path).html(bm.title);
72
+ ul.append($("<li/>").html(a));
73
+ });
74
+ listbox.html(ul);
75
+ listbox.show();
76
+ }
77
+
78
+ dog_ears.find('button[data-level]').click(function(){
79
+ dog_ears.find('button[type="submit"]').attr('class', $(this).attr('class')).removeClass('btn-mini');
80
+ dog_ears.find('#dog-ears-bookmark-level').val($(this).data('level'));
81
+ })
82
+
83
+ form.submit(function(event){
84
+ event.stopPropagation();
85
+ var level = $('#dog-ears-bookmark-level').val();
86
+ var name = $('#dog-ears-bookmark-name').val();
87
+ $.ajax(url, {
88
+ data: {
89
+ path: path,
90
+ title: name,
91
+ level: level
92
+ },
93
+ type: 'post',
94
+ success: new_component
95
+ })
96
+ form.hide();
97
+ return false;
98
+ });
99
+
100
+ $('#dog-ears').click(function(event){
101
+ event.stopPropagation();
102
+ });
103
+
104
+ dog_ears.find('#bookmark-share').click(function(e) {
105
+ e.stopPropagation();
106
+ $.ajax(url + "/get_users", {
107
+ type: 'get',
108
+ success: show_share_form
109
+ });
110
+ return false;
111
+ });
112
+
113
+ function show_share_form(data) {
114
+ var select = $('select#dog-ears-new-user');
115
+ select.html();
116
+ $.each(data, function(id,name){
117
+ var option = $('<option>');
118
+ option.val(id);
119
+ option.html(name);
120
+ select.append(option);
121
+ });
122
+ shareform.show();
123
+ }
124
+
125
+ shareform.submit(function(){
126
+ var uid = $('select#dog-ears-new-user option:selected').val();
127
+ $.ajax(url + "/" + id + "/share", {
128
+ type: 'post',
129
+ data: { user_id: uid },
130
+ success: new_component
131
+ })
132
+ return false;
133
+ });
134
+
135
+ }
136
+
137
+ $('html').click(function() {
138
+ $('#bookmark-form').hide();
139
+ $('#bookmark-list').hide();
140
+ $('#bookmark-transfer-form').hide();
141
+ });
142
+
143
+ // $(document).on('click', '#dog_ears', function(event){
144
+ // event.stopPropagation();
145
+ // });
146
+
147
+ init_dog_ears($("#dog-ears").data('url'));
148
+ });
@@ -0,0 +1,98 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ */
12
+
13
+ div#dog-ears {
14
+ width: auto;
15
+ min-width: 20px;
16
+ height: 20px;
17
+ background-color: lightgray;
18
+ position: fixed;
19
+ right: 0px;
20
+ bottom: 0px;
21
+ z-index: 12000;
22
+ border: 1px solid gray;
23
+ padding: 5px;
24
+ line-height: 15px;
25
+
26
+ i#bookmark-pin:hover, span.level {
27
+ cursor: pointer;
28
+ }
29
+
30
+ .bookmark-title {
31
+ display: none;
32
+ }
33
+
34
+ &.pinned {
35
+ .bookmark-title {
36
+ display: inline-block;
37
+ }
38
+ }
39
+
40
+ #bookmark-list, #bookmark-form, #bookmark-transfer-form {
41
+ white-space: nowrap;
42
+ position: fixed;
43
+ bottom: 32px;
44
+ right: 0px;
45
+ max-width: 400px;
46
+ max-height: 400px;
47
+ z-index: 12001;
48
+ display: none;
49
+ background-color: lightgray;
50
+ border: 1px solid gray;
51
+ padding: 5px;
52
+ margin: 0;
53
+
54
+ a {
55
+ color: inherit;
56
+ }
57
+ }
58
+
59
+ #bookmark-list {
60
+ padding: 0px;
61
+ overflow: scroll;
62
+
63
+ ul {
64
+ padding: 0;
65
+ margin: 0;
66
+ list-style-type: none;
67
+
68
+ li {
69
+ padding: 5px;
70
+ border-bottom: 1px solid white;
71
+
72
+ &:last-child {
73
+ border-bottom: none;
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ #bookmark-form {
80
+ bottom: 0px;
81
+ padding: 10px;
82
+ width: 300px;
83
+ height: 70px;
84
+
85
+ input[type=text] {
86
+ width: 240px;
87
+ }
88
+ }
89
+
90
+ #bookmark-transfer-form {
91
+ bottom: 0px;
92
+ padding: 10px;
93
+
94
+ select {
95
+ margin-right: 10px;
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,4 @@
1
+ module DogEars
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module ApplicationHelper
2
+ include DogEarsHelper
3
+ end
@@ -0,0 +1,23 @@
1
+ module DogEars
2
+ class Bookmark < ActiveRecord::Base
3
+ # attr_accessible :title, :body
4
+ LEVELS = ['none', 'info', 'success', 'warning', 'important']
5
+ validates_inclusion_of :level, in: LEVELS
6
+
7
+ belongs_to :user
8
+
9
+ scope :for_user, ->(user) { where(user_id: user.id) }
10
+
11
+ def self.for_user_and_path(user,path)
12
+ for_user(user).where(path: path).first
13
+ end
14
+
15
+ def self.count_by_levels
16
+ cbl = group(:level).count
17
+ LEVELS.inject({}) do |a,e|
18
+ a[e] = cbl[e] if cbl[e] && cbl[e] > 0
19
+ a
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ <% path ||= request.env['PATH_INFO'] %>
2
+ <% method ||= request.method %>
3
+ <%= content_tag :div, id: 'dog-ears', class: (b && 'pinned'),
4
+ data: {path: path, method: method,
5
+ url: bookmark_url, title: b.try(:title), id: b.try(:id) } do %>
6
+ <% if method == 'GET' && !b %>
7
+ <button class="btn btn-mini" type="button" id='bookmark-pin'><i class="icon-pushpin"></i></button>
8
+ <% end %>
9
+ <span class="bookmark-title label label-<%= b.try(:level) %>"><%= b.try(:title) %></span>
10
+ <% if b %>
11
+ <button class="btn btn-mini" type="button" id='bookmark-pin'><i class="icon-remove"></i></button>
12
+ <button class="btn btn-mini" type="button" id='bookmark-share'><i class="icon-share"></i></button>
13
+ <% end %>
14
+ <% DogEars::Bookmark.for_user(current_user).count_by_levels.each do |l,c| %>
15
+ <span class="badge badge-<%= l %> level" data-level="<%= l %>"><%= c %></span>
16
+ <% end %>
17
+ <div id="bookmark-list"></div>
18
+ <form class="form" id="bookmark-form">
19
+ <div class="input-append">
20
+ <input type="text" id="dog-ears-bookmark-name" />
21
+ <button class="btn" type="submit"><i class="icon-pushpin"></i></button>
22
+ </div>
23
+ <div style="display:block">
24
+ <input type="hidden" id="dog-ears-bookmark-level" value="0" />
25
+ <button data-level="0" class="btn btn-mini" type="button"><i class="icon-flag"></i></button>
26
+ <button data-level="1" class="btn btn-mini btn-primary" type="button"><i class="icon-flag"></i></button>
27
+ <button data-level="2" class="btn btn-mini btn-success" type="button"><i class="icon-flag"></i></button>
28
+ <button data-level="3" class="btn btn-mini btn-warning" type="button"><i class="icon-flag"></i></button>
29
+ <button data-level="4" class="btn btn-mini btn-danger" type="button"><i class="icon-flag"></i></button>
30
+ </div>
31
+ </form>
32
+ <form class="form" id="bookmark-transfer-form">
33
+ <div class="input-append">
34
+ <select id="dog-ears-new-user"></select>
35
+ <button class="btn" type="submit"><i class="icon-share"></i></button>
36
+ </div>
37
+ </form>
38
+ <% end -%>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>DogEars</title>
5
+ <%= stylesheet_link_tag "dog_ears/application", :media => "all" %>
6
+ <%= javascript_include_tag "dog_ears/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ DogEars::Engine.routes.draw do
2
+ end
@@ -0,0 +1,12 @@
1
+ class CreateDogEarsBookmarks < ActiveRecord::Migration
2
+ def change
3
+ create_table :dog_ears_bookmarks do |t|
4
+ t.references :user
5
+ t.text :path
6
+ t.text :title
7
+ t.text :comment
8
+ t.string :level
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+ module DogEars
2
+ module Controller
3
+
4
+ def index
5
+ @bookmarks = DogEars::Bookmark.for_user(current_user).where(level: params[:level])
6
+ render json: @bookmarks.to_json
7
+ end
8
+
9
+ def create
10
+ path = params[:path]
11
+ title = params[:title]
12
+ level = Bookmark::LEVELS[params[:level].to_i]
13
+ title = nil if title == 'null'
14
+ user = current_user
15
+ b = DogEars.bookmark(user, path, title, level)
16
+ render partial: '/dog_ears/dog_ears',
17
+ locals: { bookmark_url: '', b: b, path: b.path, method: 'GET' }
18
+ end
19
+
20
+ def get_users
21
+ uu = User.where('id <> ?', current_user.id)
22
+ render json: uu.inject({}){|a,e| a[e.id] = e.name; a }.to_json
23
+ end
24
+
25
+ def destroy
26
+ @bookmark = DogEars::Bookmark.for_user(current_user).find(params[:id])
27
+ @bookmark.destroy
28
+ render partial: '/dog_ears/dog_ears',
29
+ locals: { bookmark_url: '', b: nil, path: @bookmark.path, method: 'GET' }
30
+ end
31
+
32
+ def share
33
+ @bookmark = DogEars::Bookmark.for_user(current_user).find(params[:id])
34
+ user = User.find(params[:user_id])
35
+ nb = @bookmark.dup
36
+ nb.title = "[#{current_user.name}] #{nb.title}"
37
+ nb.user_id = user.id
38
+ nb.save!
39
+ render partial: '/dog_ears/dog_ears',
40
+ locals: { bookmark_url: '', b: @bookmark, path: @bookmark.path, method: 'GET' }
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ module DogEars
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace DogEars
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module DogEarsHelper
2
+
3
+ def dog_ears(bookmark_url)
4
+ raise "give the path for dog_ears" unless bookmark_url.present?
5
+ b = DogEars::Bookmark.for_user_and_path(current_user, request.env['PATH_INFO'])
6
+ render partial: '/dog_ears/dog_ears', locals: { bookmark_url: bookmark_url, b: b }
7
+ end
8
+
9
+ end
@@ -0,0 +1,30 @@
1
+ require "active_support/core_ext/object/try"
2
+ require "active_support/core_ext/hash/slice"
3
+
4
+ module ActionDispatch::Routing
5
+ class Mapper
6
+
7
+ def dog_ears(options={})
8
+ options[:as] ||= @scope[:as] if @scope[:as].present?
9
+ options[:module] ||= @scope[:module] if @scope[:module].present?
10
+ options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
11
+ options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {})
12
+ options[:constraints] = (@scope[:constraints] || {}).merge(options[:constraints] || {})
13
+ options[:defaults] = (@scope[:defaults] || {}).merge(options[:defaults] || {})
14
+ options[:options] = @scope[:options] || {}
15
+ options[:options][:format] = false if options[:format] == false
16
+
17
+ #puts "\n\n\n#{options.to_s}\n\n\n"
18
+
19
+ resources :bookmarks, only: [:create, :destroy, :index] do
20
+ collection do
21
+ get :get_users
22
+ end
23
+ member do
24
+ post :share
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module DogEars
2
+ VERSION = "0.1.0 "
3
+ end
data/lib/dog_ears.rb ADDED
@@ -0,0 +1,19 @@
1
+ require "dog_ears/engine"
2
+ require "dog_ears/controller"
3
+ require "dog_ears/rails/routes"
4
+ require "dog_ears/rails/helper"
5
+
6
+ module DogEars
7
+
8
+ def self.bookmark(user, path, title, level=nil)
9
+ b = Bookmark.new do |b|
10
+ b.user = user
11
+ b.path = path
12
+ b.title = title.presence || path
13
+ b.level = level
14
+ end
15
+ b.save!
16
+ b
17
+ end
18
+
19
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :dog_ears do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dog_ears
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Peter Horn, Provideal GmbH
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>'
18
+ - !ruby/object:Gem::Version
19
+ version: 3.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>'
25
+ - !ruby/object:Gem::Version
26
+ version: 3.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Generic in-app-bookmarks and bookmark-sharing based on URL routes.
42
+ email:
43
+ - ph@provideal.net
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - app/assets/javascripts/dog_ears/application.js
49
+ - app/assets/stylesheets/dog_ears/application.css
50
+ - app/controllers/dog_ears/application_controller.rb
51
+ - app/helpers/application_helper.rb
52
+ - app/models/dog_ears/bookmark.rb
53
+ - app/views/dog_ears/_dog_ears.html.erb
54
+ - app/views/layouts/dog_ears/application.html.erb
55
+ - config/routes.rb
56
+ - db/migrate/20130828134045_create_dog_ears_bookmarks.rb
57
+ - lib/dog_ears/controller.rb
58
+ - lib/dog_ears/engine.rb
59
+ - lib/dog_ears/rails/helper.rb
60
+ - lib/dog_ears/rails/routes.rb
61
+ - lib/dog_ears/version.rb
62
+ - lib/dog_ears.rb
63
+ - lib/tasks/dog_ears_tasks.rake
64
+ - MIT-LICENSE
65
+ - Rakefile
66
+ - README.rdoc
67
+ homepage: https://github.com/provideal/dog_ears
68
+ licenses: []
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.0.6
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Generic in-app-bookmarks and bookmark-sharing
90
+ test_files: []
91
+ has_rdoc: