carte-server 0.0.14 → 0.0.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94f92bcba2bb68b4e76f4380f0d4bcd508db2470
4
- data.tar.gz: ce41c8cdd0b3f0221c3e2b3cad4dae76ce5547f6
3
+ metadata.gz: 1ba4c0c1d9d328e91985d0a435eb4a9c51046a0b
4
+ data.tar.gz: 7c05b9c9d2ce1ffcbdcf4ce2690f94e4a5f56bb7
5
5
  SHA512:
6
- metadata.gz: 73b8fca305b006462412bc800b10cf00cc65675538cb1fb07681edbdcc72478b51583390e423742cd81c7d23a1a03f5966e6928a30f9e3c3a541b608e6feb572
7
- data.tar.gz: ba3a2d310e97f4eee0ca9fa2c57d88ff08cf8ef7a09843e6ef58a593d8569d2cdb7a5be504a90991af6187580af08018d3348b5022ff49fa9ed90fc4d902c0c8
6
+ metadata.gz: f2a939c479661dec2268f1f969f929131cfc487f00eb516abbcf7bffc97012b0a06ea38c6253056a310125b24b143c412b73c68a1519dd3463051aafda2109de
7
+ data.tar.gz: b862890398c149b3a8677b09446f07cf5c713d81910c817aeb5afa8c222b061991434eb4978e6440b0980671ed29443ac34831469c043f43171bb63f5e0b57fc
data/.gitignore CHANGED
@@ -14,5 +14,6 @@
14
14
  mkmf.log
15
15
  /node_modules/
16
16
  /public/app.js
17
+ /public/app.html
17
18
  /lib/carte/shared/custom.json
18
19
  .env
@@ -2,9 +2,22 @@
2
2
  "title": "Carte Sandbox (custom)",
3
3
  "description": "Sandbox for Carte",
4
4
  "icon_link": "http://www.google.com",
5
- "public_folder": "public",
6
- "script_path": "public/app.js",
7
5
  "menu_items": ["latest", "random", "atoz"],
8
6
  "default_query": {"sort": "updated_at", "order": "desc"},
9
- "api_path": ""
7
+
8
+ "root_dir": "public",
9
+ "root_path": "/",
10
+ "api_path": "api",
11
+ "icon_path": "images/icon.png",
12
+ "script_path": "app.js",
13
+ "html_path": "app.html",
14
+ "enable_apple_touch_icon": true,
15
+ "apple_touch_icon_path": "images/apple-touch-icon.png",
16
+ "apple_touch_icon_57_path": "images/apple-touch-icon-57x57.png",
17
+ "apple_touch_icon_72_path": "images/apple-touch-icon-72x72.png",
18
+ "apple_touch_icon_76_path": "images/apple-touch-icon-76x76.png",
19
+ "apple_touch_icon_114_path": "images/apple-touch-icon-114x114.png",
20
+ "apple_touch_icon_120_path": "images/apple-touch-icon-120x120.png",
21
+ "apple_touch_icon_144_path": "images/apple-touch-icon-144x144.png",
22
+ "apple_touch_icon_152_path": "images/apple-touch-icon-152x152.png"
10
23
  }
data/config.ru CHANGED
@@ -1,12 +1,20 @@
1
1
  require 'carte/server'
2
2
  require 'json'
3
3
 
4
+ $config = JSON.parse(File.read('config.json'))
5
+
4
6
  class Carte::Server
5
7
  configure do
6
8
  Mongoid.load! './mongoid.yml'
7
- config = JSON.parse File.read('config.json')
8
- set :carte, config
9
+ set :carte, $config
9
10
  end
10
11
  end
11
12
 
12
- run Carte::Server.new
13
+ map('/') do
14
+ use Rack::Static, urls: [""], root: $config['root_dir'], index: $config['html_path']
15
+ run Rack::Directory.new $config['root_dir']
16
+ end
17
+
18
+ map('/api') do
19
+ run Carte::Server.new
20
+ end
@@ -1,51 +1,77 @@
1
- fs = require 'fs'
1
+ fs = require 'fs-extra'
2
2
  path = require 'path'
3
3
  gulp = require 'gulp'
4
4
  gulpUtil = require 'gulp-util'
