annotator_store 1.0.0.pre
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +48 -0
- data/CONTRIBUTING.md +28 -0
- data/LICENSE.md +23 -0
- data/README.md +414 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/annotator_store/application.js +13 -0
- data/app/assets/stylesheets/annotator_store/application.css +15 -0
- data/app/controllers/annotator_store/annotations_controller.rb +97 -0
- data/app/controllers/annotator_store/application_controller.rb +15 -0
- data/app/controllers/annotator_store/pages_controller.rb +24 -0
- data/app/helpers/annotator_store/annotations_helper.rb +4 -0
- data/app/helpers/annotator_store/application_helper.rb +4 -0
- data/app/models/annotator_store/annotation.rb +16 -0
- data/app/models/annotator_store/range.rb +12 -0
- data/app/views/annotator_store/annotations/_annotation.json.jbuilder +23 -0
- data/app/views/annotator_store/annotations/options.json.jbuilder +1 -0
- data/app/views/annotator_store/annotations/show.json.jbuilder +1 -0
- data/app/views/annotator_store/pages/index.json.jbuilder +31 -0
- data/app/views/annotator_store/pages/search.json.jbuilder +4 -0
- data/app/views/layouts/annotator_store/application.html.erb +14 -0
- data/config/routes.rb +15 -0
- data/db/migrate/20141013113654_create_annotator_store.rb +48 -0
- data/lib/annotator_store.rb +5 -0
- data/lib/annotator_store/engine.rb +11 -0
- data/lib/annotator_store/version.rb +3 -0
- data/lib/tasks/annotator_store_tasks.rake +4 -0
- metadata +212 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c6ddd11b4ff25f3477a7c2ef180080c135f192ba
|
4
|
+
data.tar.gz: 40c0857fbb2adc58ec90f65622f91ca463016d9d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9dde1c468bcdeb6c3a6bd7069b9bb1176e479036b3e1b4b3b4bff26b756368d4fde382ffd863596fd5dd11ed04cd6995565bb8e5191b1d23080dd5212d5b067c
|
7
|
+
data.tar.gz: 39a4e0020f14898a1d0e3b730fa4adba062baa338fdf317c10214935b357f7235637d109a067319e0c87068d4ed78b603683c4ae0a4f732d6ca6ae54d17e9470
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
=========
|
3
|
+
|
4
|
+
v1.0.0.pre
|
5
|
+
----------
|
6
|
+
|
7
|
+
* Rename gem from `annotator-store` to `annotator_store`
|
8
|
+
* Fix issue with explicit require needed in main application
|
9
|
+
|
10
|
+
|
11
|
+
v0.4.0
|
12
|
+
------
|
13
|
+
|
14
|
+
* Add support for MySQL
|
15
|
+
|
16
|
+
|
17
|
+
v0.3.0
|
18
|
+
------
|
19
|
+
|
20
|
+
* Change create endpoint to respond with `201 CREATED`
|
21
|
+
* Test support for Ruby `>= 1.9.3`.
|
22
|
+
* Test support for Rails `>= 4.0`.
|
23
|
+
|
24
|
+
|
25
|
+
v0.2.0
|
26
|
+
------
|
27
|
+
|
28
|
+
* Add required files to gemspec
|
29
|
+
* Add CRUD (create, read, update and delete) endpoints
|
30
|
+
* Add search endpoint with filter support for uri
|
31
|
+
* Included tests for routes, requests, models and controllers
|
32
|
+
|
33
|
+
|
34
|
+
v0.1.0
|
35
|
+
------
|
36
|
+
|
37
|
+
* Create index page with description of API.
|
38
|
+
* Add annotation functionality & create necessary endpoints
|
39
|
+
|
40
|
+
|
41
|
+
v0.0.1
|
42
|
+
------
|
43
|
+
|
44
|
+
Initial release, to lock the gem name ... by v1.0.0 we should have a version
|
45
|
+
ready for deployment in production environment.
|
46
|
+
|
47
|
+
* Initialise the project
|
48
|
+
* Create structure
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
CONTRIBUTING
|
2
|
+
============
|
3
|
+
|
4
|
+
Submitting a Pull Request
|
5
|
+
-------------------------
|
6
|
+
|
7
|
+
1. [Fork the repository][fork].
|
8
|
+
2. [Create a topic branch][branch] (`git checkout -b BRANCH_NAME`).
|
9
|
+
3. [Install bundler][bundler].
|
10
|
+
4. Check that tests pass with `rspec spec`.
|
11
|
+
5. Write a failing test to capture existing bug or lack of feature.
|
12
|
+
6. Run `rspec spec` to verify that test fails.
|
13
|
+
7. Implement your feature or bug fix.
|
14
|
+
8. Ensure tests pass.
|
15
|
+
9. If it's a new feature or a bug fix, please add an entry to the CHANGELOG file.
|
16
|
+
10. Check code style violations using [Rubocop][rubocop].
|
17
|
+
11. Add a commit (`git commit -am 'AWESOME COMMIT MESSAGE'`).
|
18
|
+
12. Push your changes to the branch (`git push origin BRANCH_NAME`).
|
19
|
+
13. [Submit a pull request.][pr]
|
20
|
+
14. You will get some feedback and may need to push additional commits
|
21
|
+
with more fixes to the same branch; this will update your pull request
|
22
|
+
automatically.
|
23
|
+
|
24
|
+
[branch]: http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches
|
25
|
+
[bundler]: http://bundler.io
|
26
|
+
[fork]: https://help.github.com/articles/fork-a-repo/
|
27
|
+
[pr]: https://help.github.com/articles/using-pull-requests
|
28
|
+
[rubocop]: https://github.com/bbatsov/rubocop
|
data/LICENSE.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
License
|
2
|
+
=======
|
3
|
+
|
4
|
+
Copyright (c) 2014 Job King'ori Maina
|
5
|
+
|
6
|
+
MIT License
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
9
|
+
this software and associated documentation files (the "Software"), to deal in
|
10
|
+
the Software without restriction, including without limitation the rights to
|
11
|
+
use, copy, modify, merge, publish, distribute, sub-license, and/or sell copies
|
12
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
13
|
+
so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
16
|
+
copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
20
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
21
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
22
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
23
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,414 @@
|
|
1
|
+
Annotator Store
|
2
|
+
===============
|
3
|
+
|
4
|
+
[][5]
|
5
|
+
[][13]
|
6
|
+
|
7
|
+
Rails engine to implement a [Ruby on Rails][18] backend store implementation for
|
8
|
+
[Annotator][annotator].
|
9
|
+
|
10
|
+
> Annotator an open-source JavaScript library to easily add annotation
|
11
|
+
> functionality to any webpage. Annotations can have comments, tags, links,
|
12
|
+
> users, and more. Annotator is designed for [easy extensibility][1] so its a
|
13
|
+
> cinch to add a new feature or behaviour. Annotator also fosters an active
|
14
|
+
> developer community with contributors from four continents, building 3rd party
|
15
|
+
> plugins allowing the annotation of PDFs, EPUBs, videos, images, sound, and
|
16
|
+
> more.
|
17
|
+
|
18
|
+
The gem should be up on [rubygems.org][5], the [CHANGELOG here][7] and [all the
|
19
|
+
releases listed here][8].
|
20
|
+
|
21
|
+
|
22
|
+
Contents
|
23
|
+
--------
|
24
|
+
|
25
|
+
1. Dependencies & Versions
|
26
|
+
2. Installation
|
27
|
+
3. Annotation Format
|
28
|
+
4. API Endpoints
|
29
|
+
5. Development
|
30
|
+
6. Testing & Appraisals
|
31
|
+
7. Versioning
|
32
|
+
8. Contributing
|
33
|
+
9. License
|
34
|
+
|
35
|
+
|
36
|
+
Dependencies & Versions
|
37
|
+
----------------------
|
38
|
+
|
39
|
+
This engine requires Rails `>= 4.0` and Ruby `>= 1.9.3` and supports more than
|
40
|
+
one database.
|
41
|
+
|
42
|
+
Supported Ruby versions:
|
43
|
+
|
44
|
+
* [X] 1.9.3
|
45
|
+
* [X] 2.0.0
|
46
|
+
* [X] 2.1.0
|
47
|
+
* [X] 2.1.1
|
48
|
+
* [X] 2.1.2
|
49
|
+
|
50
|
+
Supported Rails versions:
|
51
|
+
|
52
|
+
* [X] 4.0.x
|
53
|
+
* [X] 4.1.x
|
54
|
+
* [X] 4.2.x
|
55
|
+
|
56
|
+
Supported databases:
|
57
|
+
|
58
|
+
* [X] MySQL
|
59
|
+
* [X] PostgreSQL
|
60
|
+
|
61
|
+
_'Supported'_ means that the test suite is designed to cover these versions
|
62
|
+
only. If your version isn't supported [raise a ticket][19]; make sure you
|
63
|
+
include the versions.
|
64
|
+
|
65
|
+
Sometimes when the build is failing, it's probably a few of these
|
66
|
+
configurations. Have a [look at the builds here][13] and see section on testing
|
67
|
+
& appraisals for more information.
|
68
|
+
|
69
|
+
|
70
|
+
Installation
|
71
|
+
------------
|
72
|
+
|
73
|
+
Add this line to your application's Gemfile:
|
74
|
+
|
75
|
+
gem 'annotator_store'
|
76
|
+
|
77
|
+
And then from the `APP_ROOT` execute:
|
78
|
+
|
79
|
+
$ bundle install
|
80
|
+
|
81
|
+
Configure your database credentials in `config/database.yml` and then run the
|
82
|
+
migrations to create the tables to store the annotations. Depending on the
|
83
|
+
database of choice you'll need to set the `DB` environment variable when running
|
84
|
+
the migrations. There are slight variations in the structure of the DB when
|
85
|
+
using MySQL and PostgreSQL. The default setting is PostgreSQL if not set.
|
86
|
+
|
87
|
+
# Copy migrations over from the engine
|
88
|
+
$ rake annotator_store:install:migrations
|
89
|
+
|
90
|
+
# To run the copied migration when using MySQL
|
91
|
+
$ DB=mysql rake db:migrate
|
92
|
+
|
93
|
+
# To run the copied migration when using PostgreSQL
|
94
|
+
$ DB=postgres rake db:migrate
|
95
|
+
|
96
|
+
# To run the copied migration without specifying type (defaults to postgres)
|
97
|
+
$ rake db:migrate
|
98
|
+
|
99
|
+
Then mount it in `config/routes.rb`:
|
100
|
+
|
101
|
+
# Configures store endpoint in your app
|
102
|
+
mount AnnotatorStore::Engine, at: '/annotator_store'
|
103
|
+
|
104
|
+
Now it should be ready for use. All the endpoints will be available at
|
105
|
+
`http://0.0.0.0:3000/annotator_store` in your app.
|
106
|
+
|
107
|
+
|
108
|
+
Annotation Format
|
109
|
+
-----------------
|
110
|
+
|
111
|
+
An annotation is a JSON document that contains a number of fields describing the
|
112
|
+
position and content of an annotation within a specified document:
|
113
|
+
|
114
|
+
{
|
115
|
+
"id": "39fc339cf058bd22176771b3e3187329", # unique id (added by backend)
|
116
|
+
"annotator_schema_version": "v1.0", # schema version: default v1.0
|
117
|
+
"created": "2011-05-24T18:52:08.036814", # created datetime in iso8601 format (added by backend)
|
118
|
+
"updated": "2011-05-26T12:17:05.012544", # updated datetime in iso8601 format (added by backend)
|
119
|
+
"text": "A note I wrote", # content of annotation
|
120
|
+
"quote": "the text that was annotated", # the annotated text (added by frontend)
|
121
|
+
"uri": "http://example.com", # URI of annotated document (added by frontend)
|
122
|
+
"ranges": [ # list of ranges covered by annotation (usually only one entry)
|
123
|
+
{
|
124
|
+
"start": "/p[69]/span/span", # (relative) XPath to start element
|
125
|
+
"end": "/p[70]/span/span", # (relative) XPath to end element
|
126
|
+
"startOffset": 0, # character offset within start element
|
127
|
+
"endOffset": 120 # character offset within end element
|
128
|
+
}
|
129
|
+
]
|
130
|
+
}
|
131
|
+
|
132
|
+
For PostgreSQL the primary key of the annotation will be a UUID while for MySQL it
|
133
|
+
will be a normal integer id.
|
134
|
+
|
135
|
+
|
136
|
+
API Endpoints
|
137
|
+
-------------
|
138
|
+
|
139
|
+
### Root
|
140
|
+
|
141
|
+
| Method | Path | Returns |
|
142
|
+
| ------ | ---- | ------------------------------------------------------------------------ |
|
143
|
+
| GET | / | `200 OK` with an object containing store metadata, including API version |
|
144
|
+
|
145
|
+
Returns (example):
|
146
|
+
|
147
|
+
$ curl http://example.com/annotator_store
|
148
|
+
{
|
149
|
+
"name": "Annotator Store API",
|
150
|
+
"version": "2.0.0",
|
151
|
+
"links": {
|
152
|
+
"annotation": {
|
153
|
+
"create": {
|
154
|
+
"url": "http://example.com/annotator_store/annotations",
|
155
|
+
"method": "POST",
|
156
|
+
"description": "Create or add new annotations."
|
157
|
+
},
|
158
|
+
"read": {
|
159
|
+
"url": "http://example.com/annotator_store/annotations/:id",
|
160
|
+
"method": "GET",
|
161
|
+
"description": "Read, retrieve or view existing annotation."
|
162
|
+
},
|
163
|
+
"update": {
|
164
|
+
"url": "http://example.com/annotator_store/annotations/:id",
|
165
|
+
"method": "PUT/PATCH",
|
166
|
+
"description": "Update or edit existing annotation."
|
167
|
+
},
|
168
|
+
"delete": {
|
169
|
+
"url": "http://example.com/annotator_store/annotations/:id",
|
170
|
+
"method": "DELETE",
|
171
|
+
"description": "Delete or deactivate existing annotation."
|
172
|
+
}
|
173
|
+
},
|
174
|
+
"search": {
|
175
|
+
"url": "http://example.com/annotator_store/search",
|
176
|
+
"method": "GET",
|
177
|
+
"description": "Search for annotations"
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
|
183
|
+
### Create
|
184
|
+
|
185
|
+
| Method | Path | Returns |
|
186
|
+
| ------- | ------------ | -------------------------------------------------------------------------- |
|
187
|
+
| POST | /annotations | `201 CREATED` with location in header set to the appropriate read endpoint |
|
188
|
+
|
189
|
+
Receives an annotation object in the proper annotation format, sent with `Content-Type: application/json`.
|
190
|
+
|
191
|
+
Returns (example):
|
192
|
+
|
193
|
+
$ curl http://example.com/annotator_store/annotations
|
194
|
+
{
|
195
|
+
"id": "d41d8cd98f00b204e9800998ecf8427e",
|
196
|
+
"text": "Annotation text",
|
197
|
+
...
|
198
|
+
}
|
199
|
+
|
200
|
+
|
201
|
+
### Read
|
202
|
+
|
203
|
+
| Method | Path | Returns |
|
204
|
+
| ------ | ---------------- | ---------------------------------- |
|
205
|
+
| GET | /annotations/:id | `200 OK` with an annotation object |
|
206
|
+
|
207
|
+
Returns (example):
|
208
|
+
|
209
|
+
$ curl http://example.com/annotator_store/annotations/d41d8cd98f00b204e9800998ecf8427e
|
210
|
+
{
|
211
|
+
"id": "d41d8cd98f00b204e9800998ecf8427e",
|
212
|
+
"text": "Annotation text",
|
213
|
+
...
|
214
|
+
}
|
215
|
+
|
216
|
+
|
217
|
+
### Update
|
218
|
+
|
219
|
+
| Method | Path | Returns |
|
220
|
+
| ---------- | ---------------- | --------------------------------------------------------------------- |
|
221
|
+
| PUT/PATCH | /annotations/:id | `200 OK` with location in header set to the appropriate read endpoint |
|
222
|
+
|
223
|
+
Receives attributes in the proper annotation format, sent with `Content-Type: application/json`.
|
224
|
+
|
225
|
+
Returns (example):
|
226
|
+
|
227
|
+
$ curl http://example.com/annotator_store/annotations/d41d8cd98f00b204e9800998ecf8427e
|
228
|
+
{
|
229
|
+
"id": "d41d8cd98f00b204e9800998ecf8427e",
|
230
|
+
"text": "Annotation text",
|
231
|
+
...
|
232
|
+
}
|
233
|
+
|
234
|
+
|
235
|
+
### Delete
|
236
|
+
|
237
|
+
| Method | Path | Returns |
|
238
|
+
| ---------- | ---------------- | ------------------------------------------ |
|
239
|
+
| DELETE | /annotations/:id | `204 NO CONTENT` and obviously, no content |
|
240
|
+
|
241
|
+
|
242
|
+
### Search
|
243
|
+
|
244
|
+
| Method | Path | Returns |
|
245
|
+
| ------ | -------- | ------------------------------------------------------- |
|
246
|
+
| GET | /search | An object with total and rows fields |
|
247
|
+
|
248
|
+
_Total_ is an integer denoting the total number of annotations matched by the
|
249
|
+
search, while _rows_ is a list containing what might be a subset of these
|
250
|
+
annotations.
|
251
|
+
|
252
|
+
If implemented, this endpoint should also support the `limit` and `offset` query
|
253
|
+
parameters for paging through results.
|
254
|
+
|
255
|
+
_Ps: Pagination with limit and offset not yet implemented. See [issue #1][15]._
|
256
|
+
|
257
|
+
Returns (example):
|
258
|
+
|
259
|
+
$ curl http://example.com/annotator_store/search?text=annotation
|
260
|
+
{
|
261
|
+
"total": 43127,
|
262
|
+
"rows": [
|
263
|
+
{
|
264
|
+
"id": "d41d8cd98f00b204e9800998ecf8427e",
|
265
|
+
"text": "Updated annotation text",
|
266
|
+
...
|
267
|
+
},
|
268
|
+
...
|
269
|
+
]
|
270
|
+
}
|
271
|
+
|
272
|
+
|
273
|
+
Development
|
274
|
+
-----------
|
275
|
+
|
276
|
+
There's a dummy Rails application in the `spec/dummy` folder. This application
|
277
|
+
is used as a mounting point for the engine, to make testing the engine on a
|
278
|
+
Rails app extremely simple. This directory should be treated like a typical
|
279
|
+
Rails testing environment, allowing for unit, functional and integration tests.
|
280
|
+
|
281
|
+
The current dummy app was generated using Rails 4.1.6 and with PostgreSQL as the
|
282
|
+
default store. The app depends on the `DB` environment variable to know which
|
283
|
+
settings to use for the database. See `config/database.yml` for details.
|
284
|
+
|
285
|
+
Set the `DB` environment variable to either `mysql` or `postgres` to choose
|
286
|
+
between the two.
|
287
|
+
|
288
|
+
# To use MySQL
|
289
|
+
$ DB=mysql [commands to run]
|
290
|
+
|
291
|
+
# To use PostgreSQL
|
292
|
+
$ DB=postgres [commands to run]
|
293
|
+
|
294
|
+
You can start up the dummy app to give it a spin by running `rails server` in
|
295
|
+
`spec/dummy` and then browse to `http://0.0.0.0:3000/`. There's a README in
|
296
|
+
there with a few details on setup, make sure you check it out.
|
297
|
+
|
298
|
+
|
299
|
+
Testing & Appraisals
|
300
|
+
--------------------
|
301
|
+
|
302
|
+
You may extend the dummy application by generating controllers, models or views
|
303
|
+
from within the directory (`spec/dummy`), and then use those to test our engine
|
304
|
+
(I've done this already but feel free to add). Then use the rspec command to run
|
305
|
+
your specs.
|
306
|
+
|
307
|
+
#=> Run all specs
|
308
|
+
$ bundle exec rspec
|
309
|
+
|
310
|
+
#=> Run only model specs example ...
|
311
|
+
$ bundle exec rspec spec/models
|
312
|
+
|
313
|
+
#=> Run only specs for AnnotatorStore::AnnotationsController ...
|
314
|
+
$ bundle exec rspec spec/controllers/annotations_controller_spec.rb
|
315
|
+
|
316
|
+
These will run the tests as per your local default configuration.
|
317
|
+
|
318
|
+
The [appraisal gem][16] is used to integrate with bundler and rake to test the
|
319
|
+
engine against different versions of dependencies in repeatable scenarios called
|
320
|
+
_'appraisals'_. This makes it easy to check for regressions in the library
|
321
|
+
without interfering with day-to-day development using Bundler.
|
322
|
+
|
323
|
+
As a result, a separate test run is created for each Ruby version and every
|
324
|
+
Rails version (see `travis.yml` file for specifics).
|
325
|
+
|
326
|
+
Locally you can test for different Rails versions. For example:
|
327
|
+
|
328
|
+
# Run specs against rails 4.0.12
|
329
|
+
$ appraisal rails-4.0.12 rspec spec
|
330
|
+
|
331
|
+
# Run specs against rails 4.1.8
|
332
|
+
$ appraisal rails-4.1.8 rspec spec
|
333
|
+
|
334
|
+
# Run specs against rails 4.2.0
|
335
|
+
$ appraisal rails-4.2.0 rspec spec
|
336
|
+
|
337
|
+
Check the Appraisal file at the root for the different rails configurations.
|
338
|
+
[Learn more about appraisals here][17].
|
339
|
+
|
340
|
+
PostgreSQL is configured to be the default database configuration. Set the `DB`
|
341
|
+
environment variable to either `mysql` or `postgres` to choose between the two.
|
342
|
+
|
343
|
+
# To use MySQL
|
344
|
+
$ DB=mysql [commands to run your tests]
|
345
|
+
|
346
|
+
# To use PostgreSQL
|
347
|
+
$ DB=postgres [commands to run your tests]
|
348
|
+
|
349
|
+
Automated tests are configured and set up to [run on Travis-CI][13]. Any push or
|
350
|
+
pull request will be built. The `DB` environment variable should be set to
|
351
|
+
either `mysql` or `postgres` to create a build matrix with good coverage.
|
352
|
+
|
353
|
+
|
354
|
+
Versioning
|
355
|
+
----------
|
356
|
+
|
357
|
+
Major version zero (0.y.z) is for initial development. Anything may change at
|
358
|
+
any time. The public API should not be considered stable (implicitly mean, not
|
359
|
+
production ready ... yet).
|
360
|
+
|
361
|
+
Version 1.0.0 defines the public API (implying that it is production ready). The
|
362
|
+
way in which the version number is incremented after this release is dependent
|
363
|
+
on this public API and how it changes as per [Semantic Versioning
|
364
|
+
2.0.0][semver].
|
365
|
+
|
366
|
+
All the releases, with their respective changes are [listed here][8].
|
367
|
+
|
368
|
+
|
369
|
+
Contributing
|
370
|
+
------------
|
371
|
+
|
372
|
+
Want to contribute to the code? First, have a look at the guide in the
|
373
|
+
[CONTRIBUTING.md][9] file for the workflow.
|
374
|
+
|
375
|
+
Then, here's some Annotator documentation to help you get up to speed:
|
376
|
+
|
377
|
+
* [Annotator Storage][10] API specifications.
|
378
|
+
* [Annotator Store Plugin][11] documentation.
|
379
|
+
|
380
|
+
In summary, this gem helps implement a store for the plugin to interact with.
|
381
|
+
|
382
|
+
Any code contributors should be [listed here][12].
|
383
|
+
|
384
|
+
|
385
|
+
License
|
386
|
+
-------
|
387
|
+
|
388
|
+
[King'ori J. Maina][2] © 2014. The MIT License bundled therein is a permissive
|
389
|
+
license that is short and to the point. It lets people do anything they want as
|
390
|
+
long as they provide attribution and waive liability.
|
391
|
+
|
392
|
+
|
393
|
+
[annotator]: http://annotatorjs.org/
|
394
|
+
[semver]: http://semver.org
|
395
|
+
|
396
|
+
[1]: http://docs.annotatorjs.org/en/latest/hacking/plugin-development.html
|
397
|
+
[2]: http://kingori.co/
|
398
|
+
[3]: http://bundler.io/gemfile.html
|
399
|
+
[4]: http://bundler.io
|
400
|
+
[5]: https://rubygems.org/gems/annotator_store
|
401
|
+
[6]: http://rubydoc.info/gems/annotator_store/frames/
|
402
|
+
[7]: https://github.com/itsmrwave/annotator_store-gem/blob/master/CHANGELOG.md
|
403
|
+
[9]: https://github.com/itsmrwave/annotator_store-gem/blob/master/CONTRIBUTING.md
|
404
|
+
[8]: https://github.com/itsmrwave/annotator_store-gem/releases
|
405
|
+
[10]: http://docs.annotatorjs.org/en/v1.2.x/storage.html
|
406
|
+
[11]: http://docs.annotatorjs.org/en/v1.2.x/plugins/store.html
|
407
|
+
[12]: https://github.com/itsmrwave/annotator_store-gem/graphs/contributors
|
408
|
+
[13]: https://travis-ci.org/itsmrwave/annotator_store-gem
|
409
|
+
[14]: https://github.com/itsmrwave/annotator-store-demo
|
410
|
+
[15]: https://github.com/itsmrwave/annotator_store-gem/issues/1
|
411
|
+
[16]: http://rubygems.org/gems/appraisal
|
412
|
+
[17]: http://www.rubydoc.info/gems/appraisal
|
413
|
+
[18]: http://rubyonrails.org
|
414
|
+
[19]: https://github.com/itsmrwave/annotator_store-gem/issues/new
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
8
|
+
load 'rails/tasks/engine.rake'
|
9
|
+
|
10
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,13 @@
|
|
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
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
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 bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_dependency 'annotator_store/application_controller'
|
2
|
+
|
3
|
+
module AnnotatorStore
|
4
|
+
class AnnotationsController < ApplicationController
|
5
|
+
before_action :set_annotation, only: [:show, :update, :destroy]
|
6
|
+
|
7
|
+
# POST /annotations
|
8
|
+
def create
|
9
|
+
format_client_input_to_rails_convention_for_create
|
10
|
+
@annotation = Annotation.new(annotation_params)
|
11
|
+
respond_to do |format|
|
12
|
+
if @annotation.save
|
13
|
+
format.json { render :show, status: :created, location: annotation_url(@annotation) }
|
14
|
+
else
|
15
|
+
format.json { render json: @annotation.errors, status: :unprocessable_entity }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# GET /annotations/1
|
21
|
+
def show
|
22
|
+
end
|
23
|
+
|
24
|
+
# PATCH/PUT /annotations/1
|
25
|
+
def update
|
26
|
+
format_client_input_to_rails_convention_for_update
|
27
|
+
respond_to do |format|
|
28
|
+
if @annotation.update(annotation_params)
|
29
|
+
format.json { render :show, status: :ok, location: annotation_url(@annotation) }
|
30
|
+
else
|
31
|
+
format.json { render json: @annotation.errors, status: :unprocessable_entity }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# DELETE /annotations/1
|
37
|
+
def destroy
|
38
|
+
@annotation.destroy
|
39
|
+
respond_to do |format|
|
40
|
+
format.json { head :no_content, status: :no_content }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# OPTIONS /annotations
|
45
|
+
def options
|
46
|
+
respond_to do |format|
|
47
|
+
format.json { render :options }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Use callbacks to share common setup or constraints between actions.
|
54
|
+
def set_annotation
|
55
|
+
@annotation = Annotation.find(params[:id])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Convert the data sent by AnnotatorJS to the format that Rails expects so
|
59
|
+
# that we are able to create a proper params object
|
60
|
+
def format_client_input_to_rails_convention_for_create
|
61
|
+
params[:annotation] = {}
|
62
|
+
params[:annotation][:version] = params[:annotator_schema_version] unless params[:annotator_schema_version].blank?
|
63
|
+
params[:annotation][:text] = params[:text] unless params[:text].blank?
|
64
|
+
params[:annotation][:quote] = params[:quote] unless params[:quote].blank?
|
65
|
+
params[:annotation][:uri] = params[:uri] unless params[:uri].blank?
|
66
|
+
params[:annotation][:ranges_attributes] = params[:ranges].map do |r|
|
67
|
+
range = {}
|
68
|
+
range[:start] = r[:start]
|
69
|
+
range[:end] = r[:end]
|
70
|
+
range[:start_offset] = r[:startOffset]
|
71
|
+
range[:end_offset] = r[:endOffset]
|
72
|
+
range
|
73
|
+
end unless params[:ranges].blank?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Convert the data sent by AnnotatorJS to the format that Rails expects so
|
77
|
+
# that we are able to create a proper params object
|
78
|
+
def format_client_input_to_rails_convention_for_update
|
79
|
+
params[:annotation] = {}
|
80
|
+
params[:annotation][:version] = params[:annotator_schema_version] unless params[:annotator_schema_version].blank?
|
81
|
+
params[:annotation][:text] = params[:text] unless params[:text].blank?
|
82
|
+
params[:annotation][:quote] = params[:quote] unless params[:quote].blank?
|
83
|
+
params[:annotation][:uri] = params[:uri] unless params[:uri].blank?
|
84
|
+
end
|
85
|
+
|
86
|
+
# Only allow a trusted parameter 'white list' through.
|
87
|
+
def annotation_params
|
88
|
+
params.require(:annotation).permit(
|
89
|
+
:text,
|
90
|
+
:quote,
|
91
|
+
:uri,
|
92
|
+
:version,
|
93
|
+
ranges_attributes: [:start, :end, :start_offset, :end_offset]
|
94
|
+
)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module AnnotatorStore
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
before_action :set_headers
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def set_headers
|
8
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
9
|
+
headers['Access-Control-Expose-Headers'] = 'ETag'
|
10
|
+
headers['Access-Control-Allow-Methods'] = 'GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD'
|
11
|
+
headers['Access-Control-Allow-Headers'] = '*,x-requested-with,Content-Type,If-Modified-Since,If-None-Match'
|
12
|
+
headers['Access-Control-Max-Age'] = '86400'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module AnnotatorStore
|
2
|
+
class PagesController < ApplicationController
|
3
|
+
before_action :format_input, only: [:search]
|
4
|
+
|
5
|
+
def index
|
6
|
+
end
|
7
|
+
|
8
|
+
def search
|
9
|
+
@annotations = AnnotatorStore::Annotation.where(search_params)
|
10
|
+
@total = @annotations.size
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def format_input
|
16
|
+
params[:search] = {}
|
17
|
+
params[:search][:uri] = params[:uri]
|
18
|
+
end
|
19
|
+
|
20
|
+
def search_params
|
21
|
+
params.require(:search).permit(:uri)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module AnnotatorStore
|
2
|
+
class Annotation < ActiveRecord::Base
|
3
|
+
# Associations
|
4
|
+
has_many :ranges, dependent: :destroy, autosave: true
|
5
|
+
|
6
|
+
# Allow saving of attributes on associated records through the parent,
|
7
|
+
# :autosave option is automatically enabled on every association
|
8
|
+
accepts_nested_attributes_for :ranges
|
9
|
+
|
10
|
+
# Validations
|
11
|
+
validates :version, presence: true
|
12
|
+
validates :text, presence: true
|
13
|
+
validates :quote, presence: true
|
14
|
+
validates :uri, presence: true
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module AnnotatorStore
|
2
|
+
class Range < ActiveRecord::Base
|
3
|
+
# Associations
|
4
|
+
belongs_to :annotation
|
5
|
+
|
6
|
+
# Validations
|
7
|
+
validates :start, presence: true
|
8
|
+
validates :end, presence: true
|
9
|
+
validates :start_offset, presence: true
|
10
|
+
validates :end_offset, presence: true
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
json.id annotation.id
|
2
|
+
|
3
|
+
# Version
|
4
|
+
json.annotator_schema_version annotation.version
|
5
|
+
|
6
|
+
# Meta
|
7
|
+
json.uri annotation.uri
|
8
|
+
|
9
|
+
# Content
|
10
|
+
json.text annotation.text
|
11
|
+
json.quote annotation.quote
|
12
|
+
json.ranges do
|
13
|
+
json.array! annotation.ranges do |range|
|
14
|
+
json.start range.start
|
15
|
+
json.end range.end
|
16
|
+
json.startOffset range.start_offset
|
17
|
+
json.endOffset range.end_offset
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Timestamps
|
22
|
+
json.created annotation.created_at
|
23
|
+
json.updated annotation.updated_at
|
@@ -0,0 +1 @@
|
|
1
|
+
json.approved true
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! 'annotator_store/annotations/annotation', annotation: @annotation, as: :annotation
|
@@ -0,0 +1,31 @@
|
|
1
|
+
json.name 'Annotator Store API'
|
2
|
+
json.version '2.0.0'
|
3
|
+
json.links do
|
4
|
+
json.annotation do
|
5
|
+
json.create do
|
6
|
+
json.url annotator_store.annotations_url
|
7
|
+
json.method 'POST'
|
8
|
+
json.description 'Create or add new annotations.'
|
9
|
+
end
|
10
|
+
json.read do
|
11
|
+
json.url annotator_store.annotation_url(':id')
|
12
|
+
json.method 'GET'
|
13
|
+
json.description 'Read, retrieve or view existing annotation.'
|
14
|
+
end
|
15
|
+
json.update do
|
16
|
+
json.url annotator_store.annotation_url(':id')
|
17
|
+
json.method 'PUT/PATCH'
|
18
|
+
json.description 'Update or edit existing annotation.'
|
19
|
+
end
|
20
|
+
json.delete do
|
21
|
+
json.url annotator_store.annotation_url(':id')
|
22
|
+
json.method 'DELETE'
|
23
|
+
json.description 'Delete or deactivate existing annotation.'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
json.search do
|
27
|
+
json.url annotator_store.search_url
|
28
|
+
json.method 'GET'
|
29
|
+
json.description 'Search for annotations'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>AnnotatorStore</title>
|
5
|
+
<%= stylesheet_link_tag "annotator_store/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "annotator_store/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,15 @@
|
|
1
|
+
AnnotatorStore::Engine.routes.draw do
|
2
|
+
|
3
|
+
# Root path
|
4
|
+
root 'pages#index', defaults: { format: :json }
|
5
|
+
|
6
|
+
# Search
|
7
|
+
match 'search', to: 'pages#search', via: [:get], defaults: { format: :json }, constraints: { format: :json }
|
8
|
+
match 'search', to: 'annotations#options', via: [:options], defaults: { format: :json }, constraints: { format: :json }
|
9
|
+
|
10
|
+
# Annotations Endpoint
|
11
|
+
resources :annotations, only: [:create, :show, :update, :destroy], defaults: { format: :json }, constraints: { format: :json } do
|
12
|
+
match '/', to: 'annotations#options', via: [:options], on: :collection
|
13
|
+
match '/', to: 'annotations#options', via: [:options], on: :member
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# This migration executes differently depending on the database set via the DB
|
2
|
+
# environment variable. For PostgreSQL we use UUIDs ... for MySQL we use normal
|
3
|
+
# primary keys.
|
4
|
+
class CreateAnnotatorStore < ActiveRecord::Migration
|
5
|
+
def self.up
|
6
|
+
# If using PostgreSQL database these are extensions are necessary
|
7
|
+
database_type = ENV['DB'] || 'postgres'
|
8
|
+
if database_type == 'postgres'
|
9
|
+
enable_extension 'plpgsql' unless extension_enabled?('plpgsql')
|
10
|
+
enable_extension 'uuid-ossp' unless extension_enabled?('uuid-ossp')
|
11
|
+
options = { id: :uuid, default: 'uuid_generate_v4()' }
|
12
|
+
else
|
13
|
+
options = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Table to store annotations
|
17
|
+
create_table :annotator_store_annotations, options do |t|
|
18
|
+
t.string :version # Schema version
|
19
|
+
t.text :text # Content of annotation
|
20
|
+
t.text :quote # The annotated text
|
21
|
+
t.string :uri # URI of annotated document
|
22
|
+
t.timestamps # Time created_at and updated_at
|
23
|
+
end
|
24
|
+
|
25
|
+
# Table to store ranges covered by an annotation since each annotation could
|
26
|
+
# have many ranges ... at least by design in annotator.js but not yet
|
27
|
+
# implemented. Since the associated annotation's primary could be a UUID, at
|
28
|
+
# least in the case of PostgreSQL, we'll have to apply some logic to cater
|
29
|
+
# for the different scenarios.
|
30
|
+
create_table :annotator_store_ranges do |t|
|
31
|
+
if database_type == 'postgres'
|
32
|
+
t.uuid :annotation_id, index: true # Associated annotation's UUID
|
33
|
+
else
|
34
|
+
t.references :annotation, index: true # Associated annotation's normal id
|
35
|
+
end
|
36
|
+
t.string :start # Relative XPath to start element
|
37
|
+
t.string :end # Relative XPath to end element
|
38
|
+
t.integer :start_offset # Character offset within start element
|
39
|
+
t.integer :end_offset # Character offset within end element
|
40
|
+
t.timestamps
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.down
|
45
|
+
drop_table :annotator_store_annotations
|
46
|
+
drop_table :annotator_store_ranges
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module AnnotatorStore
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace AnnotatorStore
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.integration_tool :rspec
|
7
|
+
g.test_framework :rspec, fixture: false
|
8
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: annotator_store
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Job King'ori Maina
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mysql2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pg
|
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
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: appraisal
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: database_cleaner
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: factory_girl_rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: faker
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: json-schema
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec-rails
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: jbuilder
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rails
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '4.0'
|
153
|
+
description: Rails engine to implement a Ruby backend store implementation for Annotator,
|
154
|
+
an open-source JavaScript library to easily add annotation functionality to any
|
155
|
+
webpage.
|
156
|
+
email:
|
157
|
+
- j@kingori.co
|
158
|
+
executables: []
|
159
|
+
extensions: []
|
160
|
+
extra_rdoc_files: []
|
161
|
+
files:
|
162
|
+
- CHANGELOG.md
|
163
|
+
- CONTRIBUTING.md
|
164
|
+
- LICENSE.md
|
165
|
+
- README.md
|
166
|
+
- Rakefile
|
167
|
+
- app/assets/javascripts/annotator_store/application.js
|
168
|
+
- app/assets/stylesheets/annotator_store/application.css
|
169
|
+
- app/controllers/annotator_store/annotations_controller.rb
|
170
|
+
- app/controllers/annotator_store/application_controller.rb
|
171
|
+
- app/controllers/annotator_store/pages_controller.rb
|
172
|
+
- app/helpers/annotator_store/annotations_helper.rb
|
173
|
+
- app/helpers/annotator_store/application_helper.rb
|
174
|
+
- app/models/annotator_store/annotation.rb
|
175
|
+
- app/models/annotator_store/range.rb
|
176
|
+
- app/views/annotator_store/annotations/_annotation.json.jbuilder
|
177
|
+
- app/views/annotator_store/annotations/options.json.jbuilder
|
178
|
+
- app/views/annotator_store/annotations/show.json.jbuilder
|
179
|
+
- app/views/annotator_store/pages/index.json.jbuilder
|
180
|
+
- app/views/annotator_store/pages/search.json.jbuilder
|
181
|
+
- app/views/layouts/annotator_store/application.html.erb
|
182
|
+
- config/routes.rb
|
183
|
+
- db/migrate/20141013113654_create_annotator_store.rb
|
184
|
+
- lib/annotator_store.rb
|
185
|
+
- lib/annotator_store/engine.rb
|
186
|
+
- lib/annotator_store/version.rb
|
187
|
+
- lib/tasks/annotator_store_tasks.rake
|
188
|
+
homepage:
|
189
|
+
licenses:
|
190
|
+
- MIT
|
191
|
+
metadata: {}
|
192
|
+
post_install_message:
|
193
|
+
rdoc_options: []
|
194
|
+
require_paths:
|
195
|
+
- lib
|
196
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: 1.9.3
|
201
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
|
+
requirements:
|
203
|
+
- - ">"
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: 1.3.1
|
206
|
+
requirements: []
|
207
|
+
rubyforge_project:
|
208
|
+
rubygems_version: 2.2.2
|
209
|
+
signing_key:
|
210
|
+
specification_version: 4
|
211
|
+
summary: Rails engine to implement a Ruby backend store implementation for Annotator.
|
212
|
+
test_files: []
|