gocart 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/LICENSE +0 -0
  2. data/README.md +0 -0
  3. data/assets/Gemfile +24 -0
  4. data/assets/Guardfile +37 -0
  5. data/assets/Rakefile +5 -0
  6. data/assets/config.rb +24 -0
  7. data/assets/spec/javascripts/support/jasmine.yml +86 -0
  8. data/assets/spec/javascripts/support/jasmine_config.rb +23 -0
  9. data/assets/spec/javascripts/support/jasmine_runner.rb +32 -0
  10. data/assets/src/server/http_handler.go +136 -0
  11. data/assets/src/server/main.go +31 -0
  12. data/assets/src/server/templates.go +42 -0
  13. data/assets/src/www/app/coffee/adapters/dummy_data.js.coffee +6 -0
  14. data/assets/src/www/app/coffee/adapters/reddit.js.coffee +294 -0
  15. data/assets/src/www/app/coffee/application.js.coffee +23 -0
  16. data/assets/src/www/app/coffee/controllers/app.js.coffee +69 -0
  17. data/assets/src/www/app/coffee/controllers/nav.js.coffee +55 -0
  18. data/assets/src/www/app/coffee/controllers/subreddit_posts.js.coffee +57 -0
  19. data/assets/src/www/app/coffee/helpers/event_manager.js.coffee +3 -0
  20. data/assets/src/www/app/coffee/helpers/properties.js.coffee +19 -0
  21. data/assets/src/www/app/coffee/helpers/storage.js.coffee +14 -0
  22. data/assets/src/www/app/coffee/libs/3rdparty.js.coffee +7 -0
  23. data/assets/src/www/app/coffee/libs/deferred.js.coffee +92 -0
  24. data/assets/src/www/app/coffee/libs/logger.js.coffee +40 -0
  25. data/assets/src/www/app/coffee/libs/mod_loader.js.coffee +44 -0
  26. data/assets/src/www/app/coffee/main.js.coffee +42 -0
  27. data/assets/src/www/app/coffee/models/comment.js.coffee +26 -0
  28. data/assets/src/www/app/coffee/models/post.js.coffee +27 -0
  29. data/assets/src/www/app/coffee/models/sub_reddit.js.coffee +18 -0
  30. data/assets/src/www/app/coffee/widgets/post_detail.js.coffee +2 -0
  31. data/assets/src/www/app/coffee/widgets/posts.js.coffee +45 -0
  32. data/assets/src/www/app/coffee/widgets/subreddit_detail.js.coffee +2 -0
  33. data/assets/src/www/app/coffee/widgets/subreddits.js.coffee +44 -0
  34. data/assets/src/www/app/images/test.png +0 -0
  35. data/assets/src/www/app/partials/index.html +92 -0
  36. data/assets/src/www/app/sass/application.css.scss +136 -0
  37. data/assets/src/www/app/templates/application.gotmpl +2 -0
  38. data/assets/src/www/app/templates/base.gotmpl.erb +27 -0
  39. data/assets/src/www/app/templates/home.gotmpl +9 -0
  40. data/assets/src/www/spec/coffee/deferred-spec.coffee +202 -0
  41. data/assets/src/www/spec/coffee/mocks.coffee +137 -0
  42. data/assets/src/www/spec/coffee/mod_loader-spec.coffee +45 -0
  43. data/assets/src/www/spec/coffee/properties-spec.coffee +21 -0
  44. data/assets/src/www/spec/coffee/reddit_adapter-spec.coffee +143 -0
  45. data/assets/src/www/vendor/css/jq.ui.css +630 -0
  46. data/assets/src/www/vendor/images/ajax-loader.png +0 -0
  47. data/assets/src/www/vendor/images/icons-18-black.png +0 -0
  48. data/assets/src/www/vendor/images/icons-18-white.png +0 -0
  49. data/assets/src/www/vendor/images/icons-36-black.png +0 -0
  50. data/assets/src/www/vendor/images/icons-36-white.png +0 -0
  51. data/assets/src/www/vendor/js/ICanHaz.min.js +10 -0
  52. data/assets/src/www/vendor/js/jq.mobi.min.js +20 -0
  53. data/assets/src/www/vendor/js/jq.ui.min.js +90 -0
  54. data/assets/src/www/vendor/js/jq.web.min.js +58 -0
  55. data/assets/src/www/vendor/js/phonegap-1.1.0.js +4577 -0
  56. data/assets/src/www/vendor/js/touch.js +103 -0
  57. data/assets/tasks/app.rake +34 -0
  58. data/assets/tasks/jasmine.rake +8 -0
  59. data/assets/tasks/server.rake +58 -0
  60. data/assets/tasks/www.rake +163 -0
  61. data/bin/gocart +25 -0
  62. data/lib/gocart.rb +5 -6
  63. data/lib/gocart/base.rb +28 -0
  64. data/lib/gocart/environment.rb +18 -0
  65. data/lib/gocart/version.rb +1 -1
  66. metadata +113 -41
  67. data/.gitignore +0 -4
  68. data/Gemfile +0 -4
  69. data/Rakefile +0 -1
  70. data/gocarg.go +0 -29
  71. data/gocart.gemspec +0 -38