5
5
  gulpIf = require 'gulp-if'
6
- source = require 'vinyl-source-stream'
6
+ sourceStream = require 'vinyl-source-stream'
7
7
  browserify = require 'browserify'
8
8
  watchify = require 'watchify'
9
9
  uglify = require 'gulp-uglify'
10
10
  streamify = require 'gulp-streamify'
11
+ _ = require 'lodash'
12
+ jade = require 'gulp-jade'
13
+ rename = require 'gulp-rename'
11
14
 
12
15
  module.exports = class Carte
16
+ watching: false
17
+
13
18
  install: (gulp, config)->
14
- gulp.task 'build', =>
15
- @build
16
- watch: false
17
- minify: true
18
- config: config
19
- gulp.task 'watch', =>
20
- @build
21
- watch: true
22
- minifty: false
23
- config: config
19
+ custom = require(config)
20
+ fs.writeFileSync(__dirname + '/carte/shared/custom.json', JSON.stringify(custom))
21
+
22
+ gulp.task 'watching', => @watching = true
23
+ gulp.task 'build', ['build:html', 'build:script']
24
+ gulp.task 'watch', ['watching', 'build:html', 'build:script']
25
+
26
+ gulp.task 'build:html', =>
27
+ _config = require('./carte/client/config')
28
+ gulp.src('lib/carte/client.jade')
29
+ .pipe jade(locals: {config: _config}, pretty: true)
30
+ .pipe rename(_config.html_path)
31
+ .pipe gulp.dest(_config.root_dir)
32
+
33
+ gulp.task 'build:script', =>
34
+ @buildScript config: config
24
35
 
25
- build: (options)->
36
+ buildScript: (options)->
26
37
  config = require(options.config)
27
38
  fs.writeFileSync(__dirname + '/carte/shared/custom.json', JSON.stringify(config))
28
- dir = path.dirname config.script_path
39
+ dir = config.root_dir
29
40
  file = path.basename config.script_path
30
- minify = options.minify
31
41
  browserify = browserify
32
42
  cache: {}
33
43
  packageCache: {}
34
44
  fullPaths: true
35
45
  entries: [__dirname + '/carte/client.coffee']
36
- extensions: ['.coffee', '.js', '.cjsx']
46
+ extensions: ['.coffee', '.js', '.cjsx', '.css']
37
47
  browserify
38
48
  .transform 'coffee-reactify'
39
49
  .transform 'debowerify'
40
- if options.watch
50
+ .transform 'browserify-css',
51
+ rootDir: 'public'
52
+ processRelativeUrl: (relativeUrl)->
53
+ stripQueryStringAndHashFromPath = (url)-> url.split('?')[0].split('#')[0]
54
+ rootDir = path.resolve(process.cwd(), 'public')
55
+ relativePath = stripQueryStringAndHashFromPath(relativeUrl)
56
+ queryStringAndHash = relativeUrl.substring(relativePath.length)
57
+ prefix = '../node_modules/'
58
+ if (_.startsWith(relativePath, prefix))
59
+ vendorPath = 'vendor/' + relativePath.substring(prefix.length)
60
+ source = path.join(rootDir, relativePath)
61
+ target = path.join(rootDir, vendorPath)
62
+ gulpUtil.log('Copying file from ' + JSON.stringify(source) + ' to ' + JSON.stringify(target))
63
+ fs.copySync(source, target)
64
+ return vendorPath + queryStringAndHash
65
+ relativeUrl
66
+ if @watching
41
67
  watchified = watchify(browserify)
42
- watchified.on 'update', ()=> @bundle(browserify, dir, file, minify)
68
+ watchified.on 'update', ()=> @bundle(browserify, dir, file)
43
69
  watchified.on 'log', gulpUtil.log
44
- @bundle(browserify, dir, file, minify)
70
+ @bundle(browserify, dir, file)
45
71
 
46
- bundle: (browserify, dir, file, minify)->
72
+ bundle: (browserify, dir, file)->
47
73
  browserify
48
74
  .bundle()
49
- .pipe source file
50
- .pipe gulpIf(minify, streamify(uglify()))
75
+ .pipe sourceStream file
76
+ .pipe gulpIf(!@watching, streamify(uglify()))
51
77
  .pipe gulp.dest dir
