lecter 0.1.3 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.all-contributorsrc +26 -0
- data/.circleci/config.yml +86 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +25 -0
- data/CHANGELOG.md +20 -0
- data/CONTRIBUTING.md +35 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +37 -69
- data/LICENSE.txt +1 -1
- data/README.md +160 -35
- data/Rakefile +5 -3
- data/app/controllers/lecter/diagnosis_controller.rb +40 -54
- data/app/views/layouts/lecter.html.erb +258 -0
- data/app/views/lecter/diagnosis/new.html.erb +61 -0
- data/app/views/lecter/diagnosis/show.html.erb +54 -0
- data/bin/console +1 -0
- data/bin/rails +16 -0
- data/config/locales/en.yml +16 -0
- data/config/locales/ru.yml +16 -0
- data/config/routes.rb +7 -0
- data/lecter.gemspec +9 -5
- data/lib/lecter/engine.rb +7 -0
- data/lib/lecter/formatter_headers.rb +26 -0
- data/lib/lecter/formatter_payload.rb +35 -0
- data/lib/lecter/html_generator.rb +66 -0
- data/lib/lecter/html_row.rb +42 -0
- data/lib/lecter/rack.rb +32 -31
- data/lib/lecter/railtie.rb +9 -0
- data/lib/lecter/requester.rb +63 -0
- data/lib/lecter/trace_point.rb +30 -0
- data/lib/lecter/version.rb +3 -1
- data/lib/lecter.rb +15 -12
- metadata +50 -23
- data/.idea/encodings.xml +0 -6
- data/.idea/lecter.iml +0 -52
- data/.idea/misc.xml +0 -7
- data/.idea/modules.xml +0 -8
- data/.idea/workspace.xml +0 -857
- data/.travis.yml +0 -7
- data/app/assets/javascripts/highlight.pack.js +0 -2
- data/app/assets/stylesheets/railscasts.css +0 -106
- data/app/views/lecter/diagnosis/new.erb +0 -18
- data/app/views/lecter/diagnosis/show.slim +0 -56
@@ -1,70 +1,56 @@
|
|
1
|
-
|
2
|
-
require 'slim-rails'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
module Lecter
|
4
|
+
class DiagnosisController < ActionController::Base
|
5
|
+
layout 'lecter'
|
6
|
+
before_action :format_request_data, only: :create
|
6
7
|
|
7
|
-
|
8
|
-
end
|
8
|
+
def new; end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def show
|
11
|
+
redirect_to new_diagnosis_path
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
def create
|
15
|
+
requester = Lecter::Requester.new(requester_params)
|
16
|
+
if requester.call
|
17
|
+
@file_listings = HtmlGenerator.new(requester.lines).call
|
18
|
+
render :show
|
19
|
+
else
|
20
|
+
flash[:error] = requester.error_message
|
21
|
+
render :new
|
20
22
|
end
|
23
|
+
end
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
prepare_data(response.body)
|
25
|
-
render :show
|
26
|
-
rescue URI::InvalidURIError
|
27
|
-
flash[:error] = 'Wrong url'
|
28
|
-
return render :new
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
25
|
+
private
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
def diagnosis_params
|
28
|
+
params.permit(:endpoint, :body_raw, :method, :headers)
|
29
|
+
end
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
else
|
45
|
-
@lines << {"#{file}" => [item.split(' ')[1].to_i]}
|
46
|
-
end
|
31
|
+
def requester_params
|
32
|
+
{
|
33
|
+
method: diagnosis_params[:method].downcase.to_sym,
|
34
|
+
url: diagnosis_params[:endpoint],
|
35
|
+
payload: formatter_payload.result,
|
36
|
+
headers: formatted_headers.result
|
37
|
+
}
|
47
38
|
end
|
48
|
-
end
|
49
39
|
|
50
|
-
|
51
|
-
|
52
|
-
return
|
40
|
+
def format_request_data
|
41
|
+
formatters = [formatter_payload, formatted_headers]
|
42
|
+
return if formatters.all?(&:call)
|
53
43
|
|
54
|
-
|
55
|
-
|
56
|
-
flash[:error] = 'Wrong parameters'
|
57
|
-
return render :new
|
44
|
+
flash[:error] = formatters.map(&:error_message).join(', ')
|
45
|
+
render :new
|
58
46
|
end
|
59
|
-
end
|
60
47
|
|
61
|
-
|
62
|
-
|
63
|
-
|
48
|
+
def formatter_payload
|
49
|
+
@formatter_payload ||= Lecter::FormatterPayload.new(diagnosis_params[:body_raw])
|
50
|
+
end
|
64
51
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
JSON.parse(string)
|
52
|
+
def formatted_headers
|
53
|
+
@formatted_headers ||= Lecter::FormatterHeaders.new(diagnosis_params[:headers])
|
54
|
+
end
|
69
55
|
end
|
70
56
|
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title><%= yield(:title) %></title>
|
4
|
+
<%= javascript_include_tag '//code.jquery.com/jquery-1.12.4.js', '//code.jquery.com/ui/1.12.1/jquery-ui.js' %>
|
5
|
+
<%= javascript_include_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js' %>
|
6
|
+
<%= stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css' %>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<style>
|
10
|
+
.hljs {
|
11
|
+
display: block;
|
12
|
+
overflow-x: auto;
|
13
|
+
padding: 0.5em;
|
14
|
+
background: #232323;
|
15
|
+
color: #e6e1dc;
|
16
|
+
}
|
17
|
+
|
18
|
+
.hljs-comment,
|
19
|
+
.hljs-quote {
|
20
|
+
color: #bc9458;
|
21
|
+
font-style: italic;
|
22
|
+
}
|
23
|
+
|
24
|
+
.hljs-keyword,
|
25
|
+
.hljs-selector-tag {
|
26
|
+
color: #c26230;
|
27
|
+
}
|
28
|
+
|
29
|
+
.hljs-string,
|
30
|
+
.hljs-number,
|
31
|
+
.hljs-regexp,
|
32
|
+
.hljs-variable,
|
33
|
+
.hljs-template-variable {
|
34
|
+
color: #a5c261;
|
35
|
+
}
|
36
|
+
|
37
|
+
.hljs-subst {
|
38
|
+
color: #519f50;
|
39
|
+
}
|
40
|
+
|
41
|
+
.hljs-tag,
|
42
|
+
.hljs-name {
|
43
|
+
color: #e8bf6a;
|
44
|
+
}
|
45
|
+
|
46
|
+
.hljs-type {
|
47
|
+
color: #da4939;
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
.hljs-symbol,
|
52
|
+
.hljs-bullet,
|
53
|
+
.hljs-built_in,
|
54
|
+
.hljs-builtin-name,
|
55
|
+
.hljs-attr,
|
56
|
+
.hljs-link {
|
57
|
+
color: #6d9cbe;
|
58
|
+
}
|
59
|
+
|
60
|
+
.hljs-params {
|
61
|
+
color: #d0d0ff;
|
62
|
+
}
|
63
|
+
|
64
|
+
.hljs-attribute {
|
65
|
+
color: #cda869;
|
66
|
+
}
|
67
|
+
|
68
|
+
.hljs-meta {
|
69
|
+
color: #9b859d;
|
70
|
+
}
|
71
|
+
|
72
|
+
.hljs-title,
|
73
|
+
.hljs-section {
|
74
|
+
color: #ffc66d;
|
75
|
+
}
|
76
|
+
|
77
|
+
.hljs-addition {
|
78
|
+
background-color: #144212;
|
79
|
+
color: #e6e1dc;
|
80
|
+
display: inline-block;
|
81
|
+
width: 100%;
|
82
|
+
}
|
83
|
+
|
84
|
+
.hljs-deletion {
|
85
|
+
background-color: #600;
|
86
|
+
color: #e6e1dc;
|
87
|
+
display: inline-block;
|
88
|
+
width: 100%;
|
89
|
+
}
|
90
|
+
|
91
|
+
.hljs-selector-class {
|
92
|
+
color: #9b703f;
|
93
|
+
}
|
94
|
+
|
95
|
+
.hljs-selector-id {
|
96
|
+
color: #8b98ab;
|
97
|
+
}
|
98
|
+
|
99
|
+
.hljs-emphasis {
|
100
|
+
font-style: italic;
|
101
|
+
}
|
102
|
+
|
103
|
+
.hljs-strong {
|
104
|
+
font-weight: bold;
|
105
|
+
}
|
106
|
+
|
107
|
+
.hljs-link {
|
108
|
+
text-decoration: underline;
|
109
|
+
}
|
110
|
+
|
111
|
+
/* diagnosis/show.slim */
|
112
|
+
|
113
|
+
|
114
|
+
.down {
|
115
|
+
border-left: 5px solid transparent;
|
116
|
+
border-right: 5px solid transparent;
|
117
|
+
border-top: 5px solid black;
|
118
|
+
margin: 10px 7px 0 5px;
|
119
|
+
}
|
120
|
+
|
121
|
+
.ui-accordion .ui-accordion-header {
|
122
|
+
font-size: 78%;
|
123
|
+
}
|
124
|
+
|
125
|
+
.sidebar {
|
126
|
+
float: left;
|
127
|
+
}
|
128
|
+
|
129
|
+
.sidebar > .sidebar-wrapper {
|
130
|
+
width: 235px;
|
131
|
+
position: fixed;
|
132
|
+
margin: 49px 33px 0 0;
|
133
|
+
overflow-y: scroll;
|
134
|
+
top: 82px;
|
135
|
+
bottom: 40px;
|
136
|
+
}
|
137
|
+
|
138
|
+
.sidebar-wrapper > ul {
|
139
|
+
list-style-type: none;
|
140
|
+
height: calc(100% - 40px);
|
141
|
+
}
|
142
|
+
|
143
|
+
.sidebar-wrapper > ul > li {
|
144
|
+
margin-bottom: 3px;
|
145
|
+
}
|
146
|
+
|
147
|
+
.sidebar-wrapper > ul > li > a {
|
148
|
+
text-decoration: none;
|
149
|
+
color: inherit;
|
150
|
+
display: block;
|
151
|
+
font-size: 13px;
|
152
|
+
text-inline: 1.5;
|
153
|
+
}
|
154
|
+
|
155
|
+
.sidebar-wrapper > ul > li > a:hover {
|
156
|
+
color: #7d7d7d;
|
157
|
+
}
|
158
|
+
|
159
|
+
.right {
|
160
|
+
float: left;
|
161
|
+
padding-left: 10px;
|
162
|
+
width: 70%;
|
163
|
+
margin-left: 295px;
|
164
|
+
}
|
165
|
+
|
166
|
+
.listing {
|
167
|
+
display: none;
|
168
|
+
padding: 1em 2.2em;
|
169
|
+
overflow: auto;
|
170
|
+
border-bottom-right-radius: 4px;
|
171
|
+
border: 0.5px solid;
|
172
|
+
border-top-width: 0;
|
173
|
+
border-bottom-left-radius: 4px;
|
174
|
+
background: #efefef;
|
175
|
+
}
|
176
|
+
|
177
|
+
.filename {
|
178
|
+
cursor: pointer;
|
179
|
+
position: relative;
|
180
|
+
margin: 2px 0 0 0;
|
181
|
+
padding: .5em .5em .5em .7em;
|
182
|
+
border: solid 0.1px;
|
183
|
+
background: #efefef;
|
184
|
+
}
|
185
|
+
|
186
|
+
/* layouts/lecter.slim */
|
187
|
+
|
188
|
+
body {
|
189
|
+
font-family: "Helvetica Neue", "Helvetica", Arial, "Open Sans", sans-serif;
|
190
|
+
font-size: 15px;
|
191
|
+
line-height: 1.6;
|
192
|
+
-webkit-font-smoothing: antialiased;
|
193
|
+
}
|
194
|
+
|
195
|
+
.body-wrapper {
|
196
|
+
overflow: hidden;
|
197
|
+
*zoom: 1;
|
198
|
+
margin-top: 50px;
|
199
|
+
margin-bottom: 50px;
|
200
|
+
display: block;
|
201
|
+
padding: 0 20px;
|
202
|
+
}
|
203
|
+
|
204
|
+
.nav {
|
205
|
+
font-weight: 500;
|
206
|
+
background: #0b4e22;
|
207
|
+
border-bottom: 1px solid #cccccc;
|
208
|
+
}
|
209
|
+
|
210
|
+
.nav-inner {
|
211
|
+
display: block;
|
212
|
+
max-width: 955px;
|
213
|
+
padding: 1px 20px;
|
214
|
+
}
|
215
|
+
|
216
|
+
.nav-inner > ul {
|
217
|
+
list-style-type: none;
|
218
|
+
}
|
219
|
+
|
220
|
+
.nav-inner > ul > li > a {
|
221
|
+
text-decoration: none;
|
222
|
+
font-weight: 600;
|
223
|
+
color: white;
|
224
|
+
letter-spacing: 0.4px;
|
225
|
+
}
|
226
|
+
|
227
|
+
.ul {
|
228
|
+
-webkit-justify-content: space-between;
|
229
|
+
justify-content: space-between;
|
230
|
+
list-style-type: none;
|
231
|
+
margin: 0;
|
232
|
+
padding: 8px 2px 8px;
|
233
|
+
display: -webkit-flex;
|
234
|
+
display: flex;
|
235
|
+
}
|
236
|
+
|
237
|
+
.li {
|
238
|
+
-webkit-flex: 0 1 auto;
|
239
|
+
flex: 0 1 auto;
|
240
|
+
display: list-item;
|
241
|
+
text-align: -webkit-match-parent;
|
242
|
+
list-style-type: none;
|
243
|
+
}
|
244
|
+
|
245
|
+
.nav-inner > li > a {
|
246
|
+
text-decoration: none;
|
247
|
+
font-weight: 400;
|
248
|
+
color: white;
|
249
|
+
letter-spacing: 0.4px;
|
250
|
+
}
|
251
|
+
</style>
|
252
|
+
|
253
|
+
<body>
|
254
|
+
<div class="container">
|
255
|
+
<%= yield %>
|
256
|
+
</div>
|
257
|
+
</body>
|
258
|
+
</html>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
<%= content_for :title, t('.title') %>
|
2
|
+
|
3
|
+
<div class="container">
|
4
|
+
<h2><%= t('.title') %></h2>
|
5
|
+
|
6
|
+
<%= form_tag diagnosis_path do %>
|
7
|
+
<% flash.each do |key, value| %>
|
8
|
+
<div class="col-sm-2 col-form-label">
|
9
|
+
<%= value %>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
<div class="row my-3">
|
13
|
+
<%= label_tag t('.method'), nil, class: 'col-sm-2 col-form-label' %>
|
14
|
+
<div class="col-sm">
|
15
|
+
<%= select_tag :method, options_for_select(Lecter::AVAILABLE_METHODS, Lecter::DEFAULT_METHOD) %>
|
16
|
+
</div>
|
17
|
+
<div class="col-sm gray">
|
18
|
+
Choose one
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div class="row my-3">
|
22
|
+
<%= label_tag t('.endpoint'), nil, class: 'col-sm-2 col-form-label' %>
|
23
|
+
<div class="col-sm">
|
24
|
+
<%= text_field_tag :endpoint, nil, class: 'form-control', placeholder: 'Endpoint' %>
|
25
|
+
</div>
|
26
|
+
<div class="col-sm gray">
|
27
|
+
localhost:3000/posts
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<div class="row my-3">
|
31
|
+
<%= label_tag t('.headers'), nil, class: 'col-sm-2 col-form-label' %>
|
32
|
+
<div class="col-sm">
|
33
|
+
<%= text_field_tag :headers, nil, class: 'form-control', placeholder: 'Headers' %>
|
34
|
+
</div>
|
35
|
+
<div class="col-sm gray">
|
36
|
+
content_type=text/html,accept=*/*
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
<div class="row my-3">
|
40
|
+
<%= label_tag t('.body_raw'), nil, class: 'col-sm-2 col-form-label' %>
|
41
|
+
<div class="col-sm">
|
42
|
+
<%= text_area_tag :body_raw, nil, rows: 10, class: 'form-control', placeholder: 'Body(raw)' %>
|
43
|
+
</div>
|
44
|
+
<div class="col-sm gray">
|
45
|
+
"post" => {
|
46
|
+
"title" => "New title",
|
47
|
+
"description" => "Desciption"
|
48
|
+
}
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
</p>
|
53
|
+
<%= submit_tag t('.send'), class: 'btn btn-primary' %>
|
54
|
+
<% end %>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<style>
|
58
|
+
.gray {
|
59
|
+
color: #727a82
|
60
|
+
}
|
61
|
+
</style>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<%= content_for :title, t('.title') %>
|
2
|
+
|
3
|
+
<div class="container">
|
4
|
+
<h2><%= t('.executed_code') %></h2>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<div class="row py-3">
|
8
|
+
<div class="col-3 order-2" style="width: 280px;">
|
9
|
+
<div class="sticky-top">
|
10
|
+
<ul>
|
11
|
+
<% @file_listings.each_with_index do |file_listing, index| %>
|
12
|
+
<li>
|
13
|
+
<a href="#anchor<%= index %>" class="nav-link link-dark">
|
14
|
+
<%= raw(file_listing.file_path.split('/').last) %>
|
15
|
+
</a>
|
16
|
+
</li>
|
17
|
+
<% end %>
|
18
|
+
</ul>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="col">
|
23
|
+
<div class="accordion" id="accordionExample">
|
24
|
+
<% @file_listings.each_with_index do |file_listing, index| %>
|
25
|
+
<div class="accordion-item">
|
26
|
+
<h2 class="accordion-header" id="headingOne">
|
27
|
+
<button class="accordion-button" type="button" data-bs-toggle="collapse"
|
28
|
+
data-bs-target="#collapse<%=index%>" aria-expanded="true" aria-controls="collapse<%=index%>"
|
29
|
+
id="anchor<%=index%>"
|
30
|
+
>
|
31
|
+
<%= file_listing.file_path.split('/').last %>
|
32
|
+
</button>
|
33
|
+
</h2>
|
34
|
+
<div id="collapse<%=index%>" class="accordion-collapse collapse show" aria-labelledby="heading<%=index%>>" data-bs-parent="#accordionExample">
|
35
|
+
<div class="accordion-body">
|
36
|
+
<pre>
|
37
|
+
<code><% file_listing.html_rows.each do |html_row| %><%= raw(html_row) %><% end %></code>
|
38
|
+
</pre>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<script>
|
48
|
+
/*! highlight.js v9.15.8 | BSD3 License | git.io/hljslicense */
|
49
|
+
!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(a){var f=[],u=Object.keys,N={},c={},n=/^(no-?highlight|plain|text)$/i,s=/\blang(?:uage)?-([\w-]+)\b/i,t=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",relevance:"r",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},b="</span>",h={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function _(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function E(e){return e.nodeName.toLowerCase()}function v(e,n){var t=e&&e.exec(n);return t&&0===t.index}function l(e){return n.test(e)}function g(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function R(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:"start",offset:t,node:r}),t=e(r,t),E(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function i(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(i)}}function m(o){function s(e){return e&&e.source||e}function c(e,n){return new RegExp(s(e),"m"+(o.cI?"i":"")+(n?"g":""))}!function n(t,e){if(!t.compiled){if(t.compiled=!0,t.k=t.k||t.bK,t.k){function r(t,e){o.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n=e.split("|");a[n[0]]=[t,n[1]?Number(n[1]):1]})}var a={};"string"==typeof t.k?r("keyword",t.k):u(t.k).forEach(function(e){r(e,t.k[e])}),t.k=a}t.lR=c(t.l||/\w+/,!0),e&&(t.bK&&(t.b="\\b("+t.bK.split(" ").join("|")+")\\b"),t.b||(t.b=/\B|\b/),t.bR=c(t.b),t.endSameAsBegin&&(t.e=t.b),t.e||t.eW||(t.e=/\B|\b/),t.e&&(t.eR=c(t.e)),t.tE=s(t.e)||"",t.eW&&e.tE&&(t.tE+=(t.e?"|":"")+e.tE)),t.i&&(t.iR=c(t.i)),null==t.r&&(t.r=1),t.c||(t.c=[]),t.c=Array.prototype.concat.apply([],t.c.map(function(e){return function(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return g(n,{v:null},e)})),n.cached_variants||n.eW&&[g(n)]||[n]}("self"===e?t:e)})),t.c.forEach(function(e){n(e,t)}),t.starts&&n(t.starts,e);var i=t.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([t.tE,t.i]).map(s).filter(Boolean);t.t=i.length?c(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i<e.length;i++){var o=r,c=s(e[i]);for(0<i&&(a+=n);0<c.length;){var u=t.exec(c);if(null==u){a+=c;break}a+=c.substring(0,u.index),c=c.substring(u.index+u[0].length),"\\"==u[0][0]&&u[1]?a+="\\"+String(Number(u[1])+o):(a+=u[0],"("==u[0]&&r++)}}return a}(i,"|"),!0):{exec:function(){return null}}}}(o)}function C(e,n,i,t){function c(e,n,t,r){var a='<span class="'+(r?"":h.classPrefix);return e?(a+=e+'">')+n+(t?"":b):n}function o(){E+=null!=l.sL?function(){var e="string"==typeof l.sL;if(e&&!N[l.sL])return _(g);var n=e?C(l.sL,g,!0,f[l.sL]):O(g,l.sL.length?l.sL:void 0);return 0<l.r&&(R+=n.r),e&&(f[l.sL]=n.top),c(n.language,n.value,!1,!0)}():function(){var e,n,t,r,a,i,o;if(!l.k)return _(g);for(r="",n=0,l.lR.lastIndex=0,t=l.lR.exec(g);t;)r+=_(g.substring(n,t.index)),a=l,i=t,void 0,o=s.cI?i[0].toLowerCase():i[0],(e=a.k.hasOwnProperty(o)&&a.k[o])?(R+=e[1],r+=c(e[0],_(t[0]))):r+=_(t[0]),n=l.lR.lastIndex,t=l.lR.exec(g);return r+_(g.substr(n))}(),g=""}function u(e){E+=e.cN?c(e.cN,"",!0):"",l=Object.create(e,{parent:{value:l}})}function r(e,n){if(g+=e,null==n)return o(),0;var t=function(e,n){var t,r,a;for(t=0,r=n.c.length;t<r;t++)if(v(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=(a=n.c[t].bR.exec(e)[0],new RegExp(a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m"))),n.c[t]}(n,l);if(t)return t.skip?g+=n:(t.eB&&(g+=n),o(),t.rB||t.eB||(g=n)),u(t),t.rB?0:n.length;var r=function e(n,t){if(v(n.eR,t)){for(;n.endsParent&&n.parent;)n=n.parent;return n}if(n.eW)return e(n.parent,t)}(l,n);if(r){var a=l;for(a.skip?g+=n:(a.rE||a.eE||(g+=n),o(),a.eE&&(g=n));l.cN&&(E+=b),l.skip||l.sL||(R+=l.r),(l=l.parent)!==r.parent;);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),u(r.starts)),a.rE?0:n.length}if(function(e,n){return!i&&v(n.iR,e)}(n,l))throw new Error('Illegal lexeme "'+n+'" for mode "'+(l.cN||"<unnamed>")+'"');return g+=n,n.length||1}var s=B(e);if(!s)throw new Error('Unknown language: "'+e+'"');m(s);var a,l=t||s,f={},E="";for(a=l;a!==s;a=a.parent)a.cN&&(E=c(a.cN,"",!0)+E);var g="",R=0;try{for(var d,p,M=0;l.t.lastIndex=M,d=l.t.exec(n);)p=r(n.substring(M,d.index),d[0]),M=d.index+p;for(r(n.substr(M)),a=l;a.parent;a=a.parent)a.cN&&(E+=b);return{r:R,value:E,language:e,top:l}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:_(n)};throw e}}function O(t,e){e=e||h.languages||u(N);var r={r:0,value:_(t)},a=r;return e.filter(B).filter(M).forEach(function(e){var n=C(e,t,!1);n.language=e,n.r>a.r&&(a=n),n.r>r.r&&(a=r,r=n)}),a.language&&(r.second_best=a),r}function d(e){return h.tabReplace||h.useBR?e.replace(t,function(e,n){return h.useBR&&"\n"===e?"<br>":h.tabReplace?n.replace(/\t/g,h.tabReplace):""}):e}function o(e){var n,t,r,a,i,o=function(e){var n,t,r,a,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=s.exec(i))return B(t[1])?t[1]:"no-highlight";for(n=0,r=(i=i.split(/\s+/)).length;n<r;n++)if(l(a=i[n])||B(a))return a}(e);l(o)||(h.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n"):n=e,i=n.textContent,r=o?C(o,i,!0):O(i),(t=R(n)).length&&((a=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=r.value,r.value=function(e,n,t){var r=0,a="",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:"start"===n[0].event?e:n:e.length?e:n}function c(e){a+="<"+E(e)+f.map.call(e.attributes,function(e){return" "+e.nodeName+'="'+_(e.value).replace('"',""")+'"'}).join("")+">"}function u(e){a+="</"+E(e)+">"}function s(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var l=o();if(a+=_(t.substring(r,l[0].offset)),r=l[0].offset,l===e){for(i.reverse().forEach(u);s(l.splice(0,1)[0]),(l=o())===e&&l.length&&l[0].offset===r;);i.reverse().forEach(c)}else"start"===l[0].event?i.push(l[0].node):i.pop(),s(l.splice(0,1)[0])}return a+_(t.substr(r))}(t,R(a),i)),r.value=d(r.value),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?c[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function p(){if(!p.called){p.called=!0;var e=document.querySelectorAll("pre code");f.forEach.call(e,o)}}function B(e){return e=(e||"").toLowerCase(),N[e]||N[c[e]]}function M(e){var n=B(e);return n&&!n.disableAutodetect}return a.highlight=C,a.highlightAuto=O,a.fixMarkup=d,a.highlightBlock=o,a.configure=function(e){h=g(h,e)},a.initHighlighting=p,a.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",p,!1),addEventListener("load",p,!1)},a.registerLanguage=function(n,e){var t=N[n]=e(a);i(t),t.aliases&&t.aliases.forEach(function(e){c[e]=n})},a.listLanguages=function(){return u(N)},a.getLanguage=B,a.autoDetection=M,a.inherit=g,a.IR=a.IDENT_RE="[a-zA-Z]\\w*",a.UIR=a.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",a.NR=a.NUMBER_RE="\\b\\d+(\\.\\d+)?",a.CNR=a.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",a.BNR=a.BINARY_NUMBER_RE="\\b(0b[01]+)",a.RSR=a.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",a.BE=a.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",r:0},a.ASM=a.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[a.BE]},a.QSM=a.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[a.BE]},a.PWM=a.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},a.C=a.COMMENT=function(e,n,t){var r=a.inherit({cN:"comment",b:e,e:n,c:[]},t||{});return r.c.push(a.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),r},a.CLCM=a.C_LINE_COMMENT_MODE=a.C("//","$"),a.CBCM=a.C_BLOCK_COMMENT_MODE=a.C("/\\*","\\*/"),a.HCM=a.HASH_COMMENT_MODE=a.C("#","$"),a.NM=a.NUMBER_MODE={cN:"number",b:a.NR,r:0},a.CNM=a.C_NUMBER_MODE={cN:"number",b:a.CNR,r:0},a.BNM=a.BINARY_NUMBER_MODE={cN:"number",b:a.BNR,r:0},a.CSSNM=a.CSS_NUMBER_MODE={cN:"number",b:a.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},a.RM=a.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[a.BE,{b:/\[/,e:/\]/,r:0,c:[a.BE]}]},a.TM=a.TITLE_MODE={cN:"title",b:a.IR,r:0},a.UTM=a.UNDERSCORE_TITLE_MODE={cN:"title",b:a.UIR,r:0},a.METHOD_GUARD={b:"\\.\\s*"+a.UIR,r:0},a});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d;var l=[{b:/^\s*=>/,starts:{e:"$",c:i.c=d}},{cN:"meta",b:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(l).concat(d)}});
|
50
|
+
|
51
|
+
$(document).ready(function(){
|
52
|
+
hljs.initHighlighting();
|
53
|
+
})
|
54
|
+
</script>
|
data/bin/console
CHANGED
data/bin/rails
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
5
|
+
# installed from the root of your application.
|
6
|
+
|
7
|
+
ENGINE_ROOT = File.expand_path('..', __dir__)
|
8
|
+
ENGINE_PATH = File.expand_path('../lib/lecter/engine', __dir__)
|
9
|
+
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
|
10
|
+
|
11
|
+
# Set up gems listed in the Gemfile.
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
13
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
14
|
+
|
15
|
+
require 'rails/all'
|
16
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
en:
|
2
|
+
layouts:
|
3
|
+
lecter:
|
4
|
+
new_diagnosis: 'New diagnosis'
|
5
|
+
lecter:
|
6
|
+
diagnosis:
|
7
|
+
show:
|
8
|
+
title: 'Diagnosis results'
|
9
|
+
executed_code: 'Executed code:'
|
10
|
+
new:
|
11
|
+
title: 'New diagnosis'
|
12
|
+
endpoint: 'Endpoint'
|
13
|
+
body_raw: 'Body (raw)'
|
14
|
+
method: 'HTTP method'
|
15
|
+
send: 'Send request'
|
16
|
+
headers: 'Headers'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
ru:
|
2
|
+
layouts:
|
3
|
+
lecter:
|
4
|
+
new_diagnosis: 'Новый диагноз'
|
5
|
+
lecter:
|
6
|
+
diagnosis:
|
7
|
+
show:
|
8
|
+
title: 'Диагноз'
|
9
|
+
executed_code: 'Используемый код:'
|
10
|
+
new:
|
11
|
+
title: 'Новый диагноз'
|
12
|
+
endpoint: 'Абсолютный путь'
|
13
|
+
body_raw: 'Тело запроса'
|
14
|
+
method: 'HTTP метод'
|
15
|
+
send: 'Послать запрос'
|
16
|
+
headers: 'Заголовки'
|
data/config/routes.rb
ADDED
data/lecter.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path('lib', __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
require 'lecter/version'
|
@@ -8,8 +10,9 @@ Gem::Specification.new do |spec|
|
|
8
10
|
spec.authors = ['Neodelf']
|
9
11
|
spec.email = ['neodelf@gmail.com']
|
10
12
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
+
spec.summary = 'Show executable code by request.'
|
14
|
+
spec.description = 'The main purpose of that gem is helping developers to understand which '\
|
15
|
+
'code executes by request.<br>'
|
13
16
|
spec.homepage = 'https://github.com/neodelf/lecter'
|
14
17
|
spec.license = 'MIT'
|
15
18
|
|
@@ -21,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
21
24
|
|
22
25
|
# Specify which files should be added to the gem when it is released.
|
23
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
-
spec.files
|
27
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
28
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
29
|
end
|
27
30
|
spec.bindir = 'exe'
|
@@ -29,9 +32,10 @@ Gem::Specification.new do |spec|
|
|
29
32
|
spec.require_paths = ['lib']
|
30
33
|
|
31
34
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
32
|
-
spec.add_development_dependency 'rake', '~>
|
35
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
33
36
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
37
|
+
spec.add_development_dependency 'rubocop'
|
34
38
|
|
35
|
-
spec.add_runtime_dependency 'slim-rails'
|
36
39
|
spec.add_runtime_dependency 'rest-client'
|
40
|
+
spec.add_runtime_dependency 'simplecov', '0.17.1'
|
37
41
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lecter
|
4
|
+
class FormatterHeaders
|
5
|
+
WRONG_HEADERS_MSG = 'Wrong headers'
|
6
|
+
attr_reader :result, :error_message
|
7
|
+
|
8
|
+
def initialize(headers)
|
9
|
+
@dirty_headers = headers
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
@result = dirty_headers
|
14
|
+
.split(',')
|
15
|
+
.map { |header_with_value| header_with_value.split('=') }
|
16
|
+
.to_h
|
17
|
+
rescue StandardError
|
18
|
+
@error_message = WRONG_HEADERS_MSG
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_accessor :dirty_headers
|
25
|
+
end
|
26
|
+
end
|