data/LICENSE ADDED
File without changes
File without changes
@@ -0,0 +1,24 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rack'
4
+
5
+ group :development do
6
+ gem 'sass'
7
+ gem 'coffee-script'
8
+ gem 'therubyracer'
9
+ gem 'sprockets'
10
+ gem 'guard'
11
+ gem 'guard-coffeescript'
12
+ gem 'guard-jasmine'
13
+ gem 'guard-sass'
14
+ gem 'guard-rake'
15
+ gem 'guard-livereload'
16
+ gem 'guard-shell'
17
+ gem 'jasmine'
18
+ gem 'yui-compressor'
19
+ gem 'uglifier'
20
+
21
+ gem 'rb-inotify', :require => false
22
+ gem 'rb-fsevent', :require => false
23
+ gem 'rb-fchange', :require => false
24
+ end
@@ -0,0 +1,37 @@
1
+ # More info at https://github.com/guard/guard#readme
2
+
3
+ load File.dirname(__FILE__) + '/config.rb'
4
+
5
+ guard 'coffeescript', :input => 'src/www/spec/coffee', :output => 'spec/javascripts', :hide_success => true
6
+
7
+ guard 'shell' do
8
+ watch(%r{^src/server/.+\.go$}) do
9
+ `GOPATH="#{ROOT}" go install #{GO_APP_NAME} 1>&2`
10
+ end
11
+ end
12
+
13
+ guard 'rake', :task => 'app:www:compile' do
14
+ watch(%r{^src/www/app/coffee/.+$})
15
+ watch(%r{^src/www/app/sass/.+$})
16
+ end
17
+
18
+ guard 'rake', :task => 'app:www:compile_templates' do
19
+ watch(%r{^src/www/app/templates/.+$})
20
+ end
21
+
22
+ guard 'rake', :task => 'app:www:vendor' do
23
+ watch(%r{^src/www/vendor/.+$})
24
+ end
25
+
26
+ guard 'rake', :task => 'app:www:images' do
27
+ watch(%r{^src/www/app/images/.+$})
28
+ end
29
+
30
+ guard 'rake', :task => 'app:www:partials' do
31
+ watch(%r{^src/www/app/partials/.+$})
32
+ end
33
+
34
+ guard 'livereload', :apply_js_live => false do
35
+ watch(%r{bin/assets/www/javascripts/.+$})
36
+ watch(%r{spec/javascripts/.+$})
37
+ end
@@ -0,0 +1,5 @@
1
+ require 'rake'
2
+
3
+ load File.dirname(__FILE__) + '/config.rb'
4
+
5
+ Dir["#{File.dirname(__FILE__)}/tasks/**/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require
5
+
6
+ if !defined? ROOT
7
+ ROOT = Pathname(File.dirname(__FILE__))
8
+
9
+ ASSET_BUNDLES = %w( application.css application.js )
10
+ GO_APP_NAME = 'server'
11
+ GO_BUILD_PATH = ROOT.join('bin')
12
+
13
+ ASSETS_PATH = ROOT.join('bin', 'assets')
14
+ TMPL_BUILD_PATH = ASSETS_PATH.join('templates')
15
+ MIN_WWW_PATH = ASSETS_PATH.join('www-min')
16
+ DEBUG_WWW_PATH = ASSETS_PATH.join('www-debug')
17
+
18
+ WWW_SPEC_PATH = ROOT.join('spec', 'javascripts')
19
+
20
+ WWW_SRC_ROOT_PATH = ROOT.join('src', 'www')
21
+ WWW_SRC_APP_PATH = WWW_SRC_ROOT_PATH.join('app')
22
+ WWW_SRC_VENDOR_PATH = WWW_SRC_ROOT_PATH.join('vendor')
23
+ WWW_SRC_SPEC_PATH = WWW_SRC_ROOT_PATH.join('spec')
24
+ end
@@ -0,0 +1,86 @@
1
+ # src_files
2
+ #
3
+ # Return an array of filepaths relative to src_dir to include before jasmine specs.
4
+ # Default: []
5
+ #
6
+ # EXAMPLE:
7
+ #
8
+ # src_files:
9
+ # - lib/source1.js
10
+ # - lib/source2.js
11
+ # - dist/**/*.js
12
+ #
13
+ src_files:
14
+ - js/vendor/jquery-1.6.4.min
15
+ - js/vendor/ICanHaz.min.js
16
+ - js/vendor/phonegap-1.1.0.js
17
+ - js/vendor/iscroll-min.js
18
+ - js/libs/mod_loader.js
19
+ - js/libs/deferred.js
20
+ - js/libs/3rdparty.js
21
+ - js/libs/logger.js
22
+ - js/helpers/**/*.js
23
+ - js/models/**/*.js
24
+ - js/adapters/**/*.js
25
+ - js/services/**/*.js
26
+ - js/controllers/**/*.js
27
+
28
+ # stylesheets
29
+ #
30
+ # Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
31
+ # Default: []
32
+ #
33
+ # EXAMPLE:
34
+ #
35
+ # stylesheets:
36
+ # - css/style.css
37
+ # - stylesheets/*.css
38
+ #
39
+ stylesheets:
40
+
41
+ # helpers
42
+ #
43
+ # Return an array of filepaths relative to spec_dir to include before jasmine specs.
44
+ # Default: ["helpers/**/*.js"]
45
+ #
46
+ # EXAMPLE:
47
+ #
48
+ # helpers:
49
+ # - helpers/**/*.js
50
+ #
51
+ helpers:
52
+ - mocks.js
53
+
54
+ # spec_files
55
+ #
56
+ # Return an array of filepaths relative to spec_dir to include.
57
+ # Default: ["**/*[sS]pec.js"]
58
+ #
59
+ # EXAMPLE:
60
+ #
61
+ # spec_files:
62
+ # - **/*[sS]pec.js
63
+ #
64
+ spec_files:
65
+
66
+ # src_dir
67
+ #
68
+ # Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
69
+ # Default: project root
70
+ #
71
+ # EXAMPLE:
72
+ #
73
+ # src_dir: public
74
+ #
75
+ src_dir: bin/assets/www-debug
76
+
77
+ # spec_dir
78
+ #
79
+ # Spec directory path. Your spec_files must be returned relative to this path.
80
+ # Default: spec/javascripts
81
+ #
82
+ # EXAMPLE:
83
+ #
84
+ # spec_dir: spec/javascripts
85
+ #
86
+ spec_dir: spec/javascripts
@@ -0,0 +1,23 @@
1
+ module Jasmine
2
+ class Config
3
+
4
+ # Add your overrides or custom config code here
5
+
6
+ end
7
+ end
8
+
9
+
10
+ # Note - this is necessary for rspec2, which has removed the backtrace
11
+ module Jasmine
12
+ class SpecBuilder
13
+ def declare_spec(parent, spec)
14
+ me = self
15
+ example_name = spec["name"]
16
+ @spec_ids << spec["id"]
17
+ backtrace = @example_locations[parent.description + " " + example_name]
18
+ parent.it example_name, {} do
19
+ me.report_spec(spec["id"])
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ $:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
2
+
3
+ require 'rubygems'
4
+ require 'jasmine'
5
+ jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb'))
6
+ require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
7
+ if Jasmine::Dependencies.rspec2?
8
+ require 'rspec'
9
+ else
10
+ require 'spec'
11
+ end
12
+
13
+ jasmine_config = Jasmine::Config.new
14
+ spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
15
+
16
+ should_stop = false
17
+
18
+ if Jasmine::Dependencies.rspec2?
19
+ RSpec.configuration.after(:suite) do
20
+ spec_builder.stop if should_stop
21
+ end
22
+ else
23
+ Spec::Runner.configure do |config|
24
+ config.after(:suite) do
25
+ spec_builder.stop if should_stop
26
+ end
27
+ end
28
+ end
29
+
30
+ spec_builder.start
31
+ should_stop = true
32
+ spec_builder.declare_suites
@@ -0,0 +1,136 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "log"
6
+ "net/http"
7
+ "os"
8
+ "regexp"
9
+ "strings"
10
+ )
11
+
12
+ // HTTP Error Enumerables
13
+ type HttpError struct {
14
+ ErrorString string
15
+ CodeNum int
16
+ }
17
+
18
+ func (h HttpError) Error() string { return h.ErrorString }
19
+ func (h HttpError) Code() int { return h.CodeNum }
20
+ func (h HttpError) Report(w http.ResponseWriter) { http.Error(w, h.ErrorString, h.CodeNum) }
21
+
22
+ var (
23
+ ErrHttpResourceNotFound = &HttpError{ErrorString: "Not found", CodeNum: 404}
24
+ ErrHttpMethodNotAllowed = &HttpError{ErrorString: "Method not allowed", CodeNum: 405}
25
+ ErrHttpBadRequeset = &HttpError{ErrorString: "Bad request", CodeNum: 400}
26
+ ErrHttpInternalError = &HttpError{ErrorString: "Internal failure", CodeNum: 500}
27
+ )
28
+
29
+ type HttpHandler struct {
30
+ RootURLPath string
31
+ TmplPath string
32
+ WwwPath string
33
+ Addr string
34
+ Port uint
35
+ Debug bool
36
+ ServStatic bool
37
+ templates *Templates
38
+ rootURLPathLen int
39
+ wwwURLPathLen int
40
+ }
41
+
42
+ // Load all the temmplates into memeory
43
+ func (h *HttpHandler) loadTemplates() {
44
+ h.templates = &Templates{}
45
+ h.templates.LoadTemplates(h.TmplPath)
46
+ }
47
+
48
+ // Configures the http connection and starts the listender
49
+ func (h *HttpHandler) HandleHttpConnection() {
50
+ h.rootURLPathLen = len(h.RootURLPath + "/")
51
+ h.wwwURLPathLen = len(h.RootURLPath + "/assets/")
52
+
53
+ h.loadTemplates()
54
+
55
+ h.initServeHomeHndlr(h.RootURLPath + "/")
56
+ if h.Debug || h.ServStatic {
57
+ h.initServeStaticHndlr(h.RootURLPath + "/assets/")
58
+ }
59
+
60
+ // Build the address with port if it's provided
61
+ address := h.Addr
62
+ if h.Port != 0 {
63
+ address = fmt.Sprintf("%s:%d", h.Addr, h.Port)
64
+ }
65
+
66
+ err := http.ListenAndServe(address, nil)
67
+ if err != nil {
68
+ log.Fatal("ListenAndServe: ", err)
69
+ }
70
+ }
71
+
72
+ // Network event handler for HTTP trafic. Serves up the
73
+ // home.html file which will allow connection to the websocket
74
+ func (h *HttpHandler) initServeHomeHndlr(path string) {
75
+ regProps := &CommonProps{
76
+ Title: "Go + WWW + Rake test app",
77
+ Debug: h.Debug,
78
+ RootURL: h.RootURLPath,
79
+ Host: "",
80
+ }
81
+
82
+ hostPortRep := regexp.MustCompile(":\\d+$")
83
+
84
+ http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
85
+ if r.URL.Path != h.RootURLPath+"/" {
86
+ ErrHttpResourceNotFound.Report(w)
87
+ return
88
+ }
89
+ if r.Method != "GET" {
90
+ ErrHttpMethodNotAllowed.Report(w)
91
+ return
92
+ }
93
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
94
+
95
+ // Normalalize http host
96
+ if len(regProps.Host) == 0 {
97
+ regProps.Host = r.Host
98
+ if (h.Debug || h.ServStatic) && h.Port != 0 {
99
+ if strings.Contains(r.Host, ":") {
100
+ regProps.Host = hostPortRep.ReplaceAllString(r.Host, fmt.Sprintf(":%d", h.Port))
101
+ } else {
102
+ regProps.Host = fmt.Sprintf("%s:%d", r.Host, h.Port)
103
+ }
104
+ }
105
+ }
106
+
107
+ b, err := h.templates.Render("home", regProps, nil)
108
+ if err != nil {
109
+ log.Println("Failed to render template, home")
110
+ return
111
+ }
112
+
113
+ w.Write(b)
114
+ })
115
+ }
116
+
117
+ // Simple handler for serving static files
118
+ func (h *HttpHandler) initServeStaticHndlr(path string) {
119
+ http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
120
+ asset := r.URL.Path[h.wwwURLPathLen:]
121
+ fullAssetPath := h.WwwPath + "/" + asset
122
+ log.Println(fullAssetPath)
123
+
124
+ file, err := os.Open(fullAssetPath)
125
+ if err != nil {
126
+ ErrHttpResourceNotFound.Report(w)
127
+ return
128
+ }
129
+ stat, err := file.Stat()
130
+ if err != nil {
131
+ ErrHttpInternalError.Report(w)
132
+ return
133
+ }
134
+ http.ServeContent(w, r, asset, stat.ModTime(), file)
135
+ })
136
+ }
@@ -0,0 +1,31 @@
1
+ package main
2
+
3
+ import (
4
+ "flag"
5
+ "log"
6
+ )
7
+
8
+ var addr = flag.String("addr", "", "IP address the server is to run on")
9
+ var port = flag.Uint("port", 0, "Port address to run the server on")
10
+ var rootURLPath = flag.String("root", "", "URL Path root of the webapp")
11
+ var tmplPath = flag.String("tmpl", "assets/templates", "Specifies the directory to use for template assets.")
12
+ var wwwPath = flag.String("www", "assets/www-debug", "Specifies the directory to use for web assest.")
13
+ var debug = flag.Bool("debug", false, "Enable debug mode where extra loging is produce, each request will reload templates, and all assets are served from non-concaticated files.")
14
+ var static = flag.Bool("static", false, "Enables serving up static content from disk")
15
+
16
+ func main() {
17
+ flag.Parse()
18
+
19
+ httpHndlr := &HttpHandler{
20
+ Addr: *addr,
21
+ Port: *port,
22
+ RootURLPath: *rootURLPath,
23
+ TmplPath: *tmplPath,
24
+ WwwPath: *wwwPath,
25
+ Debug: *debug,
26
+ ServStatic: *static,
27
+ }
28
+
29
+ httpHndlr.HandleHttpConnection()
30
+ log.Println("")
31
+ }
@@ -0,0 +1,42 @@
1
+ package main
2
+
3
+ import (
4
+ "bytes"
5
+ "html/template"
6
+ "log"
7
+ )
8
+
9
+ type Templates struct {
10
+ tmpls *template.Template
11
+ }
12
+
13
+ // Object defining what all template data will use
14
+ type TmplProps struct {
15
+ Common *CommonProps
16
+ Contents interface{}
17
+ }
18
+
19
+ // Generic properties shared by all templates
20
+ type CommonProps struct {
21
+ Title string
22
+ Debug bool
23
+ RootURL string
24
+ Host string
25
+ }
26
+
27
+ // Loads the templates from disk and returns them loaded
28
+ // into memory.
29
+ func (t *Templates) LoadTemplates(path string) {
30
+ t.tmpls = template.Must(template.ParseGlob(path + "/*.gotmpl"))
31
+ }
32
+
33
+ // Renders a template and returns the byte array for it
34
+ func (t *Templates) Render(tmplName string, common *CommonProps, contents interface{}) ([]byte, error) {
35
+ buf := bytes.NewBuffer(nil)
36
+ err := t.tmpls.ExecuteTemplate(buf, tmplName, &TmplProps{Common: common, Contents: contents})
37
+ if err != nil {
38
+ log.Println("Error: failed to execute template", tmplName, ", because", err)
39
+ }
40
+
41
+ return buf.Bytes(), err
42
+ }