@@ -4,11 +4,9 @@ $ = require('jquery')
4
4
  cssify = require('cssify')
5
5
  AppViewComponent = require('./client/views/app')
6
6
  Router = require('./client/router')
7
+ require('./client.css')
7
8
 
8
9
  Backbone.$ = $
9
- cssify.byUrl('//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css')
10
- cssify.byUrl('//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css')
11
- cssify.byUrl('//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.6/animate.min.css')
12
10
 
13
11
  $(document).ready ()->
14
12
  AppView = React.createFactory(AppViewComponent)
@@ -0,0 +1,91 @@
1
+ @import "../../node_modules/bootstrap/dist/css/bootstrap.css";
2
+ @import "../../node_modules/font-awesome/css/font-awesome.css";
3
+ @import "../../node_modules/animate.css/animate.css";
4
+
5
+ .navbar-default a,
6
+ .navbar-default a:hover,
7
+ .navbar-default a:visited,
8
+ .navbar-default a:active,
9
+ .nav-pills a,
10
+ .nav-pills a:hover,
11
+ .nav-pills a:visited,
12
+ .nav-pills a:active,
13
+ .tools a,
14
+ .tools a:hover,
15
+ .tools a:visited,
16
+ .tools a:active
17
+ {
18
+ color: #333333 !important;
19
+ text-decoration: none !important;
20
+ }
21
+
22
+ .glyphicon-refresh-animate {
23
+ -animation: spin .7s infinite linear;
24
+ -webkit-animation: spin2 .7s infinite linear;
25
+ }
26
+ @-webkit-keyframes spin2 {
27
+ from { -webkit-transform: rotate(0deg);}
28
+ to { -webkit-transform: rotate(360deg);}
29
+ }
30
+ @keyframes spin {
31
+ from { transform: scale(1) rotate(0deg);}
32
+ to { transform: scale(1) rotate(360deg);}
33
+ }
34
+
35
+ /* https://github.com/olahol/react-tagsinput/blob/master/react-tagsinput.css */
36
+ .react-tagsinput {
37
+ border: 1px solid #ccc;
38
+ background: #fff;
39
+ padding: 10px;
40
+ overflow-y: auto;
41
+ border-radius: 3px;
42
+ }
43
+
44
+ .react-tagsinput-tag {
45
+ display: block;
46
+ /*border: 1px solid #a5d24a;*/
47
+ /*background: #cde69c;*/
48
+ /*color: #638421;*/
49
+ /*font-size: 12px;*/
50
+ /*font-family: 'Helvetica Neue', 'Arial', sans-serif;*/
51
+ float: left;
52
+ /*padding: 5px;*/
53
+ margin-right: 5px;
54
+ /*margin-bottom: 5px;*/
55
+ text-decoration: none;
56
+ border-radius: 2px;
57
+ }
58
+
59
+ .react-tagsinput-invalid {
60
+ background: #FBD8DB !important;
61
+ color: #90111A !important;
62
+ }
63
+
64
+ .react-tagsinput-validating {
65
+ /* background: #FFFACD !important; */
66
+ }
67
+
68
+ .react-tagsinput-remove {
69
+ font-weight: bold;
70
+ /* color: #638421; */
71
+ text-decoration: none;
72
+ font-size: 11px;
73
+ cursor: pointer;
74
+ }
75
+
76
+ .react-tagsinput-remove:before {
77
+ /* content: " x"; */
78
+ }
79
+
80
+ .react-tagsinput-input {
81
+ background: transparent;
82
+ /* color: #777; */
83
+ border: 0;
84
+ /* font-size: 13px; */
85
+ /* font-family: 'Helvetica Neue', 'Arial', sans-serif; */
86
+ /*padding: 5px;*/
87
+ margin: 0;
88
+ width: 80px;
89
+ outline: none;
90
+ }
91
+
@@ -0,0 +1,24 @@
1
+ doctype html
2
+ html
3
+ head
4
+ meta(charset="utf-8")
5
+ meta(name="viewport",content="width=device-width,initial-scale=1.0")
6
+ meta(name="description",content=config.description)
7
+ title= config.title
8
+ script(type="text/javascript",src=config.script_path)
9
+ if config.enable_apple_touch_icon
10
+ link(href='/apple-touch-icon.png',rel='apple-touch-icon')
11
+ for size in ['', '57', '72', '76', '114', '120', '144', '152']
12
+ link(href=config['apple_touch_icon_' + size + '_path'],rel='apple-touch-icon',sizes=size + 'x' + size)
13
+ style.
14
+ a {
15
+ color: #{config.link_color};
16
+ text-decoration: none;
17
+ }
18
+ a:hover,
19
+ a:focus {
20
+ color: #{config.link_active_color};
21
+ text-decoration: underline;
22
+ }
23
+ body
24
+ #app
@@ -1,4 +1,4 @@
1
- $ = require('jquery')
1
+ extend = require('extend')
2
2
  _default = require('../shared/default')
