rage-iodine 1.7.58

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 (128) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  3. data/.github/workflows/ruby.yml +42 -0
  4. data/.gitignore +20 -0
  5. data/.rspec +2 -0
  6. data/.yardopts +8 -0
  7. data/CHANGELOG.md +1098 -0
  8. data/Gemfile +11 -0
  9. data/LICENSE.txt +21 -0
  10. data/LIMITS.md +41 -0
  11. data/README.md +782 -0
  12. data/Rakefile +23 -0
  13. data/SPEC-PubSub-Draft.md +159 -0
  14. data/SPEC-WebSocket-Draft.md +239 -0
  15. data/bin/console +22 -0
  16. data/bin/info.md +353 -0
  17. data/bin/mustache_bench.rb +100 -0
  18. data/bin/poc/Gemfile.lock +23 -0
  19. data/bin/poc/README.md +37 -0
  20. data/bin/poc/config.ru +66 -0
  21. data/bin/poc/gemfile +1 -0
  22. data/bin/poc/www/index.html +57 -0
  23. data/examples/async_task.ru +92 -0
  24. data/examples/bates/README.md +3 -0
  25. data/examples/bates/config.ru +342 -0
  26. data/examples/bates/david+bold.pdf +0 -0
  27. data/examples/bates/public/drop-pdf.png +0 -0
  28. data/examples/bates/public/index.html +600 -0
  29. data/examples/config.ru +59 -0
  30. data/examples/echo.ru +59 -0
  31. data/examples/etag.ru +16 -0
  32. data/examples/hello.ru +29 -0
  33. data/examples/pubsub_engine.ru +81 -0
  34. data/examples/rack3.ru +12 -0
  35. data/examples/redis.ru +70 -0
  36. data/examples/shootout.ru +73 -0
  37. data/examples/sub-protocols.ru +90 -0
  38. data/examples/tcp_client.rb +66 -0
  39. data/examples/x-sendfile.ru +14 -0
  40. data/exe/iodine +280 -0
  41. data/ext/iodine/extconf.rb +110 -0
  42. data/ext/iodine/fio.c +12096 -0
  43. data/ext/iodine/fio.h +6390 -0
  44. data/ext/iodine/fio_cli.c +431 -0
  45. data/ext/iodine/fio_cli.h +189 -0
  46. data/ext/iodine/fio_json_parser.h +687 -0
  47. data/ext/iodine/fio_siphash.c +157 -0
  48. data/ext/iodine/fio_siphash.h +37 -0
  49. data/ext/iodine/fio_tls.h +129 -0
  50. data/ext/iodine/fio_tls_missing.c +649 -0
  51. data/ext/iodine/fio_tls_openssl.c +1056 -0
  52. data/ext/iodine/fio_tmpfile.h +50 -0
  53. data/ext/iodine/fiobj.h +44 -0
  54. data/ext/iodine/fiobj4fio.h +21 -0
  55. data/ext/iodine/fiobj_ary.c +333 -0
  56. data/ext/iodine/fiobj_ary.h +139 -0
  57. data/ext/iodine/fiobj_data.c +1185 -0
  58. data/ext/iodine/fiobj_data.h +167 -0
  59. data/ext/iodine/fiobj_hash.c +409 -0
  60. data/ext/iodine/fiobj_hash.h +176 -0
  61. data/ext/iodine/fiobj_json.c +622 -0
  62. data/ext/iodine/fiobj_json.h +68 -0
  63. data/ext/iodine/fiobj_mem.h +71 -0
  64. data/ext/iodine/fiobj_mustache.c +317 -0
  65. data/ext/iodine/fiobj_mustache.h +62 -0
  66. data/ext/iodine/fiobj_numbers.c +344 -0
  67. data/ext/iodine/fiobj_numbers.h +127 -0
  68. data/ext/iodine/fiobj_str.c +433 -0
  69. data/ext/iodine/fiobj_str.h +172 -0
  70. data/ext/iodine/fiobject.c +620 -0
  71. data/ext/iodine/fiobject.h +654 -0
  72. data/ext/iodine/hpack.h +1923 -0
  73. data/ext/iodine/http.c +2736 -0
  74. data/ext/iodine/http.h +1019 -0
  75. data/ext/iodine/http1.c +825 -0
  76. data/ext/iodine/http1.h +29 -0
  77. data/ext/iodine/http1_parser.h +1835 -0
  78. data/ext/iodine/http_internal.c +1279 -0
  79. data/ext/iodine/http_internal.h +248 -0
  80. data/ext/iodine/http_mime_parser.h +350 -0
  81. data/ext/iodine/iodine.c +1433 -0
  82. data/ext/iodine/iodine.h +64 -0
  83. data/ext/iodine/iodine_caller.c +218 -0
  84. data/ext/iodine/iodine_caller.h +27 -0
  85. data/ext/iodine/iodine_connection.c +941 -0
  86. data/ext/iodine/iodine_connection.h +55 -0
  87. data/ext/iodine/iodine_defer.c +420 -0
  88. data/ext/iodine/iodine_defer.h +6 -0
  89. data/ext/iodine/iodine_fiobj2rb.h +120 -0
  90. data/ext/iodine/iodine_helpers.c +282 -0
  91. data/ext/iodine/iodine_helpers.h +12 -0
  92. data/ext/iodine/iodine_http.c +1280 -0
  93. data/ext/iodine/iodine_http.h +23 -0
  94. data/ext/iodine/iodine_json.c +302 -0
  95. data/ext/iodine/iodine_json.h +6 -0
  96. data/ext/iodine/iodine_mustache.c +567 -0
  97. data/ext/iodine/iodine_mustache.h +6 -0
  98. data/ext/iodine/iodine_pubsub.c +580 -0
  99. data/ext/iodine/iodine_pubsub.h +26 -0
  100. data/ext/iodine/iodine_rack_io.c +273 -0
  101. data/ext/iodine/iodine_rack_io.h +20 -0
  102. data/ext/iodine/iodine_store.c +142 -0
  103. data/ext/iodine/iodine_store.h +20 -0
  104. data/ext/iodine/iodine_tcp.c +346 -0
  105. data/ext/iodine/iodine_tcp.h +13 -0
  106. data/ext/iodine/iodine_tls.c +261 -0
  107. data/ext/iodine/iodine_tls.h +13 -0
  108. data/ext/iodine/mustache_parser.h +1546 -0
  109. data/ext/iodine/redis_engine.c +957 -0
  110. data/ext/iodine/redis_engine.h +79 -0
  111. data/ext/iodine/resp_parser.h +317 -0
  112. data/ext/iodine/scheduler.c +173 -0
  113. data/ext/iodine/scheduler.h +6 -0
  114. data/ext/iodine/websocket_parser.h +506 -0
  115. data/ext/iodine/websockets.c +752 -0
  116. data/ext/iodine/websockets.h +185 -0
  117. data/iodine.gemspec +50 -0
  118. data/lib/iodine/connection.rb +61 -0
  119. data/lib/iodine/json.rb +42 -0
  120. data/lib/iodine/mustache.rb +113 -0
  121. data/lib/iodine/pubsub.rb +55 -0
  122. data/lib/iodine/rack_utils.rb +43 -0
  123. data/lib/iodine/tls.rb +16 -0
  124. data/lib/iodine/version.rb +3 -0
  125. data/lib/iodine.rb +274 -0
  126. data/lib/rack/handler/iodine.rb +33 -0
  127. data/logo.png +0 -0
  128. metadata +284 -0
