apimaster 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 (43) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +12 -0
  3. data/apimaster.gemspec +14 -0
  4. data/bin/apimaster +6 -0
  5. data/lib/apimaster.rb +21 -0
  6. data/lib/apimaster/application.rb +28 -0
  7. data/lib/apimaster/controllers/errors.rb +34 -0
  8. data/lib/apimaster/error.rb +79 -0
  9. data/lib/apimaster/generators/application.rb +112 -0
  10. data/lib/apimaster/generators/base.rb +206 -0
  11. data/lib/apimaster/generators/command.rb +697 -0
  12. data/lib/apimaster/generators/manifest.rb +51 -0
  13. data/lib/apimaster/generators/options.rb +162 -0
  14. data/lib/apimaster/generators/scripts.rb +64 -0
  15. data/lib/apimaster/generators/simple_logger.rb +44 -0
  16. data/lib/apimaster/generators/templates/Gemfile +21 -0
  17. data/lib/apimaster/generators/templates/LICENSE +20 -0
  18. data/lib/apimaster/generators/templates/README.md +10 -0
  19. data/lib/apimaster/generators/templates/Rakefile +19 -0
  20. data/lib/apimaster/generators/templates/TODO +4 -0
  21. data/lib/apimaster/generators/templates/app/controllers/index_controller.rb.erb +7 -0
  22. data/lib/apimaster/generators/templates/config.ru.erb +8 -0
  23. data/lib/apimaster/generators/templates/config/application.rb.erb +19 -0
  24. data/lib/apimaster/generators/templates/config/boot.rb.erb +17 -0
  25. data/lib/apimaster/generators/templates/config/initializer.rb.erb +13 -0
  26. data/lib/apimaster/generators/templates/config/patches.rb.erb +0 -0
  27. data/lib/apimaster/generators/templates/config/settings/app.yml.erb +3 -0
  28. data/lib/apimaster/generators/templates/config/settings/mongoid.yml.erb +66 -0
  29. data/lib/apimaster/generators/templates/config/settings/oauth.yml.erb +8 -0
  30. data/lib/apimaster/generators/templates/gitignore +10 -0
  31. data/lib/apimaster/generators/templates/lib/module.rb.erb +6 -0
  32. data/lib/apimaster/generators/templates/test/functional_test.rb.erb +2 -0
  33. data/lib/apimaster/generators/templates/test/test_helper.rb.erb +1 -0
  34. data/lib/apimaster/generators/templates/test/unit_test.rb.erb +2 -0
  35. data/lib/apimaster/generators/version.rb +3 -0
  36. data/lib/apimaster/helpers/headers.rb +30 -0
  37. data/lib/apimaster/helpers/request.rb +49 -0
  38. data/lib/apimaster/helpers/session.rb +36 -0
  39. data/lib/apimaster/mapper.rb +86 -0
  40. data/lib/apimaster/models/user.rb +33 -0
  41. data/lib/apimaster/models/user_mock.rb +13 -0
  42. data/lib/apimaster/setting.rb +68 -0
  43. metadata +45 -3
