SHOW:
|
|
- or go back to the newest paste.
1 | - | --# Shell Utility Extended v2.0 - Program to extend/modify Computercraft autocompletion system. |
1 | + | --# Shell Utility Extended v2.1 - Program to extend/modify Computercraft autocompletion system. |
2 | --# Made By Wojbie | |
3 | --# http://pastebin.com/f8zycUS6 | |
4 | ||
5 | - | -- Copyright (c) 2016-2021 Wojbie (wojbie@wojbie.net) |
5 | + | -- Copyright (c) 2017-2021 Wojbie (wojbie@wojbie.net) |
6 | -- Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: | |
7 | -- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | |
8 | -- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | |
9 | -- 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. | |
10 | -- 4. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | |
11 | -- 5. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. | |
12 | -- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. | |
13 | ||
14 | - | --# New settings system usage functions. Allows auto correction of common errors. |
14 | + | --# New settings system useage functions. Allows autocorection of common errors. |
15 | local defaultSettings = { | |
16 | ["shellUtil.use_ghost"] = true, | |
17 | ["shellUtil.stop_dofile"] = true, | |
18 | ["shellUtil.chat_names"] = "", | |
19 | ["shellUtil.pastebin_names"] = "", | |
20 | } | |
21 | ||
22 | --Restore cleared settings | |
23 | for i,k in pairs(defaultSettings) do | |
24 | if settings.get(i) == nil then | |
25 | settings.set(i,k) | |
26 | end | |
27 | end | |
28 | ||
29 | local validSettingsTypes = { | |
30 | ["shellUtil.use_ghost"] = {["boolean"]=true}, | |
31 | ["shellUtil.stop_dofile"] = {["boolean"]=true}, | |
32 | ["shellUtil.chat_names"] = {["string"]=true}, | |
33 | ["shellUtil.pastebin_names"] = {["string"]=true}, | |
34 | } | |
35 | ||
36 | local validSettingsTest = { | |
37 | } | |
38 | ||
39 | local getSetting = function(A) | |
40 | local data = settings.get(A) | |
41 | if (not validSettingsTypes[A] or validSettingsTypes[A][type(data)]) and --See if setting type matches (when defined). | |
42 | (not validSettingsTest[A] or validSettingsTest[A](data)) --See if testing function agrees (when defined). | |
43 | then --All tests OK | |
44 | return data | |
45 | else --Any of test Failed. Reset to default setting. | |
46 | data = defaultSettings[A] | |
47 | settings.set(A,data) | |
48 | return data | |
49 | end | |
50 | end | |
51 | ||
52 | --# Basic file operators. | |
53 | local function append(A,B) local file = fs.open(tostring(A),"a") if not file then return false end file.write(B) file.close() return true end | |
54 | ||
55 | local function save(A,B) local file = fs.open(tostring(A),"w") if not file then return false end file.write(B) file.close() return true end | |
56 | local function saveT(A,B) return save(A,textutils.serialize(B)) end | |
57 | local function saveTL(A,B) return save(A,string.gsub(textutils.serialize(B),"\n%s*","")) end | |
58 | local function saveLines(A,B) local file = fs.open(tostring(A),"w") if not file then return false end for i=1,#B,1 do file.writeLine(B[i]) end file.close() return true end | |
59 | local function saveBin(A,B) local file = fs.open(tostring(A),"wb") if not file then return false end for i=1,#B,1 do file.write(B[i]) end file.close() return true end | |
60 | local function saveDump(A,B) return saveBin(A,{string.byte(B,1,#B)}) end | |
61 | ||
62 | local function get(A) local file = fs.open(tostring(A),"r") if not file then return false end local data = file.readAll() file.close() if data then return data end end | |
63 | local function getT(A) local data = get(A) if data then data = textutils.unserialize(data) end if data then return data end end | |
64 | local function getLines(A) local file = fs.open(tostring(A),"r") if not file then return false end local data = {} for k in file.readLine do data[#data+1] = k end file.close() return data end | |
65 | local function getBin(A) local file = fs.open(tostring(A),"rb") if not file then return false end local data = {} local b = file.read() while b do table.insert(data,b) b = file.read() end file.close() if data then return data end end | |
66 | local function getDump(A) local file = getBin(A) if not file then return false end local data = string.char(table.unpack(file)) if data then return data end end | |
67 | local function getHttp(A,B,C) if not http.checkURL(A) then return false end local file = B and http.post(A,B,C) or http.get(A,C) if not file then return false end local data = file.readAll() file.close() if data then return data end end | |
68 | ||
69 | local function makeLog(A) local file = fs.open(tostring(A),"a") if not file then return false end local on = true return function(m) if not on then return false end file.writeLine(m) file.flush() return true end,function() on = false file.close() end end | |
70 | local function makePrintLog(A) local logfile,logstop = makeLog(A) if not logfile then return false end return function(m) print(m) logfile(m) end,logstop,logfile end | |
71 | ||
72 | --# Useafull functions | |
73 | ||
74 | local function completeMultipleChoice( sText, tOptions, bAddSpaces, tOptionsGhosts ) --Copy of function cause its usefull | |
75 | local tResults = {} | |
76 | local tGhosts = {} | |
77 | for n=1,#tOptions do | |
78 | local sOption = tOptions[n] | |
79 | if #sOption + (bAddSpaces and 1 or 0) > #sText and string.sub( sOption, 1, #sText ) == sText then | |
80 | local sResult = string.sub( sOption, #sText + 1 ) | |
81 | if bAddSpaces then | |
82 | table.insert( tResults, sResult .. " " ) | |
83 | else | |
84 | table.insert( tResults, sResult ) | |
85 | end | |
86 | if tOptionsGhosts then | |
87 | if bAddSpaces then | |
88 | table.insert( tGhosts, tOptionsGhosts[n] or "") | |
89 | else | |
90 | table.insert( tGhosts, (tOptionsGhosts[n] and " "..tOptionsGhosts[n]) or "") | |
91 | end | |
92 | ||
93 | end | |
94 | end | |
95 | end | |
96 | return tResults,tGhosts | |
97 | end | |
98 | ||
99 | local function peripherallook(sType,fTest) --Fast way to make table of peripheral names. | |
100 | local tNames={} | |
101 | peripheral.find(sType,function(sName,tObject) if ( not fTest ) or fTest(sName,tObject) then table.insert(tNames,sName) end return false end) | |
102 | return tNames | |
103 | end | |
104 | ||
105 | ||
106 | local function hostnameslook(sProtocol,nTime) --Program to lookup hostnames that are in set sProtocol. nTime is time it will look. Defaults to 0,5. | |
107 | -- Build list of host IDs | |
108 | local tResults = {} | |
109 | local close=false | |
110 | ||
111 | if not rednet.isOpen() then | |
112 | for i,k in pairs(rs.getSides()) do | |
113 | if peripheral.getType( k ) == "modem" then | |
114 | rednet.open(k) | |
115 | close=k | |
116 | break | |
117 | end | |
118 | end | |
119 | if not close then return tResults end | |
120 | end | |
121 | ||
122 | -- Broadcast a lookup packet | |
123 | rednet.broadcast( { | |
124 | sType = "lookup", | |
125 | sProtocol = sProtocol, | |
126 | sHostname = sHostname, | |
127 | }, "dns" ) | |
128 | ||
129 | -- Start a timer | |
130 | local timer = os.startTimer( nTime or 0.5 ) | |
131 | ||
132 | -- Wait for events | |
133 | while true do | |
134 | local event, p1, p2, p3 = os.pullEvent() | |
135 | if event == "rednet_message" then | |
136 | -- Got a rednet message, check if it's the response to our request | |
137 | local nSenderID, tMessage, sMessageProtocol = p1, p2, p3 | |
138 | if sMessageProtocol == "dns" and tMessage.sType == "lookup response" then | |
139 | if tMessage.sProtocol == sProtocol then | |
140 | table.insert( tResults, tMessage.sHostname ) | |
141 | end | |
142 | end | |
143 | else | |
144 | -- Got a timer event, check it's the end of our timeout | |
145 | if p1 == timer then | |
146 | break | |
147 | end | |
148 | end | |
149 | end | |
150 | ||
151 | if close then | |
152 | rednet.close(close) | |
153 | end | |
154 | ||
155 | return tResults | |
156 | end | |
157 | ||
158 | --## Main Program Parts ##-- | |
159 | ||
160 | --# Disable autocompletition of rarely used parts/phrases that mess with the lives like xpcall and dofile | |
161 | ||
162 | if getSetting("shellUtil.stop_dofile") and textutils.complete("do")[1] == "file(" then --Tests if not disabled already to not cause chaining effect. | |
163 | ||
164 | local limited = {["do"]="file(",["x"]="pcall("} | |
165 | ||
166 | local textutils_complete = textutils.complete | |
167 | textutils.complete = function(sName,tEnv) | |
168 | if not limited[sName] then | |
169 | return textutils_complete(sName,tEnv) | |
170 | else | |
171 | local ret = textutils_complete(sName,tEnv) | |
172 | for i=#ret,1,-1 do | |
173 | if ret[i] == limited[sName] then table.remove(ret,i) end | |
174 | end | |
175 | return ret | |
176 | end | |
177 | end | |
178 | ||
179 | end | |
180 | ||
181 | --# Read overwrite to add ghosting and change to few vanilla auto-completitions to add ghost capabilities. | |
182 | ||
183 | if getSetting("shellUtil.use_ghost") then --This setting is only tested once at moment program is run. | |
184 | ||
185 | -- Overwriting read with one that supports 2nd Ghost table. | |
186 | function _G.read( _sReplaceChar, _tHistory, _fnComplete ) | |
187 | term.setCursorBlink( true ) | |
188 | ||
189 | local sLine = "" | |
190 | local nHistoryPos | |
191 | local nPos = 0 | |
192 | if _sReplaceChar then | |
193 | _sReplaceChar = string.sub( _sReplaceChar, 1, 1 ) | |
194 | end | |
195 | ||
196 | local tCompletions | |
197 | local nCompletion | |
198 | local tGhosts --# | |
199 | local function recomplete() | |
200 | if _fnComplete and nPos == string.len(sLine) then | |
201 | tCompletions,tGhosts = _fnComplete( sLine ) --# | |
202 | if tCompletions and #tCompletions > 0 then | |
203 | nCompletion = 1 | |
204 | tGhosts = tGhosts or {} --# | |
205 | else | |
206 | nCompletion = nil | |
207 | end | |
208 | else | |
209 | tCompletions = nil | |
210 | nCompletion = nil | |
211 | end | |
212 | end | |
213 | ||
214 | local function uncomplete() | |
215 | tCompletions = nil | |
216 | nCompletion = nil | |
217 | tGhosts = nil --# | |
218 | end | |
219 | ||
220 | local w = term.getSize() | |
221 | local sx = term.getCursorPos() | |
222 | ||
223 | local function redraw( _bClear ) | |
224 | local nScroll = 0 | |
225 | if sx + nPos >= w then | |
226 | nScroll = (sx + nPos) - w | |
227 | end | |
228 | ||
229 | local cx,cy = term.getCursorPos() | |
230 | term.setCursorPos( sx, cy ) | |
231 | local sReplace = (_bClear and " ") or _sReplaceChar | |
232 | if sReplace then | |
233 | term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) ) | |
234 | else | |
235 | term.write( string.sub( sLine, nScroll + 1 ) ) | |
236 | end | |
237 | ||
238 | if nCompletion then | |
239 | local sCompletion = tCompletions[ nCompletion ] | |
240 | local sGhost = tGhosts[ nCompletion ] --# | |
241 | local oldText, oldBg | |
242 | if not _bClear then | |
243 | oldText = term.getTextColor() | |
244 | oldBg = term.getBackgroundColor() | |
245 | term.setTextColor( colors.white ) | |
246 | term.setBackgroundColor( colors.gray ) | |
247 | end | |
248 | if sReplace then | |
249 | term.write( string.rep( sReplace, string.len( sCompletion ) ) ) | |
250 | else | |
251 | term.write( sCompletion ) | |
252 | end | |
253 | --# | |
254 | if sGhost then | |
255 | if not _bClear then | |
256 | term.setTextColor( colors.lightGray ) | |
257 | --term.setBackgroundColor( colors.gray ) | |
258 | end | |
259 | if sReplace then | |
260 | term.write( string.rep( sReplace, string.len( sGhost ) ) ) | |
261 | else | |
262 | term.write( sGhost ) | |
263 | end | |
264 | end | |
265 | --# | |
266 | if not _bClear then | |
267 | term.setTextColor( oldText ) | |
268 | term.setBackgroundColor( oldBg ) | |
269 | end | |
270 | end | |
271 | ||
272 | term.setCursorPos( sx + nPos - nScroll, cy ) | |
273 | end | |
274 | ||
275 | local function clear() | |
276 | redraw( true ) | |
277 | end | |
278 | ||
279 | recomplete() | |
280 | redraw() | |
281 | ||
282 | local function acceptCompletion() | |
283 | if nCompletion then | |
284 | -- Clear | |
285 | clear() | |
286 | ||
287 | -- Find the common prefix of all the other suggestions which start with the same letter as the current one | |
288 | local sCompletion = tCompletions[ nCompletion ] | |
289 | sLine = sLine .. sCompletion | |
290 | nPos = string.len( sLine ) | |
291 | ||
292 | -- Redraw | |
293 | recomplete() | |
294 | redraw() | |
295 | end | |
296 | end | |
297 | while true do | |
298 | local sEvent, param = os.pullEvent() | |
299 | if sEvent == "char" then | |
300 | -- Typed key | |
301 | clear() | |
302 | sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 ) | |
303 | nPos = nPos + 1 | |
304 | recomplete() | |
305 | redraw() | |
306 | ||
307 | elseif sEvent == "paste" then | |
308 | -- Pasted text | |
309 | clear() | |
310 | sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 ) | |
311 | nPos = nPos + string.len( param ) | |
312 | recomplete() | |
313 | redraw() | |
314 | ||
315 | elseif sEvent == "key" then | |
316 | if param == keys.enter then | |
317 | -- Enter | |
318 | if nCompletion then | |
319 | clear() | |
320 | uncomplete() | |
321 | redraw() | |
322 | end | |
323 | break | |
324 | ||
325 | elseif param == keys.left then | |
326 | -- Left | |
327 | if nPos > 0 then | |
328 | clear() | |
329 | nPos = nPos - 1 | |
330 | recomplete() | |
331 | redraw() | |
332 | end | |
333 | ||
334 | elseif param == keys.right then | |
335 | -- Right | |
336 | if nPos < string.len(sLine) then | |
337 | -- Move right | |
338 | clear() | |
339 | nPos = nPos + 1 | |
340 | recomplete() | |
341 | redraw() | |
342 | else | |
343 | -- Accept autocomplete | |
344 | acceptCompletion() | |
345 | end | |
346 | ||
347 | elseif param == keys.up or param == keys.down then | |
348 | -- Up or down | |
349 | if nCompletion then | |
350 | -- Cycle completions | |
351 | clear() | |
352 | if param == keys.up then | |
353 | nCompletion = nCompletion - 1 | |
354 | if nCompletion < 1 then | |
355 | nCompletion = #tCompletions | |
356 | end | |
357 | elseif param == keys.down then | |
358 | nCompletion = nCompletion + 1 | |
359 | if nCompletion > #tCompletions then | |
360 | nCompletion = 1 | |
361 | end | |
362 | end | |
363 | redraw() | |
364 | ||
365 | elseif _tHistory then | |
366 | -- Cycle history | |
367 | clear() | |
368 | if param == keys.up then | |
369 | -- Up | |
370 | if nHistoryPos == nil then | |
371 | if #_tHistory > 0 then | |
372 | nHistoryPos = #_tHistory | |
373 | end | |
374 | elseif nHistoryPos > 1 then | |
375 | nHistoryPos = nHistoryPos - 1 | |
376 | end | |
377 | else | |
378 | -- Down | |
379 | if nHistoryPos == #_tHistory then | |
380 | nHistoryPos = nil | |
381 | elseif nHistoryPos ~= nil then | |
382 | nHistoryPos = nHistoryPos + 1 | |
383 | end | |
384 | end | |
385 | if nHistoryPos then | |
386 | sLine = _tHistory[nHistoryPos] | |
387 | nPos = string.len( sLine ) | |
388 | else | |
389 | sLine = "" | |
390 | nPos = 0 | |
391 | end | |
392 | uncomplete() | |
393 | redraw() | |
394 | ||
395 | end | |
396 | ||
397 | elseif param == keys.backspace then | |
398 | -- Backspace | |
399 | if nPos > 0 then | |
400 | clear() | |
401 | sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 ) | |
402 | nPos = nPos - 1 | |
403 | recomplete() | |
404 | redraw() | |
405 | end | |
406 | ||
407 | elseif param == keys.home then | |
408 | -- Home | |
409 | if nPos > 0 then | |
410 | clear() | |
411 | nPos = 0 | |
412 | recomplete() | |
413 | redraw() | |
414 | end | |
415 | ||
416 | elseif param == keys.delete then | |
417 | -- Delete | |
418 | if nPos < string.len(sLine) then | |
419 | clear() | |
420 | sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 ) | |
421 | recomplete() | |
422 | redraw() | |
423 | end | |
424 | ||
425 | elseif param == keys["end"] then | |
426 | -- End | |
427 | if nPos < string.len(sLine ) then | |
428 | clear() | |
429 | nPos = string.len(sLine) | |
430 | recomplete() | |
431 | redraw() | |
432 | end | |
433 | ||
434 | elseif param == keys.tab then | |
435 | -- Tab (accept autocomplete) | |
436 | acceptCompletion() | |
437 | ||
438 | end | |
439 | ||
440 | elseif sEvent == "term_resize" then | |
441 | -- Terminal resized | |
442 | w = term.getSize() | |
443 | redraw() | |
444 | ||
445 | end | |
446 | end | |
447 | ||
448 | local cx, cy = term.getCursorPos() | |
449 | term.setCursorBlink( false ) | |
450 | term.setCursorPos( w + 1, cy ) | |
451 | print() | |
452 | ||
453 | return sLine | |
454 | end | |
455 | ||
456 | ||
457 | end | |
458 | ||
459 | ||
460 | --#Generate Shell Completitions | |
461 | ||
462 | -- /rom/programs/ | |
463 | -- Eject --List only disk drives. Ghost drive content type and label/songname. | |
464 | local function completeEject( shell, nIndex, sText, tPreviousText ) | |
465 | if nIndex == 1 then | |
466 | local tNames = peripherallook("drive") | |
467 | local tGhosts = {} | |
468 | for i=1,#tNames do | |
469 | local sName = tNames[i] | |
470 | if disk.hasData(sName) then | |
471 | tGhosts[i] = " Data "..(disk.getLabel(sName) or "") | |
472 | elseif disk.hasAudio(sName) then | |
473 | tGhosts[i] = " Music "..(disk.getAudioTitle(sName) or "") | |
474 | elseif disk.isPresent(sName) then | |
475 | tGhosts[i] = " Unknown" | |
476 | else | |
477 | tGhosts[i] = " Empty" | |
478 | end | |
479 | end | |
480 | return completeMultipleChoice(sText,tNames,false,tGhosts) | |
481 | end | |
482 | end | |
483 | -- Gps -- Move order of options so locate is first. | |
484 | local tGPSOptions = {"locate" , "host", "host "} | |
485 | local function completeGPS( shell, nIndex, sText, tPreviousText ) | |
486 | if nIndex == 1 then | |
487 | return completeMultipleChoice( sText, tGPSOptions ) | |
488 | end | |
489 | end | |
490 | -- Label -- List only disk drives. | |
491 | local tLabelOptions = { "get", "get ", "set ", "clear", "clear " } | |
492 | local function completeLabel( shell, nIndex, sText, tPreviousText ) | |
493 | if nIndex == 1 then | |
494 | return completeMultipleChoice( sText, tLabelOptions ) | |
495 | elseif nIndex == 2 then | |
496 | return completeMultipleChoice(sText,peripherallook("drive")) | |
497 | end | |
498 | end | |
499 | -- Monitor -- List only monitors. Ghost current size of selected monitor. | |
500 | local function completeMonitor( shell, nIndex, sText, tPreviousText ) | |
501 | if nIndex == 1 then | |
502 | local tNames = peripherallook("monitor") | |
503 | local tGhosts = {} | |
504 | for i=1,#tNames do | |
505 | local x,y = peripheral.call(tNames[i],"getSize") | |
506 | tGhosts[i]= x.."x"..y | |
507 | end | |
508 | return completeMultipleChoice(sText,peripherallook("monitor"), true ,tGhosts) | |
509 | elseif nIndex == 2 then | |
510 | return shell.completeProgram( sText ) | |
511 | end | |
512 | end | |
513 | -- Set -- Ghost the current setting (if table say [table]) | |
514 | local function completeSet( shell, nIndex, sText, tPreviousText ) | |
515 | if nIndex == 1 then | |
516 | local tNames = settings.getNames() | |
517 | local tGhosts = {} | |
518 | for i=1,#tNames do | |
519 | local data = settings.get(tNames[i]) | |
520 | tGhosts[i] = type(data) == "table" and "Table Detected" or tostring(data) | |
521 | end | |
522 | return completeMultipleChoice( sText, tNames, true , tGhosts) | |
523 | end | |
524 | end | |
525 | ||
526 | --/rom/programs/fun | |
527 | -- DJ -- List only disk drives with music. Ghosts dong names. | |
528 | local tDJOptions = { "play", "play ", "stop" } | |
529 | local function Audiotest(sName,tObject) | |
530 | return tObject.hasAudio() | |
531 | end | |
532 | local function completeDJ( shell, nIndex, sText, tPreviousText ) | |
533 | if nIndex == 1 then | |
534 | return completeMultipleChoice( sText, tDJOptions ) | |
535 | elseif nIndex == 2 and tPreviousText[2] == "play" then | |
536 | local tNames = peripherallook("drive",Audiotest) | |
537 | local tGhosts = {} | |
538 | for i=1,#tNames do | |
539 | tGhosts[i] = disk.getAudioTitle(tNames[i]) | |
540 | end | |
541 | return completeMultipleChoice(sText,tNames,false,tGhosts) | |
542 | end | |
543 | end | |
544 | ||
545 | --rom/programs/http/ | |
546 | --Pastebin -- List pastes from "shellUtil.pastebin_names" user(s), Ghost paste names. Suggest File Names based of pasteName? | |
547 | ||
548 | - | --get website http://pastebin.com/u/..name |
548 | + | --get website https://pastebin.com/u/..name |
549 | --<td><img src="/i/t.gif" class="i_p0" title="Public paste, anybody can see this paste." alt="" /> <a href="/DW3LCC3L">Monitor Mirror v2.1</a></td> | |
550 | --local tPastes={"DW3LCC3L"} | |
551 | --local tPasteNames={"Monitor Mirror v2.1"} | |
552 | --local tPasteSuggestNames = {["DW3LCC3L"] = "Monitor_Mirror_v2.1} | |
553 | ||
554 | --Make table of usernames from settings | |
555 | local tPastebinUserNames = {} | |
556 | for sName in string.gmatch( getSetting("shellUtil.pastebin_names"), "[^,]+" ) do table.insert(tPastebinUserNames,sName) end | |
557 | ||
558 | --Code to get all the public pastes on Ext-util load. | |
559 | local tPastes = {} | |
560 | local tPasteNames = {} | |
561 | local tPasteSuggestNames = {} | |
562 | for _,name in pairs(tPastebinUserNames) do | |
563 | - | local site = "http://pastebin.com/u/"..textutils.urlEncode( name ) |
563 | + | local site = "https://pastebin.com/u/"..textutils.urlEncode( name ) |
564 | if http.checkURL(site) then | |
565 | local data = getHttp(site) | |
566 | if data then | |
567 | --get pastes from data here. | |
568 | for i,k in string.gmatch (data, '<td><img src="/i/t.gif" class="i_p0" title="Public paste, anybody can see this paste." alt="" /> <a href="/(%w+)">(.-)</a></td>') do | |
569 | table.insert(tPastes,i) | |
570 | table.insert(tPasteNames,k) | |
571 | tPasteSuggestNames[i] = string.gsub(k,"%s","_") | |
572 | end | |
573 | end | |
574 | end | |
575 | end | |
576 | local tPastebinOptions = { "get ", "run ", "put" } | |
577 | local function completePastebin( shell, nIndex, sText, tPreviousText ) | |
578 | if nIndex == 1 then | |
579 | return completeMultipleChoice( sText, tPastebinOptions ) | |
580 | elseif nIndex == 2 then | |
581 | if tPreviousText[2] == "put" then | |
582 | return fs.complete( sText, shell.dir(), true, false ) | |
583 | elseif tPreviousText[2] == "get" then | |
584 | return completeMultipleChoice( sText, tPastes, true,tPasteNames) | |
585 | elseif tPreviousText[2] == "run" then | |
586 | return completeMultipleChoice( sText, tPastes, true,tPasteNames) | |
587 | end | |
588 | elseif nIndex == 3 then | |
589 | if tPreviousText[2] == "get" and tPasteSuggestNames[tPreviousText[3]] then | |
590 | return completeMultipleChoice( sText, {tPasteSuggestNames[tPreviousText[3]]} ) | |
591 | end | |
592 | end | |
593 | end | |
594 | ||
595 | --rom/programs/rednet/ | |
596 | -- Chat -- On join allow for duble tap of Tab to scan area for chat servers. Automaticly suggest name(s) from "shellUtil.chat_names" | |
597 | --##FIND WAY TO EXTRACT ANY SERVER INFO DATA FROM CHAT SERVER WITHOUT LOGGING INTO IT | |
598 | local tChatOptions = {"join ", "host "} | |
599 | local tServers = {} | |
600 | local nLasttab = 0 | |
601 | local function completeChat( shell, nIndex, sText, tPreviousText ) | |
602 | if nIndex == 1 then | |
603 | return completeMultipleChoice( sText, tChatOptions ) | |
604 | elseif nIndex == 2 and tPreviousText[2] == "join" then | |
605 | local tGhosts = {} | |
606 | if sText =="" then --Act only is sText field is empty. | |
607 | local nTime=os.clock() | |
608 | if (nTime-nLasttab) < 0 then --Still Blocked from last scan. | |
609 | --do nothing | |
610 | elseif (nTime-nLasttab) < 0.5 then | |
611 | tServers = hostnameslook("chat") --When 2 empty inputs in 0.5 sec range do a rednet scan, if not empty dont re-scan. | |
612 | if #tServers == 0 then | |
613 | tServers = {""} | |
614 | tGhosts = {"[No Servers Found. Re-Tap to Re-Scan]"} | |
615 | nLasttab = os.clock() | |
616 | else | |
617 | nLasttab = os.clock() + 30 -- Block scanning for 30 sec so it won't scan over and over again in row. | |
618 | end | |
619 | else | |
620 | tServers = {""} | |
621 | tGhosts = {"[Double-Tap Tab to Scan]"} | |
622 | nLasttab = os.clock() | |
623 | end | |
624 | end | |
625 | return completeMultipleChoice( sText, tServers , true ,tGhosts) | |
626 | elseif nIndex == 3 and tPreviousText[2] == "join" then | |
627 | local tNames = {} | |
628 | for sName in string.gmatch( getSetting("shellUtil.chat_names"), "[^,]+" ) do table.insert(tNames,sName) end | |
629 | return completeMultipleChoice( sText, tNames) | |
630 | end | |
631 | end | |
632 | ||
633 | --# Apply said functions | |
634 | - | shell.setCompletionFunction( "rom/programs/eject", completeEject ) |
634 | + | shell.setCompletionFunction( "rom/programs/eject.lua", completeEject ) |
635 | - | shell.setCompletionFunction( "rom/programs/gps", completeGPS ) |
635 | + | shell.setCompletionFunction( "rom/programs/gps.lua", completeGPS ) |
636 | - | shell.setCompletionFunction( "rom/programs/label", completeLabel ) |
636 | + | shell.setCompletionFunction( "rom/programs/label.lua", completeLabel ) |
637 | - | shell.setCompletionFunction( "rom/programs/monitor", completeMonitor ) |
637 | + | shell.setCompletionFunction( "rom/programs/monitor.lua", completeMonitor ) |
638 | - | shell.setCompletionFunction( "rom/programs/set", completeSet ) |
638 | + | shell.setCompletionFunction( "rom/programs/set.lua", completeSet ) |
639 | ||
640 | - | shell.setCompletionFunction( "rom/programs/fun/dj", completeDJ ) |
640 | + | shell.setCompletionFunction( "rom/programs/fun/dj.lua", completeDJ ) |
641 | ||
642 | - | shell.setCompletionFunction( "rom/programs/http/pastebin", completePastebin ) |
642 | + | shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completePastebin ) |
643 | ||
644 | - | shell.setCompletionFunction( "rom/programs/rednet/chat", completeChat ) |
644 | + | shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completeChat ) |