amber-kit 0.0.1

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.
@@ -0,0 +1,39 @@
1
+ class Amber::RoutePath
2
+ attr_reader :child, :method, :callback
3
+
4
+ def initialize(method = "GET", callback = nil)
5
+ @child = {}
6
+ @method = method
7
+ @callback = callback
8
+ end
9
+
10
+ def has_child?
11
+ !@child.empty?
12
+ end
13
+
14
+ def can_call?
15
+ @callback != nil
16
+ end
17
+
18
+ def add_child(path, child)
19
+ if child.is_a? Amber::RoutePath
20
+ @child[path] = child
21
+ return
22
+ end
23
+
24
+ raise ArgumentError, "Child should be a route item"
25
+ end
26
+
27
+ def method=(method)
28
+ @method = method
29
+ end
30
+
31
+ def callback=(callback)
32
+ if callback.is_a? Proc
33
+ @callback = callback
34
+ return
35
+ end
36
+
37
+ raise ArgumentError, "Callback should be a proc"
38
+ end
39
+ end
@@ -0,0 +1,103 @@
1
+ class Amber::Server
2
+ attr_accessor :port, :host, :base
3
+
4
+ def initialize(port = 3001, host = '127.0.0.1')
5
+ @port = port
6
+ @host = host
7
+ @server_socket
8
+ @server_address
9
+ @fd_set = []
10
+ end
11
+
12
+ def prepare
13
+ @server_socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
14
+ @server_address = Socket.sockaddr_in(@port, @host)
15
+
16
+ @server_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
17
+ @server_socket.bind(@server_address)
18
+ @server_socket.listen(5)
19
+
20
+ @fd_set << @server_socket
21
+ end
22
+
23
+ def start
24
+ loop {
25
+ fd_items = IO.select(@fd_set, [], [], 5)
26
+
27
+ if fd_items.is_a?(Array)
28
+ readable_items = fd_items.first
29
+ readable_items.each do |socket|
30
+ self.communicate(socket)
31
+ end
32
+ end
33
+ }
34
+ end
35
+
36
+ def communicate(socket)
37
+ if socket == @server_socket
38
+ begin
39
+ client_socket, client_address = @server_socket.accept_nonblock
40
+ @fd_set << client_socket
41
+ rescue IO::WaitReadable, Errno::EINTR
42
+ retry
43
+ end
44
+
45
+ else
46
+ @fd_set.delete(socket)
47
+ task = Fiber.new {
48
+ self.transaction(socket)
49
+ }
50
+ task.resume
51
+ end
52
+ end
53
+
54
+ def transaction(socket)
55
+ http_request = Amber::Http::Request.new(socket)
56
+ http_response = Amber::Http::Response.new(socket)
57
+
58
+ if http_request.receive
59
+ time = Time.new
60
+ time_string = time.strftime("%Y-%m-%d %H:%M:%S")
61
+ STDOUT.puts "#{time_string} #{http_request.method} #{http_request.url}"
62
+ begin
63
+ if (path = @base.route.find(http_request.url)) && path.can_call?
64
+ if path.method == http_request.method
65
+ result = path.callback.call http_request
66
+ case result
67
+ when Amber::View
68
+ http_response.status = result.code.to_s
69
+ http_response.header = result.header
70
+ http_response.content_type = result.content.type
71
+ http_response.body = result.content.body
72
+ when String
73
+ http_response.status = "200"
74
+ http_response.body = result
75
+ else
76
+ http_response.status = "500"
77
+ http_response.body = "<html><h1>Server Internal Error</h1></html>"
78
+ end
79
+ else
80
+ http_response.status = "301"
81
+ http_response.body = "<html><h1>Moved Permanently</h1></html>"
82
+ end
83
+ else
84
+ http_response.status = "404"
85
+ http_response.body = "<html><h1>Not Found</h1></html>"
86
+ end
87
+ rescue Exception => e
88
+ STDOUT.puts e
89
+ end
90
+ else
91
+ http_response.status = "400"
92
+ http_response.body = "<html><h1>Bad Request</h1></html>"
93
+ end
94
+
95
+ http_response.send
96
+
97
+ socket.close
98
+ end
99
+ end
100
+
101
+ require "socket"
102
+ require "fiber"
103
+
@@ -0,0 +1,116 @@
1
+ class Amber::Storage::Json < Amber::Storage
2
+ def initialize(file_path)
3
+ @file_path = file_path
4
+ end
5
+
6
+ def fetch
7
+ data = []
8
+ if raw_data = self.read_file
9
+ data = self.deserialize(raw_data)
10
+ end
11
+ data.first
12
+ end
13
+
14
+ def fetch_all
15
+ data = []
16
+ if raw_data = self.read_file
17
+ data = self.deserialize(raw_data)
18
+ end
19
+ data
20
+ end
21
+
22
+ def save(data)
23
+ if File.exist? @file_path
24
+ file = File.open(@file_path, "w")
25
+ file.puts self.serialize(data)
26
+ file.close
27
+ end
28
+ end
29
+
30
+ def update(data)
31
+ if raw_data = self.read_file
32
+ origin_data = self.deserialize(raw_data)
33
+ new_data = []
34
+
35
+ if data.is_a? Array
36
+ origin_data.each do |item|
37
+ new_item = item
38
+ data.each do |data_item|
39
+ if data_item["id"] == item["id"]
40
+ new_item = data_item
41
+ end
42
+ end
43
+ new_data.push(new_item)
44
+ end
45
+ else
46
+ origin_data.each do |item|
47
+ new_item = item
48
+ if data["id"] == item["id"]
49
+ new_item = data
50
+ end
51
+ new_data.push(new_item)
52
+ end
53
+ end
54
+
55
+ self.save(new_data)
56
+ end
57
+ end
58
+
59
+ def delete(data)
60
+ if raw_data = self.read_file
61
+ origin_data = self.deserialize(raw_data)
62
+ new_data = []
63
+
64
+ if data.is_a? Array
65
+ origin_data.each do |item|
66
+ retain = true
67
+ data.each do |data_item|
68
+ if data_item["id"] == item["id"]
69
+ retain = false
70
+ end
71
+ end
72
+ new_data.push(item) if retain
73
+ end
74
+ else
75
+ origin_data.each do |item|
76
+ retain = true
77
+ if data["id"] == item["id"]
78
+ retain = false
79
+ end
80
+ new_data.push(item) if retain
81
+ end
82
+ end
83
+
84
+ self.save(new_data)
85
+ end
86
+ end
87
+
88
+ def serialize(data)
89
+ begin
90
+ data = [data] unless data.is_a? Array
91
+ JSON.generate(data)
92
+ rescue Exception => e
93
+ p e
94
+ end
95
+ end
96
+
97
+ def deserialize(data)
98
+ begin
99
+ JSON.parse(data)
100
+ rescue Exception => e
101
+ p e
102
+ end
103
+ end
104
+
105
+ def read_file
106
+ if File.exist? @file_path
107
+ file = File.open(@file_path)
108
+ raw_data = file.read
109
+ raw_data = "[]" if raw_data.empty?
110
+ file.close
111
+ return raw_data
112
+ end
113
+ end
114
+ end
115
+
116
+ require "json"
@@ -0,0 +1,103 @@
1
+ class Amber::Storage::RemoteJson < Amber::Storage
2
+ def initialize(url)
3
+ @uri = URI.parse(url)
4
+ @status = false
5
+ @data = {}
6
+ end
7
+
8
+ def query(data)
9
+ self.request({"token" => "", "data" => data})
10
+ end
11
+
12
+ def request(body = nil)
13
+ request = Net::HTTP::Post.new(@uri)
14
+ # request.body = body if body
15
+ response = nil
16
+ @status = false
17
+ @data = {}
18
+ result = Net::HTTP.start(@uri.hostname, @uri.port) do |http|
19
+ response = http.request(request)
20
+ end
21
+
22
+ case result
23
+ when Net::HTTPSuccess
24
+ info = self.deserialize(result.body)
25
+ if info.is_a? Hash
26
+ if info.has_key?("status") && info["status"] == 1
27
+ @status = true
28
+ info_data = {}
29
+ info_data = info["data"] if info.has_key?("data")
30
+ if info_data.is_a?(Array) || info_data.is_a?(Hash)
31
+ @data = info_data
32
+ end
33
+ else
34
+ @status = false
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def serialize(data)
41
+ data_string = ""
42
+ begin
43
+ data = [data] unless data.is_a? Array
44
+ data_string = JSON.generate(data)
45
+ rescue Exception => e
46
+ p e
47
+ end
48
+ data_string
49
+ end
50
+
51
+ def deserialize(data)
52
+ data_struct = nil
53
+ begin
54
+ data_struct = JSON.parse(data)
55
+ rescue Exception => e
56
+ p e
57
+ end
58
+ data_struct
59
+ end
60
+
61
+ def pack(map)
62
+ data = nil
63
+ if map.is_a? Hash
64
+ if @data.is_a? Hash
65
+ data = {}
66
+ map.each do |key, value|
67
+ if @data.has_key? key
68
+ data[value] = @data[key]
69
+ else
70
+ data[value] = nil
71
+ end
72
+ end
73
+ elsif @data.is_a? Array
74
+ data = []
75
+ @data.each do |result_data_item|
76
+ if result_data_item.is_a? Hash
77
+ data_item = {}
78
+ map.each do |key, value|
79
+ if @result_data_item.has_key? key
80
+ data_item[value] = @result_data_item[key]
81
+ else
82
+ data_item[value] = nil
83
+ end
84
+ end
85
+ data.push data_item
86
+ end
87
+ end
88
+ end
89
+ end
90
+ data
91
+ end
92
+
93
+ def unpack(data, map)
94
+ # map.each do |key, value|
95
+ # if data.is_a? Hash
96
+
97
+ # end
98
+ # end
99
+ end
100
+ end
101
+
102
+ require "json"
103
+ require "net/http"
@@ -0,0 +1,8 @@
1
+ class Amber::Storage
2
+ attr_reader :status, :data
3
+
4
+ def initialize
5
+ @status = false
6
+ @data = nil
7
+ end
8
+ end
@@ -0,0 +1,43 @@
1
+ class Amber::Switch::Content::FormData < Amber::Switch::Content
2
+ include Amber::Switch::ContentDelegate
3
+
4
+ def initialize(data = {})
5
+ super Amber::Switch::Content::FORM_DATA_CONTENT, data
6
+ end
7
+
8
+ def data=(data)
9
+ if data.is_a? Hash
10
+ super
11
+ end
12
+ end
13
+
14
+ def serialize(data)
15
+ form_data_string = ""
16
+ if data.is_a? Hash
17
+ form_data_items = []
18
+ data.each do |key, value|
19
+ form_data_item = URI.encode(key) + "=" + URI.encode(value)
20
+ form_data_items.push form_data_item
21
+ end
22
+ form_data_string = form_data_items.join "&"
23
+ end
24
+ form_data_string
25
+ end
26
+
27
+ def deserialize(data)
28
+ form_data = {}
29
+ form_data_string = data.to_s
30
+ form_data_items = form_data_string.split '&'
31
+ form_data_items.each do |form_data_item|
32
+ info = form_data_item.split '='
33
+ if info.length == 2
34
+ key = URI.encode info[0]
35
+ value = URI.decode info[1]
36
+ form_data[key] = value
37
+ end
38
+ end
39
+ form_data
40
+ end
41
+ end
42
+
43
+ require "uri"
@@ -0,0 +1,35 @@
1
+ class Amber::Switch::Content::Json < Amber::Switch::Content
2
+ include Amber::Switch::ContentDelegate
3
+
4
+ def initialize(data = {})
5
+ super Amber::Switch::Content::JSON_CONTENT, data
6
+ end
7
+
8
+ def data=(data)
9
+ if data.is_a? Hash
10
+ super
11
+ end
12
+ end
13
+
14
+ def serialize(data)
15
+ begin
16
+ return JSON.generate data
17
+ rescue Exception => e
18
+ p e
19
+ end
20
+ ""
21
+ end
22
+
23
+ def deserialize(data)
24
+ if data.is_a? String
25
+ begin
26
+ return JSON.parse data
27
+ rescue Exception => e
28
+ p e
29
+ end
30
+ end
31
+ {}
32
+ end
33
+ end
34
+
35
+ require "amber/switch/content_delegate"
@@ -0,0 +1,22 @@
1
+ class Amber::Switch::Content::Text < Amber::Switch::Content
2
+ include Amber::Switch::ContentDelegate
3
+
4
+ def initialize(data = "")
5
+ super Amber::Switch::Content::TEXT_CONTENT, data
6
+ end
7
+
8
+ def data=(data)
9
+ if data.is_a? String
10
+ super
11
+ end
12
+ end
13
+ def serialize(data)
14
+ data.to_s
15
+ end
16
+
17
+ def deserialize(data)
18
+ data.to_s
19
+ end
20
+ end
21
+
22
+ require "amber/switch/content_delegate"
@@ -0,0 +1,38 @@
1
+ class Amber::Switch::Content
2
+ attr_accessor :type
3
+
4
+ TEXT_CONTENT = 'text/plain'
5
+ FORM_DATA_CONTENT = 'application/x-www-form-urlencoded'
6
+ JSON_CONTENT = 'application/json'
7
+
8
+ def initialize(type, data = nil)
9
+ @type = type
10
+
11
+ if data
12
+ self.data = data
13
+ end
14
+ end
15
+
16
+ def data
17
+ @data
18
+ end
19
+
20
+ def data=(data)
21
+ @data = data
22
+ end
23
+
24
+ def body
25
+ if self.class.include? Amber::Switch::ContentDelegate
26
+ return self.serialize @data
27
+ end
28
+ end
29
+
30
+ def body=(body)
31
+ if self.class.include? Amber::Switch::ContentDelegate
32
+ @data = self.deserialize body
33
+ return
34
+ end
35
+ end
36
+ end
37
+
38
+ require "amber/switch/content_delegate"
@@ -0,0 +1,9 @@
1
+ module Amber::Switch::ContentDelegate
2
+ def serialize(data)
3
+
4
+ end
5
+
6
+ def deserialize(data)
7
+
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ class Amber::Switch::Request::Get < Amber::Switch::Request
2
+ def initialize(url = "")
3
+ super Amber::Switch::Request::GET_METHOD, url
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class Amber::Switch::Request::Post < Amber::Switch::Request
2
+ attr_accessor :content
3
+
4
+ def initialize(url = "")
5
+ super Amber::Switch::Request::POST_METHOD, url
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ class Amber::Switch::Request
2
+ attr_accessor :method, :url, :header
3
+
4
+ GET_METHOD = 'GET'
5
+ POST_METHOD = 'POST'
6
+ PUT_METHOD = 'PUT'
7
+ DELETE_METHOD = 'DELETE'
8
+
9
+ def initialize(method, url)
10
+ @method = method
11
+ @url = url
12
+ @header = {}
13
+ end
14
+ end
15
+
16
+ require "json"
@@ -0,0 +1,10 @@
1
+ class Amber::Switch::Response
2
+ attr_accessor :status, :header, :content
3
+
4
+ def initialize
5
+ @status = false
6
+ @header = {}
7
+ end
8
+ end
9
+
10
+ require "json"
@@ -0,0 +1,71 @@
1
+ class Amber::Switch
2
+ def query(request)
3
+ if request.is_a? Amber::Switch::Request
4
+ result = nil
5
+ case request
6
+ when Amber::Switch::Request::Get
7
+ result = self.request(request.url, request.method, request.header)
8
+ when Amber::Switch::Request::Post
9
+ body = request.content.is_a?(Amber::Switch::Content) ? request.content.body : nil
10
+ result = self.request(request.url, request.method, request.header, body)
11
+ end
12
+ if result
13
+ response = Amber::Switch::Response.new
14
+ response.status = result["status"]
15
+ response.header = result["header"]
16
+ response_content_type = result["content_type"].is_a?(Array) ? result["content_type"].first : result["content_type"].to_s
17
+ case response_content_type
18
+ when Amber::Switch::Content::JSON_CONTENT
19
+ response.content = Amber::Switch::Content::Json.new
20
+ response.content.body = result["body"]
21
+ else
22
+ response.content = Amber::Switch::Content::Text.new
23
+ response.content.body = result["body"]
24
+ end
25
+ return response
26
+ end
27
+ end
28
+
29
+ p "#{request} should be an instance of Amber::Switch::Request"
30
+ return
31
+ end
32
+
33
+ def request(url, method, header = {}, body = nil)
34
+ request = nil
35
+ uri = URI(url)
36
+ response = {
37
+ "status" => false,
38
+ "code" => 400,
39
+ "content_type" => nil,
40
+ "header" => {},
41
+ "body" => nil
42
+ }
43
+ case method
44
+ when Amber::Switch::Request::GET_METHOD
45
+ request = Net::HTTP::Get.new uri
46
+ when Amber::Switch::Request::POST_METHOD
47
+ request = Net::HTTP::Post.new uri
48
+ end
49
+ if request
50
+ header.each do |key, value|
51
+ request[key] = value
52
+ end
53
+ request.body = body if body
54
+ result = Net::HTTP.start(uri.hostname, uri.port) do |http|
55
+ http.request(request)
56
+ end
57
+
58
+ case result
59
+ when Net::HTTPSuccess
60
+ response["status"] = true
61
+ response["code"] = result.code.to_i
62
+ response["content_type"] = result.content_type
63
+ response["header"] = result.to_hash
64
+ response["body"] = result.body
65
+ end
66
+ end
67
+ response
68
+ end
69
+ end
70
+
71
+ require "net/http"
@@ -0,0 +1,9 @@
1
+ class Amber::View::Json < Amber::View
2
+ def initialize(code = 404, header = {}, data = nil)
3
+ super code, header, Amber::Switch::Content::Json.new
4
+
5
+ if data
6
+ self.content.data = data
7
+ end
8
+ end
9
+ end
data/lib/amber/view.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Amber::View
2
+ attr_accessor :code, :header, :content
3
+
4
+ def initialize(code = 404, header = {}, content = nil)
5
+ @code = code
6
+ @header = header
7
+ @content = content
8
+ end
9
+ end