3
3
  custom = require('../shared/custom')
4
- module.exports = $.extend _default, custom
4
+ module.exports = extend _default, custom
@@ -12,13 +12,11 @@ module.exports = class Card extends Backbone.Model
12
12
  if @isNew()
13
13
  console.log @
14
14
  console.log 'url is new'
15
- url = '/api/cards.json'
15
+ url = '/cards.json'
16
16
  else
17
17
  console.log 'url is not new'
18
- url = '/api/cards/' + encodeURIComponent(@get('title')) + '.json'
19
- if config.api_path
20
- url = config.api_path + url
21
- url
18
+ url = '/cards/' + encodeURIComponent(@get('title')) + '.json'
19
+ config.root_path + config.api_path + url
22
20
 
23
21
  parse: (response)->
24
22
  if response.card then response.card else response
@@ -7,10 +7,8 @@ module.exports = class Cards extends Backbone.Collection
7
7
  model: CardModel
8
8
  query: {}
9
9
  url: ()->
10
- url = '/api/cards.json?' + $.param(@query)
11
- if config.api_path
12
- url = config.api_path + url
13
- url
10
+ url = '/cards.json?' + $.param(@query)
11
+ config.root_path + config.api_path + url
14
12
  parse: (response)->
15
13
  console.log response
16
14
  @page = response.page
@@ -1,6 +1,7 @@
1
1
  # @cjsx React.DOM
2
2
  React = require('react')
3
3
  Card = require('./card')
4
+ Message = require('./message')
4
5
 
5
6
  module.exports = React.createClass
6
7
  displayName: 'Cards'
@@ -16,36 +17,26 @@ module.exports = React.createClass
16
17
  @setState error: response
17
18
  @forceUpdate.bind(@, null)
18
19
 
20
+ componentWillReceiveProps: (nextProps)->
21
+ console.log 'component did mount'
22
+ nextProps.cards.on 'sync', @forceUpdate.bind(@, null)
23
+ if nextProps.card
24
+ nextProps.card.on 'error', (model, response)=>
25
+ @setState error: response
26
+ @forceUpdate.bind(@, null)
27
+
19
28
  render: ->
20
29
  console.log 'render cards', @props.cards, @state
21
- if @state.error
22
- <div className='row'>
23
- {
24
- for i in [1..9]
25
- <div className='col-sm-4' style={padding:'5px'} onMouseOver={@onMouseOver} onMouseLeave={@onMouseLeave}>
26
- <div className='list-group'style={margin:'0px',padding:'0px'}>
27
- <div className='list-group-item' style={height:'220px'}>
28
- <i className='glyphicon glyphicon-alert' /> {@state.error.status} {@state.error.statusText}
29
- </div>
30
- </div>
31
- </div>
32
- }
33
- </div>
34
- else if !@props.cards.fetching
30
+ if @props.cards.fetching
31
+ console.log 'cards loading'
32
+ <Message>
33
+ <i className='glyphicon glyphicon-refresh glyphicon-refresh-animate' /> Loading ...
34
+ </Message>
35
+ else if @state.error
36
+ <Message>
37
+ <i className='glyphicon glyphicon-alert' /> {@state.error.status} {@state.error.statusText}
38
+ </Message>
39
+ else
35
40
  console.log 'cards loaded'
