carte-server 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
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