@@ -0,0 +1,13 @@
1
+
2
+ # Initialize environment
3
+ ROOT_PATH = File.expand_path(".")
4
+ ENV["RACK_ENV"] ||= "development"
5
+ Bundler.require(:default, ENV["RACK_ENV"].to_sym)
6
+
7
+ # Initialize settings
8
+ setting_files = "./config/settings/{app,oauth}.yml"
9
+ Apimaster::Setting.environment = ENV["RACK_ENV"]
10
+ Apimaster::Setting.load_file(setting_files)
11
+
12
+ # Database setting
13
+ # Mongoid.load!("./config/settings/mongoid.yml")
@@ -0,0 +1,3 @@
1
+ app:
2
+ base_url: "http://your-app.com"
3
+ site_url: "http://your-app.com"
@@ -0,0 +1,66 @@
1
+ development:
2
+ sessions:
3
+ default:
4
+ database: mongoid
5
+ hosts:
6
+ - localhost:27017
7
+
8
+ # Tell Mongoid which environment this configuration is for.
9
+ production:
10
+ # This starts the session configuration settings. You may have as
11
+ # many sessions as you like, but you must have at least 1 named
12
+ # 'default'.
13
+ sessions:
14
+ # Define the default session.
15
+ default:
16
+ # A session can have any number of hosts. Usually 1 for a single
17
+ # server setup, and at least 3 for a replica set. Hosts must be
18
+ # an array of host:port pairs. This session is single server.
19
+ hosts:
20
+ - flame.mongohq.com:27017
21
+ # Define the default database name.
22
+ database: mongoid
23
+ # Since this database points at a session connected to MongoHQ, we must
24
+ # provide the authentication details.
25
+ username: user
26
+ password: password
27
+ # This defines a secondary session at a replica set.
28
+ replica_set:
29
+ # This configuration is a 3 node replica set.
30
+ hosts:
31
+ - dedicated1.myapp.com:27017
32
+ - dedicated2.myapp.com:27017
33
+ - dedicated3.myapp.com:27017
34
+ database: mongoid
35
+ # We can set session specific options, like reads executing
36
+ # on secondary nodes, and defaulting the session to safe mode.
37
+ options:
38
+ consistency: :eventual
39
+ safe: true
40
+ # This defines a tertiary session at a Mongos fronted shard.
41
+ shard:
42
+ # This configuration is a Mongos shard server.
43
+ hosts:
44
+ - mongos.myapp.com:27017
45
+ database: mongoid
46
+ # This configuration shows an authenticated replica set via a uri.
47
+ another:
48
+ uri: mongodb://user:pass@59.1.22.1:27017,59.1.22.2:27017/mongoid
49
+ # Here we put the Mongoid specific configuration options. These are explained
50
+ # in more detail next.
51
+ options:
52
+ allow_dynamic_fields: false
53
+ identity_map_enabled: true
54
+ include_root_in_json: true
55
+ include_type_for_serialization: true
56
+ # Note this can also be true if you want to preload everything, but this is
57
+ # almost never necessary. Most of the time set this to false.
58
+ preload_models:
59
+ - Canvas
60
+ - Browser
61
+ - Firefox
62
+ scope_overwrite_exception: true
63
+ raise_not_found_error: false
64
+ skip_version_check: false
65
+ use_activesupport_time_zone: false
66
+ use_utc: true
@@ -0,0 +1,8 @@
1
+ oauth:
2
+ production:
3
+ oauth_domain: "open.admaster.com.cn"
4
+
5
+ development:
6
+ oauth_domain: "testopen.admasterapi.com"
7
+
8
+ test:
@@ -0,0 +1,10 @@
1
+ .DS_Store
2
+ *.db
3
+ public/*.*
4
+ coverage/
5
+ *.swp
6
+ .yardoc/
7
+ doc/
8
+ tmp/
9
+ *.rb~
10
+ tags
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+
5
+ module <%= module_name %> end
6
+
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
@@ -0,0 +1,3 @@
1
+ module Apimaster::Generators
2
+ VERSION = "1.5.8"
3
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+
5
+ module Apimaster::Helpers
6
+ module Headers
7
+
8
+ def header_pagination(pagination)
9
+ path = base_url + request.path_info
10
+ next_link = path + "?" + query_string_modifier(page: pagination.next_page)
11
+ last_link = path + "?" + query_string_modifier(page: pagination.page_count)
12
+ pagination_link = "<#{next_link}>; rel=\"next\", <#{last_link}>; rel=\"last\""
13
+ headers "Link" => pagination_link
14
+ end
15
+
16
+ def header_location(path)
17
+ headers "Location" => base_url + path
18
+ end
19
+
20
+ def header_link(path, rel)
21
+ headers "Link" => "<#{base_url+path}>; rel=\"#{rel}\""
22
+ end
23
+
24
+ private
25
+
26
+ def base_url
27
+ Apimaster::Setting.get('app.base_url')
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+ #
5
+ # @author: sunxiqiu@admaster.com.cn
6
+
7
+ module Apimaster::Helpers
8
+ module Request
9
+
10
+ # Convert a hash to a querystring for form population
11
+ def hash_to_query_string(hash)
12
+ hash.collect {|k,v| "#{k}=#{v}"}.join("&")
13
+ end
14
+
15
+ def query_string_modifier(hash)
16
+ hash_to_query_string(CGI::parse(request.query_string).merge(hash))
17
+ end
18
+
19
+ def posts
20
+ @posts ||= to_symbol_key_hash(request_json)
21
+ end
22
+
23
+ private
24
+
25
+ def to_symbol_key_hash(hash)
26
+ return hash unless hash.is_a? Hash
27
+ result = {}
28
+ hash.map do |key, val|
29
+ val = to_symbol_key_hash(val) if val.is_a? Hash
30
+ result[key.to_sym] = val
31
+ end
32
+ result
33
+ end
34
+
35
+ def request_json
36
+ begin
37
+ @request_json ||= parse_json
38
+ rescue JSON::ParserError => e
39
+ raise Apimaster::RequestError, "Problems parsing JSON"
40
+ end
41
+ end
42
+
43
+ def parse_json
44
+ body_data = request.body.read
45
+ body_data.empty? ? {} : JSON.parse(body_data)
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+ #
5
+ # @author: sunxiqiu@admaster.com.cn
6
+
7
+ module Apimaster::Helpers
8
+ module Session
9
+
10
+ # Check logged in user is the owner
11
+ def is_owner? owner_id
12
+ !!current_user && current_user.id.to_i == owner_id.to_i
13
+ end
14
+
15
+ def authorize
16
+ raise Apimaster::UnauthorizedError.new :user unless current_user
17
+ end
18
+
19
+ # Return current_user record if logged in
20
+ def current_user
21
+ @current_user ||= auth_user
22
+ end
23
+
24
+ def auth_user
25
+ @access_token ||= params[:access_token] or header_token
26
+ (test? ? Apimaster::Models::UserMock : Apimaster::Models::User).auth @access_token
27
+ end
28
+
29
+ def header_token
30
+ keys = %w{HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION X_HTTP_AUTHORIZATION}
31
+ authorization ||= keys.inject(nil) { |auth, key| auth || request.env[key] }
32
+ authorization.split[1] if authorization and authorization[/^token/i]
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+
5
+ module Apimaster
6
+ class Mapper
7
+ # include Mongoid::Document
8
+
9
+ def post hash
10
+ from_hash hash
11
+ save
12
+ end
13
+
14
+ def put hash
15
+ from_hash hash
16
+ save
17
+ end
18
+
19
+ def patch hash
20
+ from_hash hash
21
+ save
22
+ end
23
+
24
+ def to_hash accessor = :all
25
+ record = {}
26
+ fields = self.class.find_attrs_in_options(:accessor, accessor)
27
+ fields.each do |field|
28
+ if self.respond_to?(field)
29
+ record[field] = self.send(field)
30
+ else
31
+ raise "Dataset #{self.class} has no method with the name of #{field}"
32
+ end
33
+ end
34
+ record
35
+ end
36
+
37
+ def from_hash(hash, method = :all)
38
+ data = {}
39
+ attrs = [:required, :optional]
40
+
41
+ attrs.each do |type|
42
+ fields = self.class.get_attrs(type, method)
43
+ fields.each do |field|
44
+ if hash.has_key?(field)
45
+ data[field] = hash[field]
46
+ elsif hash.has_key?(field.to_s)
47
+ data[field] = hash[field.to_s]
48
+ else
49
+ raise Apimaster::MissingFieldError.new(self.class.get_class_name, field) if type == :required
50
+ end
51
+ end
52
+ end
53
+
54
+ data.each do |key, val|
55
+ respond_setter key, val
56
+ end
57
+ end
58
+
59
+ def respond_setter key, val
60
+ name = (key.to_s + '=').to_sym
61
+ raise "#{self.class} lost of #{name}" unless self.respond_to?(name)
62
+ self.send name, val
63
+ end
64
+
65
+ class << self
66
+
67
+ OPTION_TYPES = [:accessor, :required, :optional]
68
+
69
+ @attr_options ||= {}
70
+
71
+ # attr_options :url, accessor: [:get, :list]
72
+ def attr_options name, options = {}
73
+ @attr_options[name] = options
74
+ end
75
+
76
+ # [:url, :name]
77
+ def find_attrs_in_options type, option = :all
78
+ raise "Unknown attribute options type: #{type}" unless OPTION_TYPES.include? type
79
+ @attr_options.select do |name, options|
80
+ type_options = options.is_a?(Hash) and options.key?(type) ? options[type] : nil
81
+ type_options.is_a?(Array) and (type_options.include?(option) or type_options.include(:all))
82
+ end.keys
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+
5
+ require 'net/http'
6
+
7
+ module Apimaster::Models
8
+ class User
9
+
10
+ attr_accessor :id
11
+ attr_accessor :email
12
+ attr_accessor :username
13
+
14
+ def initialize hash
15
+ hash.each do |key, val|
16
+ method_name = (key.to_s+'=').to_sym
17
+ self.send(method_name, val) if respond_to?(method_name)
18
+ end
19
+ end
20
+
21
+ def self.auth access_token
22
+ oauth_domain = Apimaster::Setting.get('oauth.oauth_domain')
23
+ json = Net::HTTP.get(oauth_domain, "/user?access_token=#{access_token}", 80)
24
+ user_hash = JSON.parse(json)
25
+
26
+ return nil unless user_hash.is_a?(Hash)
27
+ raise Apimaster::OauthError.new(user_hash["message"]) if user_hash.key?("message")
28
+
29
+ self.new user_hash
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+
5
+ module Apimaster::Models
6
+ class UserMock
7
+
8
+ def self.auth access_token
9
+ User.new id: 1, email: "hello@admaster.com.cn", username: "hello"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Copyright (C) 2011-2012 AdMaster, Inc.
4
+
5
+ module Apimaster
6
+
7
+ module Setting
8
+ class << self
9
+ @@hashes = {}
10
+
11
+ # environments: development, test and production.
12
+ ENVIRONMENTS = %w[test production development]
13
+
14
+ attr_accessor :environment
15
+
16
+ def set(key, value)
17
+ @@hashes[key] = value
18
+ end
19
+
20
+ def get(key, default = nil)
21
+ current = @@hashes
22
+ key.split('.').each do |k|
23
+ if current and current.is_a?(Hash)
24
+ current = current.has_key?(k) ? current[k] : default
25
+ end
26
+ end
27
+ current
28
+ end
29
+
30
+ # Loads the configuration from the YAML files whose +paths+ are passed as
31
+ # arguments, filtering the settings for the current environment. Note that
32
+ # these +paths+ can actually be globs.
33
+ def load_file(*paths)
34
+ paths.each do |pattern|
35
+ Dir.glob(pattern) do |file|
36
+ yaml = config_for_env(YAML.load_file(file)) || {}
37
+ yaml.each_pair do |key, value|
38
+ for_env = config_for_env(value)
39
+ set key, for_env unless value and for_env.nil? and respond_to? key
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ # Given a +hash+ with some application configuration it returns the
48
+ # settings applicable to the current environment. Note that this can only
49
+ # be done when all the keys of +hash+ are environment names included in the
50
+ # +environments+ setting (which is an Array of Strings). Also, the
51
+ # returned config is a indifferently accessible Hash, which means that you
52
+ # can get its values using Strings or Symbols as keys.
53
+ def config_for_env(hash)
54
+ if hash.respond_to? :keys and hash.keys.all? { |k| ENVIRONMENTS.include? k.to_s }
55
+ hash = hash[environment.to_s] || hash[environment.to_sym]
56
+ end
57
+
58
+ if hash.respond_to? :to_hash
59
+ indifferent_hash = Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
60
+ indifferent_hash.merge hash.to_hash
61
+ else
62
+ hash
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end