36
41
  cards = @props.cards.map (card)-> <Card key={card.get("title")} card={card} />
37
42
  <div className='row'>{cards}</div>
38
- else
39
- console.log 'cards loading'
40
- <div className='row'>
41
- {
42
- for i in [1..9]
43
- <div className='col-sm-4' style={padding:'5px'} onMouseOver={@onMouseOver} onMouseLeave={@onMouseLeave}>
44
- <div className='list-group'style={margin:'0px',padding:'0px'}>
45
- <div className='list-group-item' style={height:'220px'}>
46
- <i className='glyphicon glyphicon-refresh glyphicon-refresh-animate' /> Loading ...
47
- </div>
48
- </div>
49
- </div>
50
- }
51
- </div>
@@ -63,7 +63,7 @@ module.exports = React.createClass
63
63
  <div className="container-fluid">
64
64
  <div className="navbar-header">
65
65
  <a className="navbar-brand" onClick={helpers.reload if !config.icon_link} href={if config.icon_link then config.icon_link else "#/"} style={{paddingTop:"10px"}}>
66
- <img alt="Brand" src="/images/icon.png" width="30" height="30" />
66
+ <img alt="Brand" src={config.root_path + config.icon_path} width="30" height="30" />
67
67
  </a>
68
68
  <a className="navbar-brand" onClick={helpers.reload} href="#/">
69
69
  {config.title}
@@ -53,7 +53,7 @@ module.exports = React.createClass
53
53
  when 'random'
54
54
  <li><a onClick={helpers.reload} href={"#/?" + @randomParam()} style={{padding:'6px 12px',fontWeight: if @props.cards.query.order == 'random' then 'bold' else 'normal'}}>Random</a></li>
55
55
  }
56
- <li><a href={config.api_path + "/api/cards.xml?" + @queryParam({}, [])} style={{padding:'6px 12px'}}><i className="fa fa-rss" /></a></li>
56
+ <li><a href={config.root_path + config.api_path + "/api/cards.xml?" + @queryParam({}, [])} style={{padding:'6px 12px'}}><i className="fa fa-rss" /></a></li>
57
57
  </ul>
58
58
  </div>
59
59
  <div className="col-sm-6" style={{padding:"0px"}}>
@@ -0,0 +1,20 @@
1
+ # @cjsx React.DOM
2
+ React = require('react')
3
+ Card = require('./card')
4
+
5
+ module.exports = React.createClass
6
+ displayName: 'Message'
7
+
8
+ render: ->
9
+ <div className='row'>
10
+ {
11
+ for i in [1..9]
12
+ <div className='col-sm-4' style={padding:'5px'} onMouseOver={@onMouseOver} onMouseLeave={@onMouseLeave}>
13
+ <div className='list-group'style={margin:'0px',padding:'0px'}>
14
+ <div className='list-group-item' style={height:'220px'}>
15
+ {@props.children}
16
+ </div>
17
+ </div>
18
+ </div>
19
+ }
20
+ </div>
@@ -21,7 +21,6 @@ module Carte
21
21
  set :public_folder, 'public'
22
22
  set :default, JSON.parse(File.read(File.join(File.dirname(__FILE__), 'shared/default.json')))
23
23
  set :carte, {}
24
- set :script_path, '/app.js'
25
24
  end
26
25
 
27
26
  helpers do
@@ -61,81 +60,69 @@ module Carte
61
60
  end
62
61
  end
63
62
 
64
- get '/' do
65
- haml :index
63
+ get '/cards.xml' do
64
+ @cards = search(params)
65
+ builder :cards
66
66
  end