@@ -0,0 +1,600 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en"><head>
3
+ <title>Bates Numbering for Court</title>
4
+ <meta charset='utf-8'>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, minimal-ui=yes">
6
+ <style>
7
+ html, body {
8
+ height: 100%; width: 100%;
9
+ padding: 0; margin: 0;
10
+ color: #111;
11
+ background-color: #99A3CE;
12
+ }
13
+
14
+ h2, h3 {
15
+ font-size: 1.2em;
16
+ background-color: #44518E;
17
+ color: #C6CCE7;
18
+ }
19
+ h2 a, h3 a
20
+ {
21
+ color: inherit;
22
+ text-decoration: none;
23
+ }
24
+ h2 a:hover, h3 a:hover
25
+ {
26
+ color: #00f;
27
+ }
28
+
29
+ h1 {
30
+ font-size: 1.5em;
31
+ text-align: center;
32
+ background-color: #1B2864;
33
+ color: #99A3CE;
34
+ margin:0; padding: 0.5em;
35
+ }
36
+ h2 {
37
+ border-radius: 0.5em;
38
+ text-align: center;
39
+ }
40
+ h3 {
41
+ text-align: left;
42
+ }
43
+ .hide {
44
+ display: none !important;
45
+ }
46
+ span.en {
47
+ direction: ltr;
48
+ display: inline-block;
49
+ text-align: left;
50
+ width: auto;
51
+ }
52
+ #notice
53
+ {
54
+ z-index: 99999;
55
+ position: absolute;
56
+ top: 0; left: 0;
57
+ background-color: rgba(0, 0, 0, 0.75);
58
+ box-sizing: border-box;
59
+ padding: 1em 0;
60
+ text-align: center;
61
+ height: 100px;
62
+ width: 100%;
63
+ overflow-y: auto;
64
+ color: #fff; font-weight: bold;
65
+ transition:All 0.25s ease;
66
+ -webkit-transition:All 0.25s ease;
67
+ -moz-transition:All 0.25s ease;
68
+ -o-transition:All 0.25s ease;
69
+ -ms-transition:All 0.25s ease;
70
+ transform-origin: 0 50%;
71
+ -webkit-transform-origin: 50% 0; /* Chrome, Safari, Opera */
72
+ -ms-transform-origin: 50% 0; /* IE 9 */
73
+ -moz-transform-origin: 50% 0;
74
+ -o-transform-origin: 50% 0;
75
+ transform: scale(1, 1);
76
+ -webkit-transform: scale(1, 1);
77
+ -moz-transform: scale(1, 1);
78
+ -o-transform: scale(1, 1);
79
+ -ms-transform: scale(1, 1);
80
+ }
81
+ #notice.hidden
82
+ {
83
+ transform: scale(1, 0);
84
+ -webkit-transform: scale(1, 0);
85
+ -moz-transform: scale(1, 0);
86
+ -o-transform: scale(1, 0);
87
+ -ms-transform: scale(1, 0);
88
+ }
89
+ #notice .notice_close
90
+ {
91
+ display:block;
92
+ position: absolute;
93
+ top:0; left:0;
94
+ padding:0.5em;
95
+ height:100%;
96
+ width:5em;
97
+ text-align:left;
98
+ cursor: pointer;
99
+ border-right:1px solid #eee;
100
+ color: #ccc;
101
+ }
102
+ #notice .notice_close:hover
103
+ {
104
+ color: #eee;
105
+ background-color: rgba(255, 255, 255, 0.25);
106
+ }
107
+
108
+ #content {
109
+ background-color: #fff;
110
+ color: #111;
111
+ min-height: 100%;
112
+ padding: 4em 1.5em;
113
+ margin: 0 1em;
114
+ overflow-x: hidden;
115
+ box-sizing: border-box;
116
+ }
117
+ #content h1, #content h2, #content h3 {
118
+ background-color: #1B2864;
119
+ color: #99A3CE;
120
+ padding: 0.2em 1em;
121
+ margin: 0.2em 0;
122
+ }
123
+ #content h1 {
124
+ padding: 0.5em;
125
+ margin: 0;
126
+ }
127
+ #content p {
128
+ padding: 0.5em;
129
+ margin: 0;
130
+ }
131
+ #content a {
132
+ color: #0000aa;
133
+ text-decoration: none;
134
+ }
135
+ #content a:hover {
136
+ color: blue;
137
+ text-decoration: underline;
138
+ background: white;
139
+ position: relative;
140
+ top: 1px;
141
+ left: 2px;
142
+ }
143
+ #content h1 a, #content h2 a, #content h3 a, #content table th a {
144
+ color: #aaaaff;
145
+ }
146
+ #content h1 a:hover, #content h2 a:hover, #content h3 a:hover, #content table th a:hover {
147
+ background: inherit;
148
+ color: #ddddff;
149
+ }
150
+ #content #notice {
151
+ background: #ffaadd;
152
+ color: #551111;
153
+ margin: 0.3em 15%;
154
+ padding: 1em 0.5em;
155
+ text-align: center;
156
+ border-radius: 1em;
157
+ font-weight: bold;
158
+ font-size: 1.1em;
159
+ }
160
+
161
+ .desc, form {
162
+ text-align: justify;
163
+ display: block;
164
+ margin: 0.5em 15%; padding: 0 0 0.5em 0;
165
+ background: #eeeefa;
166
+ color: #111111;
167
+ border-radius: 1em;
168
+ }
169
+ .with_border
170
+ {
171
+ border: 1px solid #aab;
172
+ }
173
+ .desc p, form p {
174
+ padding: 0.2em;
175
+ margin: 0.5em 0;
176
+ }
177
+ form input[type='submit'] {
178
+ margin: 0.5em 20%;
179
+ width: 60%;
180
+ color: #000033;
181
+ background: #eeeeff;
182
+ }
183
+ form table {
184
+ width: 100%;
185
+ table-layout: fixed;
186
+ border-collapse: collapse;
187
+ }
188
+ form table th {
189
+ background: #bbb;
190
+ color: #111111;
191
+ }
192
+ form table td {
193
+ width: 2%;
194
+ border-collapse: collapse;
195
+ border-top: #bbbbcc dotted 1px;
196
+ border-bottom: #bbbbcc dotted 1px;
197
+ padding: 1px 2px;
198
+ }
199
+ form table tr {
200
+ border-collapse: collapse;
201
+ }
202
+ form table .en {
203
+ direction: ltr;
204
+ }
205
+ form table input, form table select {
206
+ width: 100%;
207
+ margin: 0.5em 0;
208
+ padding: 0;
209
+ color: #000033;
210
+ background: #eeeeff;
211
+ }
212
+ form table .no_resize input, form table .no_resize select {
213
+ width: auto;
214
+ margin: 0.5em 0;
215
+ padding: inherit;
216
+ }
217
+ form .field {
218
+ width: 100%;
219
+ display: block;
220
+ text-align: justify;
221
+ padding: 0.5em 0;
222
+ margin: 0;
223
+ margin-bottom: 0;
224
+ vertical-align: top;
225
+ border-collapse: collapse;
226
+ border-top: #bbbbcc dotted 1px;
227
+ border-bottom: #bbbbcc dotted 1px;
228
+ }
229
+ form .field label {
230
+ width: 34%;
231
+ margin: 0 2%;
232
+ padding: 0;
233
+ display: inline-block;
234
+ vertical-align: top;
235
+ }
236
+ form .field input {
237
+ width: 60%;
238
+ margin: 0;
239
+ padding: 0;
240
+ display: inline-block;
241
+ vertical-align: top;
242
+ color: #000033;
243
+ background: #eeeeff;
244
+ }
245
+ form .field select {
246
+ width: 60%;
247
+ margin: 0;
248
+ padding: 0;
249
+ }
250
+ form .field .no_resize input, form .field .no_resize select {
251
+ width: auto;
252
+ margin: inherit;
253
+ padding: inherit;
254
+ color: #000033;
255
+ background: #eeeeff;
256
+ }
257
+ form .field textarea {
258
+ width: 98%;
259
+ padding: 0;
260
+ margin: 0;
261
+ height: 5em;
262
+ display: block;
263
+ color: #000033;
264
+ background: #eeeeff;
265
+ }
266
+ form .en input, form .en textarea {
267
+ text-align: left;
268
+ direction: ltr;
269
+ }
270
+
271
+ table.one_liners {
272
+ table-layout: fixed !important;
273
+ max-width: 100% !important;
274
+ width: 100% !important;
275
+ text-overflow: ellipsis;
276
+ overflow: none;
277
+ }
278
+ table.one_liners td, table.one_liners th {
279
+ width: inherit;
280
+ max-width: 10%;
281
+ white-space: nowrap;
282
+ text-overflow: ellipsis;
283
+ }
284
+
285
+ h1#dropzone {
286
+ font-size: 2em;
287
+ text-align: center;
288
+ background-color: #44518E;
289
+ color: #C6CCE7;
290
+ padding: 0.5em 0;
291
+ background-image: url(/drop-pdf.png);
292
+ background-repeat: no-repeat;
293
+ background-position: 10% center;
294
+ background-size: auto 100%;
295
+ border-radius: 0.5em 0.5em 0 0;
296
+ }
297
+
298
+ ul.bates_file_table_list, ol.bates_file_table_list {
299
+ display: block;
300
+ margin: 0;
301
+ padding: 0;
302
+ list-style-position: inside;
303
+ width: 100%;
304
+ }
305
+ ul.bates_file_table_list li, ol.bates_file_table_list li {
306
+ border-top: 1px dotted #111111;
307
+ border-bottom: 1px dotted #111111;
308
+ border-collapse: collapse;
309
+ }
310
+ ul.bates_file_table_list li div, ol.bates_file_table_list li div {
311
+ display: inline-block;
312
+ width: 28%;
313
+ }
314
+ ul.bates_file_table_list input, ol.bates_file_table_list input {
315
+ width: 90%;
316
+ color: #000033;
317
+ background: #eeeeff;
318
+ }
319
+ ul.bates_file_table_list {
320
+ list-style-type: circle;
321
+ }
322
+ ul.bates_file_table_list li:first-child {
323
+ background: #aab;
324
+ color: #111111;
325
+ }
326
+ input[type=checkbox]:checked#bates_first_pdf_is_cover ~ ol.bates_file_table_list li:first-child {
327
+ background: #bbc;
328
+ color: #551111;
329
+ }
330
+ input[type=checkbox]
331
+ {
332
+ width: auto;
333
+ display: inline;
334
+ }
335
+ #file_remover {
336
+ float: left;
337
+ }
338
+
339
+ /* RESPONSIVE RELATED */
340
+ @media screen and (max-width: 46em) {
341
+ /* STYLING CONTENT (none at the moment)*/
342
+ /* line 800, /Users/2Be/Ruby/combine_pdf_demo/app/assets/stylesheets/welcome.css.scss */
343
+ body, html {
344
+ height: auto;
345
+ }
346
+
347
+ /* line 803, /Users/2Be/Ruby/combine_pdf_demo/app/assets/stylesheets/welcome.css.scss */
348
+ #content {
349
+ padding: 3em 0;
350
+ margin: 0;
351
+ }
352
+ #content #notice {
353
+ margin: 0.2em 1em;
354
+ }
355
+ /* line 814, /Users/2Be/Ruby/combine_pdf_demo/app/assets/stylesheets/welcome.css.scss */
356
+ #content .hide_when_small {
357
+ display: none;
358
+ }
359
+ form, .desc {
360
+ margin: 0.3em 1em;
361
+ }
362
+ }
363
+ </style>
364
+ <script>
365
+ function show_notice() { document.getElementById("notice").classList.remove('hidden'); }
366
+ function hide_notice() { document.getElementById("notice").classList.add('hidden'); }
367
+ </script>
368
+ </head><body>
369
+ <h1>Bates Numbering - PDF file merge and number</h1>
370
+ <div id="notice" class="hidden"><a class='notice_close'onclick='hide_notice()'>X</a><div id="notice_text"></div></div>
371
+ <div id="contents">
372
+ <ol class='bates_file_table_list' id='demo' style='display:none;'>
373
+ <li id='file_NUM'>
374
+ <div>
375
+ <input id="file_NUM_name" name="file[NUM][name]" readonly="readonly" type="text" value="FILE_NAME">
376
+ <input id="file_NUM_data" name="file[NUM][data]" type="hidden" value="NUM">
377
+ </div>
378
+ <div>
379
+ <input id="file_NUM_date" name="file[NUM][date]" type="text" value="DATE">
380
+ </div><div>
381
+ <input id="file_NUM_title" name="file[NUM][title]" type="text" value="TITLE">
382
+ </div>
383
+ |||
384
+ <a href="#" class="file_remover" onclick='this.parentNode.parentNode.removeChild(this.parentNode); return false;'>[x]</a>
385
+ </li>
386
+ </ol>
387
+ <form accept-charset="UTF-8" enctype="multipart/form-data" method="post" onsubmit="onSubmit()">
388
+ <h1 id='dropzone'>Drag PDF files here</h1>
389
+ <p>
390
+ <ul class='bates_file_table_list'>
391
+ <li>
392
+ <div>File Name</div>
393
+ <div>Date</div>
394
+ <div>Title</div>
395
+ </li>
396
+ </ul>
397
+ <input checked="checked" id="bates_first_pdf_is_cover" name="bates[first_pdf_is_cover]" type="checkbox" value="true">
398
+ <label for="bates_first_pdf_is_cover">Place the first PDF file before the Index page.</label>
399
+ <ol class='bates_file_table_list' id='file_list'></ol>
400
+ <input type="submit" value="Submit">
401
+ </p>
402
+ <h3>Settings</h3>
403
+ <table>
404
+ <tr><td>Output file name:</td><td><input type='text' id="output_filename" name='bates[output]' value="combined"></td></tr><tr><td>First page number:</td><td><input type='number' name='bates[first_page_number]' value="1">
405
+ </td></tr><tr><td>First index number:</td><td><input type='number' name='bates[first_index_number]' value="1">
406
+ </td></tr><tr><td>Numbering:</td><td><select id='numbering' name='bates[numbering]'>
407
+ <option value='0'>Center</option>
408
+ <option value='1'>Left</option>
409
+ <option value='2'>Right</option>
410
+ <option value='3'>None</option>
411
+ </select>
412
+ </td></tr><tr><td><input checked="checked" id="bates_should_index_files" name="bates[should_index]" type="checkbox" value="true"><label for='bates_should_index_files'>Index Files?</label></td><td><label for='bates_should_index_files'>un-check to avoid an index and title pages.</label>
413
+ </td></tr><tr><td><input id="bates_skip_cover" name="bates[skip_cover]" type="checkbox" value="true"><label for='bates_skip_cover'>Skip Cover?</label></td><td><label for='bates_skip_cover'>check to skip numbering the cover page.</label>
414
+ </td></tr><tr><td>Language:</td><td><select id='dir' name='bates[dir]'>
415
+ <option value='rtl'>עברית</option>
416
+ <option value='ltr'>English</option>
417
+ </select>
418
+ </td></tr><tr><td>Index Title:</td><td>
419
+ <input type='text' id='bates_index_title' name='bates[index_title]' value="Index">
420
+ </td></tr><tr><td>"Number" Header:</td><td>
421
+ <input type='text' id='bates_number_header' name='bates[number_header]' value="#">
422
+ </td></tr><tr><td>"Date" Header (Leave empty to ignore):</td><td>
423
+ <input type='text' id='bates_date_header' name='bates[date_header]' value="Date">
424
+ </td></tr><tr><td>"Title" Header:</td><td>
425
+ <input type='text' id='bates_title_header' name='bates[title_header]' value="Title">
426
+ </td></tr><tr><td> "Page Number" Header:</td><td>
427
+ <input type='text' id='bates_page_header' name='bates[page_header]' value="Page">
428
+ </td></tr><tr><td>Cover Page Title:</td><td>
429
+ <input type='text' id='bates_title_type' name='bates[title_type]' value="Exhibit">
430
+ <input type="submit" value="Submit">
431
+ </form>
432
+ </div>
433
+ <script>
434
+ function onSubmit()
435
+ {
436
+ return true;
437
+ }
438
+ file_i=0
439
+ files_read = 0
440
+
441
+ template = document.getElementById('demo').innerHTML
442
+
443
+ function transform_file(file)
444
+ {
445
+ // Get Time and Title if the name matches standard naming
446
+ obj_date_string = file.name.match("^[0-9\\-–]*") + ""
447
+ if(obj_date_string.length == 8) {
448
+ obj_date = obj_date_string.substr(6,2) + "." + obj_date_string.substr(4,2) + "." + obj_date_string.substr(0,4)
449
+ obj_description = file.name.substring(9, file.name.toLowerCase().search("\.pdf") )
450
+ } else if(obj_date_string.length == 10 && obj_date_string[4] == '-' && obj_date_string[7] == '-') {
451
+ obj_date = obj_date_string.substr(8,2) + "." + obj_date_string.substr(5,2) + "." + obj_date_string.substr(0,4)
452
+ obj_description = file.name.substring(11, file.name.toLowerCase().search("\.pdf") )
453
+ } else {
454
+ obj_date = ""
455
+ obj_description = file.name.substring(0, file.name.toLowerCase().search("\.pdf") )
456
+ }
457
+
458
+ // copy template and adjust details
459
+
460
+ document.getElementById('file_list').innerHTML += template.replace(RegExp("NUM", "g"), "" + file_i).replace(RegExp("FILE_NAME", "g"), file.name).replace(RegExp("DATE", "g"), obj_date).replace(RegExp("TITLE", "g"), obj_description)
461
+
462
+ // set reader for file
463
+ reader = new FileReader();
464
+ reader.futureObject = document.getElementById("file_" + file_i + "_data")
465
+
466
+ file_i += 1;
467
+
468
+ reader.onloadend = function(e)
469
+ {
470
+ //var id = this.futureObject.value
471
+ console.log("adding result to: " + this.futureObject.id )
472
+ document.getElementById(this.futureObject.id).value = e.target.result
473
+ files_read +=1
474
+ }
475
+
476
+ //reader.readAsText(file)
477
+ reader.readAsDataURL(file)
478
+ true
479
+ }
480
+
481
+ // make drop_zone droppable and set callbacks
482
+ var dropzone = document.getElementById('dropzone')
483
+
484
+ dropzone.ondragend = function (event) {event.stopPropagation();return false; };
485
+ dropzone.ondragover = function (event) {event.stopPropagation();return false; };
486
+ dropzone.ondragenter = function (event) {event.stopPropagation();return false; };
487
+
488
+ dropzone.ondrop = function(event) {
489
+ event.preventDefault()
490
+ event.stopPropagation();
491
+ var files = event.dataTransfer.files; // FileList object.
492
+ i = 0
493
+ while(files[i])
494
+ {
495
+ console.log('transforming:' + files[i] + ' name: ' + files[i].name.toLowerCase())
496
+ if( files[i].name.toLowerCase().search("\.pdf") != -1) transform_file(files[i])
497
+ i++
498
+ }
499
+
500
+ set_list_sotrable()
501
+ return false;
502
+ }
503
+
504
+ // make drag-drop and sortable list from file_list
505
+ var Dragged_id = ''
506
+
507
+ function start_drag_list_item(e) {
508
+ Dragged_id = this.id
509
+ e.dataTransfer.setData('text/plain', this.id)
510
+ this.style.opacity = '0.3'
511
+ }
512
+ function end_drag_list_item(e) {
513
+ this.style.opacity = '1'
514
+ Dragged_id = ''
515
+ }
516
+ function enter_drag_list_item(e) {
517
+ if(Dragged_id == '') return false;
518
+ if(this.id == Dragged_id) return false; //this.style.opacity = '0.7'
519
+ this.parentNode.insertBefore(this.parentNode.removeChild(document.getElementById(Dragged_id)), this);
520
+ }
521
+ function leave_drag_list_item(e) {
522
+ if(Dragged_id == '') return false;
523
+ if(this.id != Dragged_id) this.style.opacity = '1'
524
+ }
525
+ function drop_list_item(e)
526
+ {
527
+ e.stopPropagation()
528
+ e.preventDefault()
529
+ alert('move ' + Dragged_id + ' before ' + this.id)
530
+ if (this.id == Dragged_id) return false;
531
+ }
532
+ function set_list_sotrable()
533
+ {
534
+ all_list_items = document.querySelectorAll('#file_list li');
535
+ for(i=0; i < all_list_items.length; i++)
536
+ {
537
+ all_list_items[i].setAttribute("draggable","true");
538
+ all_list_items[i].ondragstart = start_drag_list_item
539
+ all_list_items[i].ondragenter = enter_drag_list_item
540
+ all_list_items[i].ondragleave = leave_drag_list_item
541
+ all_list_items[i].ondragend = end_drag_list_item
542
+ all_list_items[i].ondrop = drop_list_item
543
+ }
544
+ }
545
+
546
+ function get_today_as_str(){
547
+ const n = new Date();
548
+ return (n.getUTCFullYear().toString() + (n.getUTCMonth() < 10 ? ("0" + n.getUTCMonth().toString()) : n.getUTCMonth().toString()) + (n.getUTCMonth() < 10 ? ("0" + n.getUTCDate().toString()) : n.getUTCDate().toString()));
549
+ }
550
+
551
+ // set some initial values
552
+ function set_common_values(o){
553
+ for (let [key, value] of Object.entries(o)) {
554
+ console.log(key, value);
555
+ var tmp = document.getElementById(key);
556
+ if(tmp){
557
+ if(tmp.value)
558
+ tmp.value = value;
559
+ else
560
+ tmp.innerHTML = value;
561
+ }
562
+ }
563
+ }
564
+ function set_en_values(){
565
+
566
+ set_common_values({
567
+ output_filename: get_today_as_str() + " name",
568
+ bates_index_title: "Index",
569
+ bates_number_header: "Ex.",
570
+ bates_date_header: "Date",
571
+ bates_title_header: "Title",
572
+ bates_page_header: "Page",
573
+ bates_title_type: "Exhibit",
574
+ });
575
+ }
576
+ function set_he_values(){
577
+ set_common_values({
578
+ output_filename: get_today_as_str() + " שם",
579
+ bates_index_title: "תוכן עניינים",
580
+ bates_number_header: "נספח",
581
+ bates_date_header: "תאריך",
582
+ bates_title_header: "כותרת",
583
+ bates_page_header: "עמוד",
584
+ bates_title_type: "נספח",
585
+ });
586
+ }
587
+
588
+ function update_defaults(e) {
589
+ if(e.target.value == 'ltr') set_en_values();
590
+ else set_he_values();
591
+ }
592
+
593
+ function init_page(e){
594
+ set_he_values();
595
+ var tmp = document.getElementById("dir");
596
+ tmp.onchange = update_defaults;
597
+ }
598
+ init_page();
599
+ </script>
600
+ </body></html>
@@ -0,0 +1,59 @@
1
+ # This is a WebSocket / SSE notification broadcasting application.
2
+ #
3
+ # Running this application from the command line is easy with:
4
+ #
5
+ # iodine
6
+ #
7
+ # Or, in single thread and single process:
8
+ #
9
+ # iodine -t 1 -w 1
10
+ #
11
+ # Benchmark with `ab` or `wrk` (a 5 seconds benchmark with 2000 concurrent clients):
12
+ #
13
+ # ab -c 2000 -t 5 -n 1000000 -k http://127.0.0.1:3000/
14
+ # wrk -c2000 -d5 -t12 http://localhost:3000/
15
+ #
16
+ # Test websocket echo using the browser. For example:
17
+ # ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data);}; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
18
+
19
+
20
+ # A simple router - Checks for Websocket Upgrade and answers HTTP.
21
+ module MyHTTPRouter
22
+ # This is the HTTP response object according to the Rack specification.
23
+ HTTP_RESPONSE = [200, { 'Content-Type' => 'text/html',
24
+ 'Content-Length' => '77' },
25
+ ['Please connect using WebSockets or SSE (send messages only using WebSockets).']]
26
+
27
+ WS_RESPONSE = [0, {}, []].freeze
28
+
29
+ # this is function will be called by the Rack server (iodine) for every request.
30
+ def self.call env
31
+ # check if this is an upgrade request (WebsSocket / SSE).
32
+ if(env['rack.upgrade?'.freeze])
33
+ env['rack.upgrade'.freeze] = BroadcastClient
34
+ return WS_RESPONSE
35
+ end
36
+ # simply return the RESPONSE object, no matter what request was received.
37
+ HTTP_RESPONSE
38
+ end
39
+ end
40
+
41
+ # A simple Websocket Callback Object.
42
+ module BroadcastClient
43
+ # seng a message to new clients.
44
+ def on_open client
45
+ client.subscribe :broadcast
46
+ end
47
+ # send a message, letting the client know the server is suggunt down.
48
+ def on_shutdown client
49
+ client.write "Server shutting down. Goodbye."
50
+ end
51
+ # perform the echo
52
+ def on_message client, data
53
+ client.publish :broadcast, data
54
+ end
55
+ extend self
56
+ end
57
+
58
+ # this function call links our HelloWorld application with Rack
59
+ run MyHTTPRouter