doraemon 1.0.14 → 1.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f4bdf7f5bc56c25adb1740cd5895aed9e691f58c1d8d65b9ee927b54c980005
4
- data.tar.gz: 20c6b6a1711262074b936762c0a9522dcf24706a2443d633dcbe96c73e5b9e7e
3
+ metadata.gz: cd9915b76a0811f54ca86b207607bf1fb203b0b03abe725e6eedda5387403f17
4
+ data.tar.gz: 01e2ac17bd28a96492657d994234f8fbfa6e0567f6c826a73bea5d1b9e6c095f
5
5
  SHA512:
6
- metadata.gz: 141a231646384e2d35f85caafdcd3924c4f3fa9553704391ece07ed14fb225ef4f90a4c75422546b161163dbecd2a009ee6e7f06a42aed316d4fd4926143ffc9
7
- data.tar.gz: a04210a4a7157f1f242e87746a62f90827b889e883cb527e5d8b94223f4622e481d4d31268dbff6d1ff49c5d16741aa8f5b8c6bfe1c63ff522520aad8bbf9ee1
6
+ metadata.gz: ab9f0aa9ebe998f00d1aa135a87b2efbdae4cd20d548a2fb152b06dbe20796aba57aa59c51db4095dc570d872f2c6911175692e833fdf96f5112642c9a76ef6f
7
+ data.tar.gz: 63a30862c9a0cd21b406902361df5d764ab82b6bfb55d36bfa309ce38ab8b40e1fb6808ec6c76b452510fe60c751c190ede214d0f2de266cb356e20fded7b551
data/exe/doraemon CHANGED
@@ -25,11 +25,12 @@ Thread.new {
25
25
 
26
26
  sleep(0.5)
27
27
 
28
- ip = local_ip_address
28
+ Doraemon::LOCAL_IP_ADDRESS = local_ip_address
29
+ Doraemon::LOCAL_PORT = port
29
30
 
30
31
  puts "\n"
31
32
  puts '============================================='
32
- puts "Dashboard: http://#{ip}:#{port}/"
33
+ puts "Dashboard: http://#{Doraemon::LOCAL_IP_ADDRESS}:#{port}/"
33
34
  puts '============================================='
34
35
 
35
36
  trap 'INT' do
@@ -3,13 +3,14 @@
3
3
 
4
4
  require 'sinatra'
5
5
  require_relative '../database'
6
+ require_relative './base'
6
7
 
7
8
  module Doraemon
8
9
 
9
10
  class HTTPServer < Sinatra::Base
10
11
 
11
12
  post '/api/mocker/api/all' do
12
- stream :keep_open do |out|
13
+ handle_api do |out|
13
14
  uid = request.uid_from_token
14
15
  scene_id = request.body_params['scene_id']
15
16
  DB.query_apis(scene_id) do |scene_name, is_actived, apis|
@@ -39,7 +40,7 @@ module Doraemon
39
40
  end
40
41
 
41
42
  post '/api/mocker/api/save' do
42
- stream :keep_open do |out|
43
+ handle_api do |out|
43
44
  scene_id = request.body_params['scene_id']
44
45
  apis = request.body_params['apis']
45
46
  DB.save_apis(scene_id, apis) do |_|
@@ -50,7 +51,7 @@ module Doraemon
50
51
  end
51
52
 
52
53
  post '/api/mocker/api/create' do
53
- stream :keep_open do |out|
54
+ handle_api do |out|
54
55
  scene_id = request.body_params['scene_id']
55
56
  path = request.body_params['path']
56
57
  DB.create_api(scene_id, path) do |api|
@@ -61,7 +62,7 @@ module Doraemon
61
62
  end
62
63
 
63
64
  post '/api/mocker/api/delete' do
64
- stream :keep_open do |out|
65
+ handle_api do |out|
65
66
  id = request.body_params['id']
66
67
  DB.delete_api(id) do |_|
67
68
  out << {code: 0, msg: 'OK'}.to_json
@@ -71,7 +72,7 @@ module Doraemon
71
72
  end
72
73
 
73
74
  post '/api/mocker/api/modify' do
74
- stream :keep_open do |out|
75
+ handle_api do |out|
75
76
  id = request.body_params['id']
76
77
  enabled = request.body_params['enabled']
77
78
  path = request.body_params['path']
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'sinatra'
5
+
6
+ module Doraemon
7
+ # 处理 API 请求,用于捕获异常并响应
8
+ def handle_api
9
+ stream :keep_open do |out|
10
+ begin
11
+ yield(out) if block_given?
12
+ rescue Exception => e
13
+ msg = e.full_message(order: :top)
14
+ puts "Catch exception: #{msg}"
15
+ out << {
16
+ code: -1, msg: msg
17
+ }
18
+ out.close
19
+ end
20
+ end
21
+ end
22
+ end
@@ -5,6 +5,7 @@ require 'sinatra'
5
5
  require_relative '../utils/aes'
6
6
  require_relative '../database'
7
7
  require_relative '../user'
8
+ require_relative './base'
8
9
 
9
10
  module Doraemon
10
11
 
@@ -12,7 +13,7 @@ module Doraemon
12
13
 
13
14
  # 登录
14
15
  post '/api/mocker/user/login' do
15
- stream :keep_open do |out|
16
+ handle_api do |out|
16
17
  username = request.body_params['username']
17
18
  DB.query_user(username) do |user|
18
19
  if user.nil?
@@ -30,15 +31,18 @@ module Doraemon
30
31
 
31
32
  # 用户注册
32
33
  post '/api/mocker/user/register' do
33
- stream :keep_open do |out|
34
+ handle_api do |out|
34
35
  username = request.body_params['username']
35
- DB.register_user(username) do |succ|
36
+ DB.register_user(username) do |succ, uid|
36
37
  if (succ)
37
- out << {code: 0, msg: 'OK'}.to_json
38
+ DB.add_scene(uid, '默认场景') do |scene|
39
+ out << {code: 0, msg: 'OK'}.to_json
40
+ out.close
41
+ end
38
42
  else
39
43
  out << {code: -1, msg: '用户已注册'}.to_json
44
+ out.close
40
45
  end
41
- out.close
42
46
  end
43
47
  end
44
48
  end
@@ -5,6 +5,7 @@ require 'sinatra'
5
5
  require_relative '../database'
6
6
  require_relative '../utils/request'
7
7
  require_relative '../user'
8
+ require_relative './base'
8
9
 
9
10
  module Doraemon
10
11
 
@@ -12,7 +13,7 @@ module Doraemon
12
13
 
13
14
  # 获取场景列表
14
15
  post '/api/mocker/scenes/all' do
15
- stream :keep_open do |out|
16
+ handle_api do |out|
16
17
  uid = request.uid_from_token
17
18
  DB.query_scenes(uid) do |scenes|
18
19
  DB.query_user_with_uid(uid) do |user|
@@ -40,7 +41,7 @@ module Doraemon
40
41
 
41
42
  # 添加场景
42
43
  post '/api/mocker/scenes/add' do
43
- stream :keep_open do |out|
44
+ handle_api do |out|
44
45
  uid = request.uid_from_token
45
46
  name = request.body_params['name']
46
47
  if name.nil? || name.length == 0
@@ -57,7 +58,7 @@ module Doraemon
57
58
 
58
59
  # 激活场景
59
60
  post '/api/mocker/scene/active' do
60
- stream :keep_open do |out|
61
+ handle_api do |out|
61
62
  uid = request.uid_from_token
62
63
  scene_id = request.body_params['scene_id']
63
64
  DB.active_scene(uid, scene_id) do |_|
@@ -69,7 +70,7 @@ module Doraemon
69
70
  end
70
71
 
71
72
  post '/api/mocker/scene/delete' do
72
- stream :keep_open do |out|
73
+ handle_api do |out|
73
74
  uid = request.uid_from_token
74
75
  # TODO:
75
76
  end
@@ -23,9 +23,9 @@ end
23
23
 
24
24
  def _web_echo(text = nil)
25
25
  if text.nil?
26
- "http://192.168.2.81:4001/echo.html"
26
+ "http://#{Doraemon::LOCAL_IP_ADDRESS}:#{Doraemon::LOCAL_PORT}/echo.html"
27
27
  else
28
- "http://192.168.2.81:4001/echo.html?text=#{text}"
28
+ "http://#{Doraemon::LOCAL_IP_ADDRESS}:#{Doraemon::LOCAL_PORT}/echo.html?text=#{text}"
29
29
  end
30
30
  end
31
31
 
@@ -15,11 +15,12 @@
15
15
  </head>
16
16
 
17
17
  <body>
18
- <div class="container">
19
- <div id="nav">
20
- <div id="div_save_btn">
18
+ <div class="container-fluid">
19
+ <div class="nav">
20
+
21
+ <div class="nav-left-area">
21
22
  <button type="button" class="btn" id="back_btn" onclick="backBtnClicked()">
22
- <span>
23
+ <span class="nav-text">
23
24
  <i class="fa fa-chevron-left" aria-hidden="true"></i>
24
25
  返回
25
26
  </span>
@@ -33,19 +34,22 @@
33
34
  <div class="scene_name">
34
35
  <p id="scene_name"></p>
35
36
  </div>
36
- <div id="right-area">
37
- <div id="user_info">
38
- <div id="user_info_name"></div>
39
- <div id="user_info_port"></div>
40
- </div>
41
- <div class="operation-button">
42
- <a href="help.html" target="_blank">
43
- <i class="fa fa-question-circle fa-lg" aria-hidden="true"></i>
44
- </a>
45
- </div>
37
+ </div>
38
+
39
+ <div class="nav-right-area">
40
+ <div id="user_info">
41
+ <div id="user_info_name"></div>
42
+ <div id="user_info_port"></div>
43
+ </div>
44
+ <div class="operation-button">
45
+ <a href="help.html" target="_blank">
46
+ <i class="fa fa-question-circle fa-lg" aria-hidden="true"></i>
47
+ </a>
46
48
  </div>
47
49
  </div>
50
+
48
51
  </div>
52
+
49
53
  <div class="content">
50
54
  <div class="row">
51
55
  <div class="col-sm-3">
@@ -27,10 +27,6 @@
27
27
  margin-top: 5px;
28
28
  }