67
-
68
- get '/app.js' do
69
- cache_control :public
70
- send_file settings.carte['script_path']
71
- end
72
-
73
- namespace '/api' do
74
- get '/cards.xml' do
75
- @cards = search(params)
76
- builder :cards
77
- end
78
-
79
- get '/cards.json' do
80
- cards = search(params)
81
- if cards.respond_to?(:current_page) && cards.respond_to?(:total_pages)
82
- current_page = cards.current_page.to_i
83
- total_pages = cards.total_pages
84
- end
85
- cards = cards.map {|card| {id: card.id, title: card.title, content: card.content, version: card.version, tags: card.tags}}
86
- {cards: cards, page: {current: current_page, total: total_pages}}.to_json
87
- end
88
-
89
- get '/cards/:title.json' do
90
- card = Card.where(title: params[:title]).first
91
- halt 404 if card.nil?
92
- {card: {id: card.id, title: card.title, content: card.content, version: card.version, tags: card.tags, lefts: card.lefts(4), rights: card.rights(4)}}.to_json
67
+
68
+ get '/cards.json' do
69
+ cards = search(params)
70
+ if cards.respond_to?(:current_page) && cards.respond_to?(:total_pages)
71
+ current_page = cards.current_page.to_i
72
+ total_pages = cards.total_pages
93
73
  end
74
+ cards = cards.map {|card| {id: card.id, title: card.title, content: card.content, version: card.version, tags: card.tags}}
75
+ {cards: cards, page: {current: current_page, total: total_pages}}.to_json
76
+ end
77
+
78
+ get '/cards/:title.json' do
79
+ card = Card.where(title: params[:title]).first
80
+ halt 404 if card.nil?
81
+ {card: {id: card.id, title: card.title, content: card.content, version: card.version, tags: card.tags, lefts: card.lefts(4), rights: card.rights(4)}}.to_json
82
+ end
94
83
 
95
- post '/cards.json' do
96
- card = Card.new(json_data.slice('title', 'content', 'tags'))
97
- if card.save
98
- status 201
99
- {card: {id: card.id}}.to_json
100
- else
101
- status 400
102
- {card: {errors: card.errors}}.to_json
103
- end
84
+ post '/cards.json' do
85
+ card = Card.new(json_data.slice('title', 'content', 'tags'))
86
+ if card.save
87
+ status 201
88
+ {card: {id: card.id}}.to_json
89
+ else
90
+ status 400
91
+ {card: {errors: card.errors}}.to_json
104
92
  end
93
+ end
105
94
 
106
- put '/cards/:title.json' do
107
- card = Card.where(title: params[:title]).first
108
- halt 404 if card.nil?
109
- card.histories.create!
110
- p json_data.slice('new_title', 'content', 'tags').compact
111
- if card.update_attributes(json_data.slice('new_title', 'content', 'tags').compact)
112
- status 201
113
- {}.to_json
114
- else
115
- status 400
116
- {card: {errors: card.errors}}.to_json
117
- end
118
- end
119
-
120
- #delete '/cards/:title.json' do
121
- # card = Card.where(title: params[:title]).first
122
- # halt 404 if card.nil?
123
- # card.destroy
124
- #end
125
-
126
- get '/cards/:title/history.json' do
127
- card = Card.where(title: params[:title]).first
128
- halt 404 if card.nil?
129
- {history: card.histories}.to_json
95
+ put '/cards/:title.json' do
96
+ card = Card.where(title: params[:title]).first
97
+ halt 404 if card.nil?
98
+ card.histories.create!
99
+ if card.update_attributes(json_data.slice('new_title', 'content', 'tags').compact)
100
+ status 201
101
+ {}.to_json
102
+ else
103
+ status 400
104
+ {card: {errors: card.errors}}.to_json
130
105
  end
106
+ end
107
+
108
+ #delete '/cards/:title.json' do
109
+ # card = Card.where(title: params[:title]).first
110
+ # halt 404 if card.nil?
111
+ # card.destroy
112
+ #end
113
+
114
+ get '/cards/:title/history.json' do
115
+ card = Card.where(title: params[:title]).first
116
+ halt 404 if card.nil?
117
+ {history: card.histories}.to_json
118
+ end
131
119
 
132
- get '/tags.json' do
133
- {tags: Card.all_tags}.to_json
134
- end
120
+ get '/tags.json' do
121
+ {tags: Card.all_tags}.to_json
122
+ end
135
123
 
136
- error(404) do
137
- {}.to_json
138
- end
124
+ error(404) do
125
+ {}.to_json
139
126
  end
140
127
  end
141
128
  end
@@ -1,7 +1,8 @@
1
1
  require 'sinatra/base'
2
+ require 'json'
2
3
 
3
4
  module Carte
4
5
  class Server < Sinatra::Base
