carte-server 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +49 -0
- data/carte.gemspec +34 -0
- data/config.json +6 -0
- data/config.ru +14 -0
- data/gulpfile.coffee +11 -0
- data/lib/carte.coffee +34 -0
- data/lib/carte.rb +5 -0
- data/lib/carte/client.coffee +14 -0
- data/lib/carte/client/models/card.coffee +19 -0
- data/lib/carte/client/models/cards.coffee +14 -0
- data/lib/carte/client/router.coffee +28 -0
- data/lib/carte/client/views/app.cjsx +21 -0
- data/lib/carte/client/views/card.cjsx +62 -0
- data/lib/carte/client/views/cards.cjsx +45 -0
- data/lib/carte/client/views/content.cjsx +66 -0
- data/lib/carte/client/views/edit.cjsx +77 -0
- data/lib/carte/client/views/footer.cjsx +9 -0
- data/lib/carte/client/views/header.cjsx +44 -0
- data/lib/carte/client/views/list.cjsx +111 -0
- data/lib/carte/server.rb +113 -0
- data/lib/carte/server/models.rb +2 -0
- data/lib/carte/server/models/card.rb +60 -0
- data/lib/carte/server/models/history.rb +20 -0
- data/lib/carte/server/version.rb +7 -0
- data/lib/carte/server/views/cards.builder +18 -0
- data/lib/carte/server/views/index.haml +27 -0
- data/lib/carte/shared/.keep +0 -0
- data/mongoid.yml +10 -0
- data/package.json +36 -0
- data/public/images/icon.png +0 -0
- data/spec/server_spec.rb +174 -0
- metadata +248 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c9ec151590cdcf41c9eca74c23baec0fce5cefad
|
4
|
+
data.tar.gz: 6b8966161d19a8e0c911bd2536df1c74d7157fe7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7db8ee6f8b114c56fad2104b31019c87a82053ead56d3d1552deb25f10a4cbf62e862cf1b39b56e0215a2502fd300881bb2d7e08e1cd65f4538d94c38e69ffb3
|
7
|
+
data.tar.gz: de06f2eca3db3658e49d1646bd70efe20ab3b0bd22cf2b08ad923921dedbf9899656783def2ef8b3f804aa43c62d1c34b4397d2c38c365eedb26f7ab6e69d650
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 tily
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Carte
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'carte'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install carte
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/[my-github-username]/carte/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "carte/server"
|
3
|
+
Carte::Server.configure { Mongoid.load!('mongoid.yml') }
|
4
|
+
include Carte::Server::Models
|
5
|
+
|
6
|
+
namespace :carte do
|
7
|
+
desc 'analyze'
|
8
|
+
task :analyze do
|
9
|
+
title, content = {max: 0, min: 0}, {max: 0, min: 0}
|
10
|
+
count = Hash.new(0)
|
11
|
+
Card.all.each do |card|
|
12
|
+
title[:max] = [card.title.length, title[:max]].max
|
13
|
+
title[:min] = [card.title.length, title[:min]].min
|
14
|
+
content[:max] = [card.content.length, content[:max]].max
|
15
|
+
content[:min] = [card.content.length, content[:min]].min
|
16
|
+
if card.content == ''
|
17
|
+
puts "#{card.title} : content is empty"
|
18
|
+
end
|
19
|
+
count[card.title] += 1
|
20
|
+
end
|
21
|
+
puts "title: #{title}, content: #{content}"
|
22
|
+
count.each do |card, count|
|
23
|
+
puts "#{card}: #{count} items" if count != 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'import fr.txt'
|
28
|
+
task :import do
|
29
|
+
entries = []
|
30
|
+
file = File.open(ENV['FILE'])
|
31
|
+
lines = file.read.split("\n")
|
32
|
+
lines.each_slice(2) do |title, content|
|
33
|
+
Card.create!(title: title, content: content)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'export'
|
38
|
+
task :export do
|
39
|
+
Card.all.each do |card|
|
40
|
+
puts card.title
|
41
|
+
puts card.content
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'reset'
|
46
|
+
task :reset do
|
47
|
+
Card.delete_all
|
48
|
+
end
|
49
|
+
end
|
data/carte.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'carte/server/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "carte-server"
|
8
|
+
spec.version = Carte::Server::VERSION
|
9
|
+
spec.authors = ["tily"]
|
10
|
+
spec.email = ["tidnlyam@gmail.com"]
|
11
|
+
spec.summary = %q{something like dictionary, wiki, or information card}
|
12
|
+
spec.description = %q{something like dictionary, wiki, or information card}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "shotgun"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "httparty"
|
26
|
+
|
27
|
+
spec.add_dependency "sinatra"
|
28
|
+
spec.add_dependency "sinatra-contrib"
|
29
|
+
spec.add_dependency "mongoid"
|
30
|
+
spec.add_dependency "mongoid_auto_increment_id", "0.6.5"
|
31
|
+
spec.add_dependency "will_paginate_mongoid"
|
32
|
+
spec.add_dependency "activesupport"
|
33
|
+
spec.add_dependency "haml"
|
34
|
+
end
|
data/config.json
ADDED
data/config.ru
ADDED
data/gulpfile.coffee
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
gulp = require 'gulp'
|
2
|
+
Carte = require './lib/carte'
|
3
|
+
|
4
|
+
carte = new Carte()
|
5
|
+
path = 'public/app.js'
|
6
|
+
|
7
|
+
gulp.task 'build', ->
|
8
|
+
carte.build watch: false, config: __dirname + '/config.json'
|
9
|
+
|
10
|
+
gulp.task 'watch', ->
|
11
|
+
carte.build watch: true, config: __dirname + '/config.json'
|
data/lib/carte.coffee
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
fs = require 'fs'
|
2
|
+
path = require 'path'
|
3
|
+
gulp = require 'gulp'
|
4
|
+
gulpUtil = require 'gulp-util'
|
5
|
+
source = require 'vinyl-source-stream'
|
6
|
+
browserify = require 'browserify'
|
7
|
+
watchify = require 'watchify'
|
8
|
+
|
9
|
+
module.exports = class Carte
|
10
|
+
build: (options)->
|
11
|
+
config = require(options.config)
|
12
|
+
fs.writeFileSync(__dirname + '/carte/shared/config.json', JSON.stringify(config))
|
13
|
+
dir = path.dirname config.script_path
|
14
|
+
file = path.basename config.script_path
|
15
|
+
browserify = browserify
|
16
|
+
cache: {}
|
17
|
+
packageCache: {}
|
18
|
+
fullPaths: true
|
19
|
+
entries: [__dirname + '/carte/client.coffee']
|
20
|
+
extensions: ['.coffee', '.js', '.cjsx']
|
21
|
+
browserify
|
22
|
+
.transform 'coffee-reactify'
|
23
|
+
.transform 'debowerify'
|
24
|
+
if options.watch
|
25
|
+
watchified = watchify(browserify)
|
26
|
+
watchified.on 'update', ()=> @bundle(browserify, dir, file)
|
27
|
+
watchified.on 'log', gulpUtil.log
|
28
|
+
@bundle(browserify, dir, file)
|
29
|
+
|
30
|
+
bundle: (browserify, dir, file)->
|
31
|
+
browserify
|
32
|
+
.bundle()
|
33
|
+
.pipe source file
|
34
|
+
.pipe gulp.dest dir
|
data/lib/carte.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
React = require('react')
|
2
|
+
Backbone = require('backbone')
|
3
|
+
$ = require('jquery')
|
4
|
+
cssify = require('cssify')
|
5
|
+
AppViewComponent = require('./client/views/app')
|
6
|
+
Router = require('./client/router')
|
7
|
+
|
8
|
+
Backbone.$ = $
|
9
|
+
cssify.byUrl('//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css')
|
10
|
+
|
11
|
+
$(document).ready ()->
|
12
|
+
AppView = React.createFactory(AppViewComponent)
|
13
|
+
appView = AppView(router: new Router)
|
14
|
+
React.render appView, document.getElementById('app')
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Backbone = require('backbone')
|
2
|
+
|
3
|
+
module.exports = class Card extends Backbone.Model
|
4
|
+
idAttribute: 'title'
|
5
|
+
|
6
|
+
isNew: ()->
|
7
|
+
@_isNew
|
8
|
+
|
9
|
+
url: ()->
|
10
|
+
if @isNew()
|
11
|
+
console.log @
|
12
|
+
console.log 'url is new'
|
13
|
+
'/api/cards.json'
|
14
|
+
else
|
15
|
+
console.log 'url is not new'
|
16
|
+
'/api/cards/' + @get('title') + '.json'
|
17
|
+
|
18
|
+
parse: (response)->
|
19
|
+
if response.card then response.card else response
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Backbone = require('backbone')
|
2
|
+
CardModel = require('./card')
|
3
|
+
$ = require('jquery')
|
4
|
+
|
5
|
+
module.exports = class Cards extends Backbone.Collection
|
6
|
+
model: CardModel
|
7
|
+
query: {}
|
8
|
+
url: ()->
|
9
|
+
'/api/cards.json?' + $.param(@query)
|
10
|
+
parse: (response)->
|
11
|
+
console.log response
|
12
|
+
@page = response.page
|
13
|
+
console.log @page
|
14
|
+
response.cards
|
@@ -0,0 +1,28 @@
|
|
1
|
+
querystring = require('querystring')
|
2
|
+
Backbone = require('backbone')
|
3
|
+
|
4
|
+
module.exports = class Router extends Backbone.Router
|
5
|
+
routes:
|
6
|
+
':title' : 'show'
|
7
|
+
'' : 'list'
|
8
|
+
|
9
|
+
list: (string)->
|
10
|
+
location.hash = '/' if location.hash == ''
|
11
|
+
console.log 'list'
|
12
|
+
@current = 'list'
|
13
|
+
@query = querystring.parse(string)
|
14
|
+
console.log @query
|
15
|
+
|
16
|
+
new: ()->
|
17
|
+
console.log 'new'
|
18
|
+
@current = 'new'
|
19
|
+
|
20
|
+
edit: (title)->
|
21
|
+
console.log 'edit', title
|
22
|
+
@current = 'edit'
|
23
|
+
@title = title
|
24
|
+
|
25
|
+
show: (title)->
|
26
|
+
console.log 'show', title
|
27
|
+
@current = 'show'
|
28
|
+
@title = title
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# @cjsx React.DOM
|
2
|
+
Backbone = require('backbone')
|
3
|
+
React = require('react')
|
4
|
+
Header = require('./header')
|
5
|
+
Content = require('./content')
|
6
|
+
Footer = require('./footer')
|
7
|
+
|
8
|
+
module.exports = React.createClass
|
9
|
+
displayName: 'App'
|
10
|
+
|
11
|
+
componentDidMount: ->
|
12
|
+
Backbone.history.start()
|
13
|
+
|
14
|
+
render: ->
|
15
|
+
Button = require('react-bootstrap/lib/Button')
|
16
|
+
<div>
|
17
|
+
<Header key='header' />
|
18
|
+
<Content key='content' router={@props.router} />
|
19
|
+
<Footer key='footer' />
|
20
|
+
</div>
|
21
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# @cjsx React.DOM
|
2
|
+
React = require('react')
|
3
|
+
Edit = require('./edit')
|
4
|
+
ModalTrigger = require('react-bootstrap/lib/ModalTrigger')
|
5
|
+
|
6
|
+
module.exports = React.createClass
|
7
|
+
displayName: 'Card'
|
8
|
+
|
9
|
+
componentDidMount: ->
|
10
|
+
@props.card.on 'change', @forceUpdate.bind(@, null)
|
11
|
+
@props.card.on 'change', (model)->
|
12
|
+
console.log 'change', model
|
13
|
+
|
14
|
+
getInitialState: ()->
|
15
|
+
showTools: false
|
16
|
+
editing: false
|
17
|
+
updating: false
|
18
|
+
title: @props.card.get('title')
|
19
|
+
content: @props.card.get('content')
|
20
|
+
|
21
|
+
onMouseOver: ()->
|
22
|
+
@setState showTools: true
|
23
|
+
|
24
|
+
onMouseLeave: ()->
|
25
|
+
@setState showTools: false
|
26
|
+
|
27
|
+
render: ->
|
28
|
+
console.log 'Card: render'
|
29
|
+
style = {height:'220px'}
|
30
|
+
if @props.card.get('focused')
|
31
|
+
#style.color = 'red'
|
32
|
+
style.borderColor = '#ccc'
|
33
|
+
<div className='col-sm-4' style={padding:'5px'} onMouseOver={@onMouseOver} onMouseLeave={@onMouseLeave}>
|
34
|
+
<div className='list-group' style={margin:'0px',padding:'0px'}>
|
35
|
+
<div className='list-group-item' style={style}>
|
36
|
+
<p>
|
37
|
+
{
|
38
|
+
if @props.card.get('focused')
|
39
|
+
<i className='glyphicon glyphicon-star' style={marginRight:'5px'} />
|
40
|
+
}
|
41
|
+
<strong>
|
42
|
+
{@props.card.get('title')}
|
43
|
+
</strong>
|
44
|
+
<span className='pull-right' style={{visibility: if @state.showTools then 'visible' else 'hidden'}}>
|
45
|
+
<ModalTrigger modal={<Edit card={@props.card} />}>
|
46
|
+
<a href="javascript:void(0)">
|
47
|
+
<i className='glyphicon glyphicon-edit' />
|
48
|
+
</a>
|
49
|
+
</ModalTrigger>
|
50
|
+
|
51
|
+
|
52
|
+
<a href={'#/' + @props.card.get('title')}>
|
53
|
+
<i className='glyphicon glyphicon-link' />
|
54
|
+
</a>
|
55
|
+
</span>
|
56
|
+
</p>
|
57
|
+
<p style={overflow:'scroll',width:'100%',height:'80%',wordWrap:'break-word'}>
|
58
|
+
{@props.card.get('content')}
|
59
|
+
</p>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
</div>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# @cjsx React.DOM
|
2
|
+
React = require('react')
|
3
|
+
Card = require('./card')
|
4
|
+
|
5
|
+
module.exports = React.createClass
|
6
|
+
displayName: 'Cards'
|
7
|
+
|
8
|
+
componentDidMount: ()->
|
9
|
+
console.log 'component did mount'
|
10
|
+
@props.cards.on 'sync', @forceUpdate.bind(@, null)
|
11
|
+
|
12
|
+
render: ->
|
13
|
+
console.log 'render cards', @props.cards
|
14
|
+
if !@props.cards.fetching
|
15
|
+
console.log 'cards loaded'
|
16
|
+
cards = @props.cards.map (card)-> <Card key={card.get("title")} card={card} />
|
17
|
+
<div className='row'>{cards}</div>
|
18
|
+
else if @props.cards.error
|
19
|
+
<div className='row'>
|
20
|
+
{
|
21
|
+
for i in [1..9]
|
22
|
+
<div className='col-sm-4' style={padding:'5px'} onMouseOver={@onMouseOver} onMouseLeave={@onMouseLeave}>
|
23
|
+
<div className='list-group'style={margin:'0px',padding:'0px'}>
|
24
|
+
<div className='list-group-item' style={height:'220px'}>
|
25
|
+
<i className='glyphicon glyphicon-alert' />
|
26
|
+
{@props.cards.error}
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
}
|
31
|
+
</div>
|
32
|
+
else
|
33
|
+
console.log 'cards loading'
|
34
|
+
<div className='row'>
|
35
|
+
{
|
36
|
+
for i in [1..9]
|
37
|
+
<div className='col-sm-4' style={padding:'5px'} onMouseOver={@onMouseOver} onMouseLeave={@onMouseLeave}>
|
38
|
+
<div className='list-group'style={margin:'0px',padding:'0px'}>
|
39
|
+
<div className='list-group-item' style={height:'220px'}>
|
40
|
+
<i className='glyphicon glyphicon-refresh glyphicon-refresh-animate' /> Loading ...
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
}
|
45
|
+
</div>
|