gocart 0.0.1 → 0.0.2

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.
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
+ }