5
- VERSION = "0.0.14"
6
+ VERSION = JSON.parse(File.read(File.join(File.dirname(__FILE__), "../../../package.json")))['version']
6
7
  end
7
8
  end
@@ -1,15 +1,28 @@
1
1
  {
2
2
  "title": "Carte Sandbox",
3
3
  "description": "Sandbox for Carte",
4
- "public_folder": "public",
5
- "script_path": "public/app.js",
6
4
  "link_color": "#337ab7",
7
5
  "link_active_color": "#23527c",
8
- "api_path": "",
9
6
  "menu_items": ["atoz", "latest", "random"],
10
7
  "default_query": {"sort": "title", "order": "asc"},
11
8
  "title_max_length": 70,
12
9
  "description_max_length": 560,
13
10
  "tags_max_size": 3,
14
- "tag_max_length": 10
11
+ "tag_max_length": 10,
12
+
13
+ "root_dir": "public",
14
+ "root_path": "/",
15
+ "api_path": "api",
16
+ "icon_path": "images/icon.png",
17
+ "script_path": "app.js",
18
+ "html_path": "app.html",
19
+ "enable_apple_touch_icon": true,
20
+ "apple_touch_icon_path": "images/apple-touch-icon.png",
21
+ "apple_touch_icon_57_path": "images/apple-touch-icon-57x57.png",
22
+ "apple_touch_icon_72_path": "images/apple-touch-icon-72x72.png",
23
+ "apple_touch_icon_76_path": "images/apple-touch-icon-76x76.png",
24
+ "apple_touch_icon_114_path": "images/apple-touch-icon-114x114.png",
25
+ "apple_touch_icon_120_path": "images/apple-touch-icon-120x120.png",
26
+ "apple_touch_icon_144_path": "images/apple-touch-icon-144x144.png",
27
+ "apple_touch_icon_152_path": "images/apple-touch-icon-152x152.png"
15
28
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "carte-client",
3
3
  "description": "something like dictionary, wiki, or information card",
4
- "version": "0.0.14",
4
+ "version": "0.0.15",
5
5
  "main": "lib/carte.coffee",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -17,20 +17,26 @@
17
17
  },
18
18
  "homepage": "https://github.com/tily/carte",
