amber-kit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5b2b0cde2d48a5f894ed730b36260d428de273da
4
+ data.tar.gz: df73ca4d62fb83e44fde411594a1d451a3448dbe
5
+ SHA512:
6
+ metadata.gz: d0e02a5aa95e3fbfd6d2cf492fc333b9673a20c565e16452a99b711c3943343ac03f30279ef4bc65b30f2aa21131264bb602136d92afc858380f36f48d627d5c
7
+ data.tar.gz: b2c3db8bcb7203822e8f9604a7f288a35c7a082fb825372128ad651b8718d92e0eb8be1180d3ca1d79c56d2c4734ba779c59fd739c696fe04e699b432c20fb8f
data/Rakefile ADDED
File without changes
data/amber.gemspec ADDED
@@ -0,0 +1,49 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "amber-kit"
3
+ s.version = "0.0.1"
4
+ s.authors = ["Jakit"]
5
+ s.date = "2017-06-03"
6
+ s.summary = "A glitter network toolkit"
7
+ s.description = "Useful network toolkit for create your application"
8
+ s.email = "jakit_liang@outlook.com"
9
+ s.files = [
10
+ "Rakefile",
11
+ "amber.gemspec",
12
+ "bin/amber",
13
+ "lib/amber.rb",
14
+ "lib/amber/controller.rb",
15
+ "lib/amber/data.rb",
16
+ "lib/amber/data/array_data.rb",
17
+ "lib/amber/data/date_data.rb",
18
+ "lib/amber/data/float_data.rb",
19
+ "lib/amber/data/integer_data.rb",
20
+ "lib/amber/data/string_data.rb",
21
+ "lib/amber/data_delegate.rb",
22
+ "lib/amber/http.rb",
23
+ "lib/amber/http/request.rb",
24
+ "lib/amber/http/response.rb",
25
+ "lib/amber/model.rb",
26
+ "lib/amber/route.rb",
27
+ "lib/amber/route_path.rb",
28
+ "lib/amber/server.rb",
29
+ "lib/amber/storage.rb",
30
+ "lib/amber/storage/json.rb",
31
+ "lib/amber/storage/remote_json.rb",
32
+ "lib/amber/switch.rb",
33
+ "lib/amber/switch/content.rb",
34
+ "lib/amber/switch/content/form_data.rb",
35
+ "lib/amber/switch/content/json.rb",
36
+ "lib/amber/switch/content/text.rb",
37
+ "lib/amber/switch/content_delegate.rb",
38
+ "lib/amber/switch/request.rb",
39
+ "lib/amber/switch/request/get.rb",
40
+ "lib/amber/switch/request/post.rb",
41
+ "lib/amber/switch/response.rb",
42
+ "lib/amber/view.rb",
43
+ "lib/amber/view/json.rb"
44
+ ]
45
+ s.executables << 'amber'
46
+ s.require_paths = ["lib"]
47
+ s.homepage = "http://pingz.org.cn/amber"
48
+ s.license = "MIT"
49
+ end
data/bin/amber ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "amber"
4
+
5
+ run_operation = ARGV[0] ? ARGV[0] : "run"
6
+ run_parameter = ARGV[1] ? ARGV[0] : nil
7
+
8
+ current_path = Dir.pwd
9
+
10
+ # Add controller path if exist
11
+ controller_path = current_path + '/controller'
12
+
13
+ if File.exist? controller_path
14
+ $LOAD_PATH << controller_path
15
+ end
16
+
17
+ # Add model path if exist
18
+ model_path = current_path + '/model'
19
+
20
+ if File.exist? model_path
21
+ $LOAD_PATH << model_path
22
+ end
23
+
24
+ # Add library path if exist
25
+ library_path = current_path + '/library'
26
+
27
+ if File.exist? library_path
28
+ $LOAD_PATH << library_path
29
+ end
30
+
31
+ # Add view path if exist
32
+ view_path = current_path + '/view'
33
+
34
+ if File.exist? view_path
35
+ $LOAD_PATH << view_path
36
+ end
37
+
38
+ if run_operation
39
+ case run_operation
40
+ when /\w+.rb/
41
+ if File.exist? run_operation
42
+ if run_operation.slice(0, 1) == '/'
43
+ require run_operation
44
+ else
45
+ require_relative current_path + '/' + run_operation
46
+ end
47
+ end
48
+ when "run"
49
+ amber_instance = Amber.new
50
+ amber_instance.run
51
+ else
52
+ amber_instance = Amber.new
53
+ amber_instance.run
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ class Amber::Controller
2
+ def main
3
+ "Hello World"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class Amber::Data::ArrayData < Amber::Data
2
+ include Amber::DataDelegate
3
+
4
+ def initialize(value = [])
5
+ @delegate = self
6
+
7
+ self.assign(value)
8
+ end
9
+
10
+ def assign(value)
11
+ if value.is_a? Array
12
+ @value = value
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ class Amber::Data::DateData < Amber::Data
2
+ include Amber::DataDelegate
3
+
4
+ def initialize(value = Time.new)
5
+ @delegate = self
6
+
7
+ self.assign(value)
8
+ end
9
+
10
+ def assign(value)
11
+ if (value.is_a?(Integer)) || (value.is_a?(Float))
12
+ @value = Time.at(value)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ class Amber::Data::FloatData < Amber::Data
2
+ include Amber::DataDelegate
3
+
4
+ def initialize(value = 0.0)
5
+ @delegate = self
6
+
7
+ self.assign(value)
8
+ end
9
+
10
+ def assign(value)
11
+ @value = value.to_f
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class Amber::Data::IntegerData < Amber::Data
2
+ include Amber::DataDelegate
3
+
4
+ def initialize(value = 0)
5
+ @delegate = self
6
+
7
+ self.assign(value)
8
+ end
9
+
10
+ def assign(value)
11
+ @value = value.to_i
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class Amber::Data::StringData < Amber::Data
2
+ include Amber::DataDelegate
3
+
4
+ def initialize(value = '')
5
+ @delegate = self
6
+
7
+ self.assign(value)
8
+ end
9
+
10
+ def assign(value)
11
+ @value = value.to_s
12
+ end
13
+ end
data/lib/amber/data.rb ADDED
@@ -0,0 +1,14 @@
1
+ class Amber::Data
2
+ def initialize
3
+ @value = nil
4
+ @delegate = nil
5
+ end
6
+
7
+ def value
8
+ @delegate.fetch if @delegate.class.include?(Amber::DataDelegate)
9
+ end
10
+
11
+ def value=(value)
12
+ @delegate.assign(value) if @delegate.class.include?(Amber::DataDelegate)
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Amber::DataDelegate
2
+ def assign(value)
3
+ @value = value
4
+ end
5
+
6
+ def fetch
7
+ @value
8
+ end
9
+ end
@@ -0,0 +1,229 @@
1
+ class Amber::Http::Request < Amber::Http
2
+ attr_reader :method, :url, :query, :protocol, :body
3
+
4
+ GET = "GET"
5
+ POST = "POST"
6
+ PUT = "PUT"
7
+ DELETE = "DELETE"
8
+
9
+ def initialize(socket)
10
+ super
11
+
12
+ @url = ""
13
+ @query = {}
14
+ @body = {}
15
+ end
16
+
17
+ def receive
18
+ unless self.receive_request
19
+ STDERR.puts "Bad request"
20
+ return false
21
+ end
22
+
23
+ self.receive_header
24
+
25
+ # p @header
26
+
27
+ if @header.has_key?("Content-Length")
28
+ content_length = @header["Content-Length"].to_i
29
+
30
+ if content_length > 0
31
+ self.receive_body(content_length)
32
+ end
33
+ end
34
+
35
+ # p @body_raw_data
36
+
37
+ # p @body
38
+
39
+ return true
40
+ end
41
+
42
+ def receive_request
43
+ last_token = ""
44
+ data = ""
45
+
46
+ Timeout::timeout(30) {
47
+ while buffer = @socket.recv_nonblock(1)
48
+ if last_token == "\r" && buffer == "\n"
49
+ break
50
+ end
51
+
52
+ data << buffer
53
+ last_token = buffer
54
+ end
55
+ }
56
+
57
+ self.parse_request(data)
58
+ end
59
+
60
+ def parse_request(data)
61
+ request_info = data.split(' ')
62
+
63
+ if request_info.length == 3
64
+ case request_info[0]
65
+ when GET
66
+ @method = GET
67
+ when POST
68
+ @method = POST
69
+ when PUT
70
+ @method = PUT
71
+ when DELETE
72
+ @method = DELETE
73
+ else
74
+ return false
75
+ end
76
+
77
+ self.parse_url request_info[1]
78
+ @protocol = request_info[2]
79
+ end
80
+
81
+ return true
82
+ end
83
+
84
+ def parse_url(url)
85
+ if url.include? "?"
86
+ url_info = url.split "?"
87
+ @url = url_info[0]
88
+ if url_info.length > 1
89
+ self.parse_query url_info[1]
90
+ end
91
+ return
92
+ end
93
+ @url = url
94
+ end
95
+
96
+ def parse_query(query_string)
97
+ query_info = query_string.split "&"
98
+ query_info.each do |query_info_item|
99
+ query_item = query_info_item.split "="
100
+ if query_item.length == 2
101
+ query_item_key = query_item[0]
102
+ query_item_value = query_item[1]
103
+ @query[query_item_key] = query_item_value
104
+ end
105
+ end
106
+ end
107
+
108
+ def receive_header
109
+ loop { break unless receive_header_item }
110
+ end
111
+
112
+ def receive_header_item
113
+ last_token = ""
114
+ data = ""
115
+
116
+ while buffer = @socket.recv_nonblock(1)
117
+ if last_token == "\r" && buffer == "\n"
118
+ break
119
+ end
120
+
121
+ data << buffer
122
+ last_token = buffer
123
+ end
124
+
125
+ if data == "\r"
126
+ return false
127
+ end
128
+
129
+ self.parse_header_item(data.chomp)
130
+ end
131
+
132
+ def parse_header_item(data)
133
+ header_item = data.split(": ")
134
+
135
+ if header_item.length == 2
136
+ @header[header_item[0]] = header_item[1]
137
+ end
138
+
139
+ return true
140
+ end
141
+
142
+ def receive_body(size)
143
+ data = @socket.recv(size)
144
+ self.parse_body(data)
145
+ end
146
+
147
+ def parse_body(data)
148
+ @body_raw_data = data
149
+
150
+ if @header.has_key?("Content-Type")
151
+ content_type = @header["Content-Type"]
152
+
153
+ if content_type.include? "application/x-www-form-urlencoded"
154
+ self.parse_form_body(data)
155
+ elsif content_type.include? "multipart/form-data"
156
+ content_type_info = content_type.split("; ")
157
+ content_type_info.each do |info|
158
+ if info.include? "boundary"
159
+ boundary_info = info.split('=')
160
+
161
+ if boundary_info.length == 2
162
+ boundary = boundary_info[1]
163
+ self.parse_multipart_form_body(boundary, data)
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ def parse_form_body(data)
172
+ form_items = data.split('&')
173
+
174
+ form_items.each do |item|
175
+ item_info = item.split('=')
176
+ if item_info.length == 2
177
+ @body[item_info[0]] = item_info[1]
178
+ end
179
+ end
180
+ end
181
+
182
+ def parse_multipart_form_body(boundary, data)
183
+ offset = 0
184
+ boundary_string = "--#{boundary}"
185
+
186
+ while offset = data.index(boundary_string, offset)
187
+ next_offset = data.index(boundary_string, offset + 1)
188
+
189
+ unless next_offset
190
+ break
191
+ end
192
+
193
+ data_part = data.slice(offset + boundary_string.length + 2, next_offset - offset - boundary_string.length - 4)
194
+ self.parse_form_part(data_part)
195
+
196
+ offset = next_offset
197
+ end
198
+ end
199
+
200
+ def parse_form_part(data)
201
+ first_of_break = data.index("\r\n\r\n")
202
+ unless first_of_break === nil
203
+ content_info_data = data.slice(0, first_of_break)
204
+ content_info_data = content_info_data.gsub("\r\n", "; ")
205
+ content_info = content_info_data.split("; ")
206
+ content_disposition = ""
207
+ content_name = ""
208
+
209
+ content_info.each do |info|
210
+ if info.include? "Content-Disposition"
211
+ info_array = info.split(': ')
212
+ content_disposition = info_array[1] if info_array.length == 2
213
+
214
+ elsif info.include? "name="
215
+ info_array = info.split('=')
216
+ content_name = info_array[1] if info_array.length == 2
217
+ end
218
+ end
219
+
220
+ content_body = data.slice(first_of_break + 4, data.length - 4 - first_of_break - 2)
221
+
222
+ unless content_name.empty?
223
+ @body[content_name] = content_body
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ require "timeout"
@@ -0,0 +1,80 @@
1
+ class Amber::Http::Response < Amber::Http
2
+ attr_reader :status, :header, :content_type, :body
3
+
4
+ TEXT_CONTENT = "text/plain"
5
+ HTML_CONTENT = "text/html"
6
+ JSON_CONTENT = "application/json"
7
+
8
+ def initialize(socket)
9
+ super
10
+
11
+ @status_table = {
12
+ "100" => "Continue",
13
+ "200" => "OK",
14
+ "300" => "Multiple Choices",
15
+ "301" => "Moved Permanently",
16
+ "400" => "Bad Request",
17
+ "401" => "Unauthorized",
18
+ "403" => "Forbidden",
19
+ "404" => "Not Found",
20
+ "500" => "Internal Server Error",
21
+ "502" => "Bad Gateway",
22
+ "503" => "Service Unavailable"
23
+ }
24
+
25
+ @mime_table = [
26
+ TEXT_CONTENT,
27
+ HTML_CONTENT,
28
+ JSON_CONTENT
29
+ ]
30
+
31
+ @status = "200"
32
+ @header = {}
33
+ @content_type = HTML_CONTENT
34
+ @body = ""
35
+ end
36
+
37
+ def send
38
+ data = create_status_line
39
+ data << "Server: Amber/0.0.1\r\n"
40
+ @header.each do |key, value|
41
+ data << "#{key}: #{value}\r\n"
42
+ end
43
+ data << "Content-Type: #{@content_type}\r\n"
44
+ data << "Content-Length: #{@body.length}\r\n\r\n"
45
+ data << @body
46
+
47
+ @socket.sendmsg data, 0
48
+ end
49
+
50
+ def create_status_line
51
+ status_line = "HTTP/1.1 "
52
+ status_line << @status
53
+ status_line << ' '
54
+ status_line << @status_table[@status]
55
+ status_line << "\r\n"
56
+ status_line
57
+ end
58
+
59
+ def status=(status)
60
+ @status = status if @status_table.has_key?(status)
61
+ end
62
+
63
+ def header=(header)
64
+ if header.is_a? Hash
65
+ header.each do |key, value|
66
+ @header[key] = value
67
+ end
68
+ end
69
+ end
70
+
71
+ def content_type=(content_type)
72
+ @content_type = content_type if @mime_table.include?(content_type)
73
+ end
74
+
75
+ def body=(body)
76
+ if body.is_a? String
77
+ @body = body.bytes.to_a.pack("C*")
78
+ end
79
+ end
80
+ end
data/lib/amber/http.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Amber::Http
2
+ attr_reader :header
3
+
4
+ def initialize(socket)
5
+ @header = {}
6
+ @body_raw_data = ""
7
+ @socket = socket
8
+ end
9
+ end
@@ -0,0 +1,89 @@
1
+ class Amber::Model
2
+
3
+ def initialize
4
+ @data = {}
5
+ @data["id"] = Amber::Data::IntegerData.new
6
+ end
7
+
8
+ def [](key)
9
+ if @data.has_key? key
10
+ return @data[key]
11
+ end
12
+ end
13
+
14
+ def has_key?(key)
15
+ @data.has_key? key
16
+ end
17
+
18
+ def []=(key, value)
19
+ if value.is_a? Amber::Data
20
+ @data[key] = value
21
+ end
22
+ end
23
+
24
+ def keys
25
+ @data.keys
26
+ end
27
+
28
+ def pack(map = nil)
29
+ data = {}
30
+ if map.is_a? Hash
31
+ map.each do |key, value|
32
+ if @data.has_key? key
33
+ data_item = @data[key]
34
+ data[value] = data_item.value
35
+ end
36
+ end
37
+ else
38
+ @data.each do |key, value|
39
+ data[key] = value.value
40
+ end
41
+ end
42
+ data
43
+ end
44
+
45
+ def unpack(data, map = nil)
46
+ if data.is_a? Hash
47
+ if map.is_a? Hash
48
+ map.each do |key, value|
49
+ if @data.has_key?(key) && data.has_key?(value)
50
+ data_item = @data[key]
51
+ data_item.value = data[value]
52
+ end
53
+ end
54
+ else
55
+ data.each do |key, value|
56
+ if @data.has_key? key
57
+ data_item = @data[key]
58
+ data_item.value = data[key]
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def struct(map = nil, name_only = false)
66
+ struct = {}
67
+ if map.is_a? Hash
68
+ map.each do |key, value|
69
+ if @data.has_key? key
70
+ data_item = @data[key]
71
+ if name_only
72
+ struct[value] = data_item.class.to_s.match('\w+$').to_s
73
+ next
74
+ end
75
+ struct[value] = data_item.class.to_s
76
+ end
77
+ end
78
+ else
79
+ @data.each do |key, value|
80
+ if name_only
81
+ struct[key] = value.class.to_s.match('\w+$').to_s
82
+ next
83
+ end
84
+ struct[key] = value.class.to_s
85
+ end
86
+ end
87
+ struct
88
+ end
89
+ end
@@ -0,0 +1,66 @@
1
+ class Amber::Route
2
+ attr_reader :root
3
+
4
+ def initialize
5
+ @root = Amber::RoutePath.new
6
+ end
7
+
8
+ def map(url, method = nil, &callback)
9
+ layers = self.parse_url(url)
10
+
11
+ if layers.length > 0
12
+ layers.delete ""
13
+ current_layer = @root
14
+
15
+ layers.each do |layer|
16
+ if layer == layers.last
17
+ if current_layer.child.has_key? layer
18
+ path = current_layer.child[layer]
19
+ path.callback = callback
20
+ path.method = method if method
21
+ next
22
+ end
23
+
24
+ new_path = Amber::RoutePath.new
25
+ new_path.callback = callback
26
+ new_path.method = method if method
27
+
28
+ current_layer.add_child(layer, new_path)
29
+ else
30
+ if current_layer.child.has_key? layer
31
+ current_layer = current_layer.child[layer]
32
+ next
33
+ end
34
+
35
+ new_path = Amber::RoutePath.new
36
+ current_layer.add_child(layer, new_path)
37
+ current_layer = new_path
38
+ end
39
+ end
40
+ else
41
+ @root.callback = callback
42
+ end
43
+ end
44
+
45
+ def find(url)
46
+ layers = self.parse_url(url)
47
+ current_layer = @root
48
+
49
+ if layers.length > 0
50
+ layers.delete ""
51
+ layers.each do |layer|
52
+ if current_layer.child.has_key? layer
53
+ current_layer = current_layer.child[layer]
54
+ else
55
+ return nil
56
+ end
57
+ end
58
+ end
59
+
60
+ current_layer
61
+ end
62
+
63
+ def parse_url(url)
64
+ url.split('/')
65
+ end
66
+ end