29
29
 
30
- #back_btn:hover {
31
- background: #fff;
32
- }
33
-
34
30
  #save_btn {
35
31
  width: 100px;
36
32
  float: left;
@@ -65,6 +61,10 @@
65
61
  line-height: 50px;
66
62
  }
67
63
 
64
+ .fa-question-circle {
65
+ color: #fff;
66
+ }
67
+
68
68
  .left_panel {
69
69
  height: 50px;
70
70
  line-height: 50px;
@@ -104,23 +104,36 @@
104
104
  padding-left: 0px;
105
105
  }
106
106
 
107
- .api_path {
108
- float: left;
109
- font-family: monospace;
110
- font-size: 12;
107
+ .api_item_wrap {
108
+ display: flex;
109
+ justify-content: space-between;
110
+ align-items: center;
111
+ }
112
+
113
+ .api_path_wrap {
114
+ max-width: 85%;
115
+ word-wrap: break-word;
116
+ cursor: pointer;
111
117
  }
112
118
 
113
- .api_path_disabled {
119
+ .api_path {
114
120
  float: left;
115
121
  font-family: monospace;
116
- font-size: 12;
122
+ font-size: 12px;
123
+ font-weight: normal;
124
+ color: #0066CC;
117
125
  }
118
126
 
119
- .api_path_disabled a {
127
+ .disabled {
120
128
  color: #aaa;
121
129
  font-style: italic;
122
130
  }
123
131
 
132
+ .selected {
133
+ font-size: 13px;
134
+ font-weight: bold;
135
+ }
136
+
124
137
  .api_delete {
125
138
  float: right;
126
139
  }
@@ -1,25 +1,42 @@
1
1
  html, body {
2
2
  height: 100%;
3
- margin: 0px auto;
3
+ margin: 0px;
4
4
  padding: 0px auto;
5
5
  }
6
6
 
7
- .container {
8
- margin: 0 auto;
9
- padding: 0 auto;
7
+ .container-fluid {
8
+ padding: 0;
10
9
  }
11
10
 
12
- #nav {
13
- background-color: #fff;
14
- height: 50px;
11
+ .nav {
12
+ background-color: #444;
13
+ height: 4rem;
14
+ display: block;
15
+ color: white;
16
+ font-weight: bold;
17
+ }
18
+
19
+ .nav-left-area {
20
+ position: absolute;
21
+ top: 0.5rem;
22
+ height: 3rem;
23
+ left: 2rem
24
+ }
25
+
26
+ .nav-right-area {
27
+ position: absolute;
28
+ top: 0.5rem;
29
+ height: 3rem;
30
+ right: 2rem
31
+ }
32
+
33
+ .nav-text {
34
+ color: white;
35
+ font-weight: bold;
15
36
  }
16
37
 
17
38
  .content {
18
- width: 100%;
19
- height: 100%;
20
- top: 50px;
21
- bottom: 0px;
22
- left: 0px;
39
+ margin: 1rem 2rem 0 2rem;
23
40
  }
24
41
 
25
42
  #user_info {
@@ -5,8 +5,8 @@
5
5
  #add_scene_btn {
6
6
  width: 100px;
7
7
  float: left;
8
- margin-left: 10px;
9
- margin-top:5px;
8
+ margin-top: 0.3rem;
9
+ height: 80%;
10
10
  }
11
11
 
12
12
  a.card-control {
@@ -12,20 +12,24 @@
12
12
  </head>
13
13
 
14
14
  <body>
15
- <div class="container-lg">
16
- <div id="nav">
17
- <div id="div_save_btn">
15
+ <div class="container-fluid">
16
+ <div class="nav">
17
+ <div class="nav-left-area">
18
18
  <button type="button" class="btn btn-primary" id="add_scene_btn" onclick="addSceneBtnClicked()">
19
19
  添加场景
20
20
  </button>
21
+ </div>
22
+ <div class="nav-right-area">
21
23
  <div id="user_info">
22
24
  <div id="user_info_name"></div>
23
25
  <div id="user_info_port"></div>
24
26
  </div>
25
27
  </div>
26
28
  </div>
27
- <div class="row" id="scenes">
28
-
29
+
30
+ <div class="content">
31
+ <div class="row" id="scenes">
32
+ </div>
29
33
  </div>
30
34
  </div>
31
35
  </body>
@@ -33,19 +33,26 @@ function reloadLeftSide() {
33
33
  $('tbody').empty();
34
34
  let rows = '';
35
35
  for (let i = 0; i < _apis.length; ++i) {
36
- let api = _apis[i];
37
- let className = "api_path";
38
- if (!api.enabled) {
39
- className += " api_path_disabled";
40
- }
41
- rows += '<tr>';
42
- rows += '<td>';
43
- rows += '<div>';
44
- rows += '<div class="' + className + '" id=api_' + i + '><a href="javascript:void(0);" onclick="selectApi(' + i + ')"><div>' + api.path + '</div></a></div>';
45
- rows += '<div class="api_delete" data-toggle="modal" data-target="#api_edit_modal" data-index=' + i + '><a href="javascript:void(0);"><i class="fa fa-edit fa-sm" aria-hidden="true"></i></a></div>';
46
- rows += '</div>';
47
- rows += '</td>';
48
- rows += '</tr>';
36
+ const api = _apis[i];
37
+ const disabled = api.enabled ? '' : 'disabled';
38
+ rows += `
39
+ <tr>
40
+ <td>
41
+ <div class="api_item_wrap">
42
+ <div class="api_path_wrap" onclick="selectApi(${i})">
43
+ <div class="api_path ${disabled}" id="api_${i}">
44
+ ${api.path}
45
+ </div>
46
+ </div>
47
+ <div class="api_delete" data-toggle="modal" data-target="#api_edit_modal" data-index=${i}>
48
+ <a href="javascript:void(0);">
49
+ <i class="fa fa-edit fa-sm" aria-hidden="true"></i>
50
+ </a>
51
+ </div>
52
+ </div>
53
+ </td>
54
+ </tr>
55
+ `
49
56
  }
50
57
  if (rows.length) {
51
58
  $('tbody').append(rows);
@@ -54,12 +61,9 @@ function reloadLeftSide() {
54
61
 
55
62
  // 选中了一个 API
56
63
  function selectApi(index) {
57
- $("#api_" + _selected_api_index).css('font-weight', 'normal');
58
- $("#api_" + _selected_api_index).css('font-size', '12px');
59
- let api = _apis[index];
60
- $("#api_" + index).css('font-weight', 'bold');
61
- $("#api_" + index).css('font-size', '13px');
62
- monacoEditor.getModel().setValue(api.contents);
64
+ $("#api_" + _selected_api_index).removeClass('selected');
65
+ $("#api_" + index).addClass('selected');
66
+ monacoEditor.getModel().setValue(_apis[index].contents);
63
67
  _selected_api_index = index;
64
68
  }
65
69
 
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ module Doraemon
5
+
6
+ LOCAL_IP_ADDRESS = nil
7
+
8
+ LOCAL_PORT = 4001
9
+
10
+ end
@@ -46,8 +46,10 @@ module Doraemon
46
46
 
47
47
  uri = URI.join(api_host, api_path)
48
48
 
49
+ uri.query = request.query_string
50
+
49
51
  h = request.extract_header(
50
- 'System-Version',
52
+ 'System-Version',
51
53
  'Authorization',
52
54
  'Accept',
53
55
  'Device-Id',
@@ -61,7 +63,8 @@ module Doraemon
61
63
  'User-Agent',
62
64
  'Connection',
63
65
  'Client',
64
- 'Sign'
66
+ 'Sign',
67
+ 'Cookie'
65
68
  )
66
69
  .merge \
67
70
  'Host': uri.host,
@@ -70,8 +73,12 @@ module Doraemon
70
73
  http = Net::HTTP.new(uri.host, uri.port)
71
74
  http.use_ssl = uri.scheme == 'https'
72
75
 
73
- _req = Net::HTTP::Post.new(uri, h)
74
- _req.body = request_body
76
+ is_get = request.request_method == 'GET'
77
+
78
+ _req = is_get ? Net::HTTP::Get.new(uri, h) : Net::HTTP::Post.new(uri, h)
79
+ if !is_get
80
+ _req.body = request_body
81
+ end
75
82
 
76
83
  _resp = http.request(_req)
77
84
 
@@ -150,6 +157,24 @@ module Doraemon
150
157
  end
151
158
  end
152
159
 
160
+ get '/mock/*' do
161
+ stream :keep_open do |out|
162
+ begin
163
+ handle_request(request) do |body|
164
+ out << body
165
+ out.close
166
+ end
167
+ rescue Exception => e
168
+ puts "Exception rescue: #{e.full_message(order: :top)}"
169
+ out << {
170
+ "code": -1,
171
+ "msg": "Doraemon: #{e.to_s}"
172
+ }.to_json
173
+ out.close
174
+ end
175
+ end
176
+ end
177
+
153
178
  end
154
-
179
+
155
180
  end
@@ -49,12 +49,13 @@ module Doraemon
49
49
  port = next_port.first['next_port'].to_i
50
50
  reg_tm = (Time.now.to_f * 1000).to_i
51
51
  execute("INSERT INTO users (username, port, reg_tm) VALUES ('#{username}', #{port}, #{reg_tm})")
52
+ uid = @conn.last_insert_row_id
52
53
  execute("UPDATE configure SET next_port = #{port+1} WHERE id = 1")
53
54
  @mutex.unlock
54
- yield(true) if block_given?
55
+ yield(true, uid) if block_given?
55
56
  else
56
57
  @mutex.unlock
57
- yield(false) if block_given?
58
+ yield(false, -1) if block_given?
58
59
  end
59
60
  end
60
61
 
@@ -93,9 +94,9 @@ module Doraemon
93
94
  puts __method__.to_s
94
95
  @mutex.lock
95
96
  execute("INSERT INTO scenes (name, uid) VALUES ('#{name}', #{uid})")
96
- result = execute("SELECT seq FROM sqlite_sequence WHERE name = 'users'")
97
+ result = execute("SELECT seq FROM sqlite_sequence WHERE name = 'scenes'")
97
98
  id = result.first['seq']
98
- scene = {id: id, name: name, isActived: false}
99
+ scene = {id: id, name: name, isActived: false, apiCount: 0}
99
100
  @mutex.unlock
100
101
  yield(scene) if block_given?
101
102
  end
@@ -132,7 +133,7 @@ module Doraemon
132
133
  end
133
134
  end
134
135
 
135
- # 获取所有 api
136
+ # 获取对应场景下的所有 api
136
137
  def query_apis(scene_id)
137
138
  puts __method__.to_s
138
139
  @mutex.lock
@@ -1,3 +1,3 @@
1
1
  module Doraemon
2
- VERSION = "1.0.14"
2
+ VERSION = "1.0.17"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doraemon
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.14
4
+ version: 1.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - zhuoyi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-09 00:00:00.000000000 Z
11
+ date: 2023-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.7.2
103
+ version: 1.8.0
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.7.2
110
+ version: 1.8.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: sqlite3
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: 1.4.2
125
+ - !ruby/object:Gem::Dependency
126
+ name: activesupport
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 6.1.4
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 6.1.4
125
139
  description: a simple API mock server.
126
140
  email:
127
141
  - jiangzhuoyi@gmail.com
@@ -134,6 +148,7 @@ files:
134
148
  - exe/doraemon
135
149
  - lib/doraemon.rb
136
150
  - lib/doraemon/api/apis.rb
151
+ - lib/doraemon/api/base.rb
137
152
  - lib/doraemon/api/login.rb
138
153
  - lib/doraemon/api/scenes.rb
139
154
  - lib/doraemon/context.rb
@@ -2939,6 +2954,7 @@ files:
2939
2954
  - lib/doraemon/dashboard/vendors/twitter-bootstrap/4.5.0/js/bootstrap.min.js
2940
2955
  - lib/doraemon/dashboard/vendors/twitter-bootstrap/4.5.0/js/bootstrap.min.js.map
2941
2956
  - lib/doraemon/database.rb
2957
+ - lib/doraemon/dora_env.rb
2942
2958
  - lib/doraemon/gateway_server.rb
2943
2959
  - lib/doraemon/http_server.rb
2944
2960
  - lib/doraemon/network.rb
@@ -2974,7 +2990,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2974
2990
  - !ruby/object:Gem::Version
2975
2991
  version: '0'
2976
2992
  requirements: []
2977
- rubygems_version: 3.0.3
2993
+ rubygems_version: 3.0.3.1
2978
2994
  signing_key:
2979
2995
  specification_version: 4
2980
2996
  summary: a simple API mock server