19
19
  "dependencies": {
20
+ "animate.css": "^3.2.5",
20
21
  "backbone": "^1.1.2",
21
22
  "bootstrap": "^3.3.4",
22
23
  "browserify": "^9.0.8",
24
+ "browserify-css": "^0.6.1",
23
25
  "coffee-reactify": "^3.0.0",
24
26
  "coffee-script": "^1.9.2",
25
27
  "coffeeify": "^1.0.0",
26
- "cssify": "^0.7.0",
27
28
  "debowerify": "^1.2.1",
29
+ "extend": "^2.0.1",
30
+ "fs-extra": "^0.18.2",
28
31
  "gulp": "^3.8.11",
29
32
  "gulp-if": "^1.2.5",
33
+ "gulp-jade": "^1.0.0",
34
+ "gulp-rename": "^1.2.2",
30
35
  "gulp-streamify": "0.0.5",
31
36
  "gulp-uglify": "^1.2.0",
32
37
  "gulp-util": "^3.0.4",
33
38
  "jquery": "^2.1.3",
39
+ "lodash": "^3.8.0",
34
40
  "markdown-it": "^4.2.0",
35
41
  "react": "^0.13.2",
36
42
  "react-bootstrap": "^0.21.0",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carte-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - tily
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-05 00:00:00.000000000 Z
11
+ date: 2015-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -240,6 +240,8 @@ files:
240
240
  - lib/carte.coffee
241
241
  - lib/carte.rb
242
242
  - lib/carte/client.coffee
243
+ - lib/carte/client.css
244
+ - lib/carte/client.jade
243
245
  - lib/carte/client/config.coffee
244
246
  - lib/carte/client/helpers.coffee
245
247
  - lib/carte/client/models/card.coffee
@@ -253,6 +255,7 @@ files:
253
255
  - lib/carte/client/views/footer.cjsx
254
256
  - lib/carte/client/views/header.cjsx
255
257
  - lib/carte/client/views/list.cjsx
258
+ - lib/carte/client/views/message.cjsx
256
259
  - lib/carte/client/views/pagination.cjsx
257
260
  - lib/carte/server.rb
258
261
  - lib/carte/server/models.rb
@@ -263,11 +266,11 @@ files:
263
266
  - lib/carte/server/validators/array_validator.rb
264
267
  - lib/carte/server/version.rb
265
268
  - lib/carte/server/views/cards.builder
266
- - lib/carte/server/views/index.haml
267
269
  - lib/carte/shared/.keep
268
270
  - lib/carte/shared/default.json
269
271
  - mongoid.yml
270
272
  - package.json
273
+ - public/app.html
271
274
  - public/images/icon.png
272
275
  - screenshot.png
273
276
  - spec/server_spec.rb
@@ -1,105 +0,0 @@
1
- !!! 5
2
- %html
3
- %head
4
- %meta{charset:"utf-8"}
5
- %title= config['title']
6
- %meta{name:"viewport",content:"width=device-width,initial-scale=1.0"}
7
- %meta{name:"description",content:config['description']}
8
- %script{type:"text/javascript",src:"/app.js"}
9
- :css
10
- .navbar-default a,
11
- .navbar-default a:hover,
12
- .navbar-default a:visited,
13
- .navbar-default a:active,
14
- .nav-pills a,
15
- .nav-pills a:hover,
16
- .nav-pills a:visited,
17
- .nav-pills a:active,
18
- .tools a,
19
- .tools a:hover,
20
- .tools a:visited,
21
- .tools a:active
22
- {
23
- color: #333333 !important;
24
- text-decoration: none !important;
25
- }
26
- a {
27
- color: #{config['link_color']};
28
- text-decoration: none;
29
- }
30
- a:hover,
31
- a:focus {
32
- color: #{config['link_active_color']};
33
- text-decoration: underline;
34
- }
35
- .glyphicon-refresh-animate {
36
- -animation: spin .7s infinite linear;
37
- -webkit-animation: spin2 .7s infinite linear;
38
- }
39
- @-webkit-keyframes spin2 {
40
- from { -webkit-transform: rotate(0deg);}
41
- to { -webkit-transform: rotate(360deg);}
42
- }
43
- @keyframes spin {
44
- from { transform: scale(1) rotate(0deg);}
45
- to { transform: scale(1) rotate(360deg);}
46
- }
47
-
48
- /* https://github.com/olahol/react-tagsinput/blob/master/react-tagsinput.css */
49
- .react-tagsinput {
50
- border: 1px solid #ccc;
51
- background: #fff;
52
- padding: 10px;
53
- overflow-y: auto;
54
- border-radius: 3px;
55
- }
56
-
57
- .react-tagsinput-tag {
58
- display: block;
59
- /*border: 1px solid #a5d24a;*/
60
- /*background: #cde69c;*/
61
- /*color: #638421;*/
62
- /*font-size: 12px;*/
63
- /*font-family: 'Helvetica Neue', 'Arial', sans-serif;*/
64
- float: left;
65
- /*padding: 5px;*/
66
- margin-right: 5px;
67
- /*margin-bottom: 5px;*/
68
- text-decoration: none;
69
- border-radius: 2px;
70
- }
71
-
72
- .react-tagsinput-invalid {
73
- background: #FBD8DB !important;
74
- color: #90111A !important;
75
- }
76
-
77
- .react-tagsinput-validating {
78
- /* background: #FFFACD !important; */
79
- }
80
-
81
- .react-tagsinput-remove {
82
- font-weight: bold;
83
- /* color: #638421; */
84
- text-decoration: none;
85
- font-size: 11px;
86
- cursor: pointer;
87
- }
88
-
89
- .react-tagsinput-remove:before {
90
- /* content: " x"; */
91
- }
92
-
93
- .react-tagsinput-input {
94
- background: transparent;
95
- /* color: #777; */
96
- border: 0;
97
- /* font-size: 13px; */
98
- /* font-family: 'Helvetica Neue', 'Arial', sans-serif; */
99
- /*padding: 5px;*/
100
- margin: 0;
101
- width: 80px;
102
- outline: none;
103
- }
104
- %body
105
- #app