· 5 years ago · Nov 26, 2020, 02:20 AM
1--===GIT API===
2--=============
3--Developed by LNETeam from LNET Technologies
4--Please remove the 'a' from the end of the file before putting it into your API folder
5
6--Usage: git.get(author,repository,branch,path,saveName), git.view(author,repository,branch,path)
7
8
9local function edit(file)
10-- Error checking
11local sPath = 'temp'
12
13local x,y = 1,1
14local w,h = term.getSize()
15local scrollX, scrollY = 0,0
16
17local tLines = {}
18local bRunning = true
19
20-- Colours
21local highlightColour, keywordColour, commentColour, textColour, bgColour
22if term.isColour() then
23 bgColour = colours.black
24 textColour = colours.white
25 highlightColour = colours.yellow
26 keywordColour = colours.yellow
27 commentColour = colours.lime
28 stringColour = colours.red
29else
30 bgColour = colours.black
31 textColour = colours.white
32 highlightColour = colours.white
33 keywordColour = colours.white
34 commentColour = colours.white
35 stringColour = colours.white
36end
37
38-- Menus
39local bMenu = false
40local nMenuItem = 1
41local tMenuItems = {"Exit", "Print"}
42local sStatus = "Press Ctrl to access menu"
43
44local function load(_sPath)
45 tLines = {}
46 if fs.exists( _sPath ) then
47 local file = io.open( _sPath, "r" )
48 local sLine = file:read()
49 while sLine do
50 table.insert( tLines, sLine )
51 sLine = file:read()
52 end
53 file:close()
54 end
55
56 if #tLines == 0 then
57 table.insert( tLines, "" )
58 end
59end
60
61local function save( _sPath )
62 -- Create intervening folder
63 local sDir = sPath:sub(1, sPath:len() - fs.getName(sPath):len() )
64 if not fs.exists( sDir ) then
65 fs.makeDir( sDir )
66 end
67
68 -- Save
69 local file = nil
70 local function innerSave()
71 file = fs.open( _sPath, "w" )
72 if file then
73 for n, sLine in ipairs( tLines ) do
74 file.write( sLine .. "\n" )
75 end
76 else
77 error( "Failed to open ".._sPath )
78 end
79 end
80
81 local ok = pcall( innerSave )
82 if file then
83 file.close()
84 end
85 return ok
86end
87
88local tKeywords = {
89 ["and"] = true,
90 ["break"] = true,
91 ["do"] = true,
92 ["else"] = true,
93 ["elseif"] = true,
94 ["end"] = true,
95 ["false"] = true,
96 ["for"] = true,
97 ["function"] = true,
98 ["if"] = true,
99 ["in"] = true,
100 ["local"] = true,
101 ["nil"] = true,
102 ["not"] = true,
103 ["or"] = true,
104 ["repeat"] = true,
105 ["return"] = true,
106 ["then"] = true,
107 ["true"] = true,
108 ["until"]= true,
109 ["while"] = true,
110}
111
112local function tryWrite( sLine, regex, colour )
113 local match = string.match( sLine, regex )
114 if match then
115 if type(colour) == "number" then
116 term.setTextColour( colour )
117 else
118 term.setTextColour( colour(match) )
119 end
120 term.write( match )
121 term.setTextColour( textColour )
122 return string.sub( sLine, string.len(match) + 1 )
123 end
124 return nil
125end
126
127local function writeHighlighted( sLine )
128 while string.len(sLine) > 0 do
129 sLine =
130 tryWrite( sLine, "^%-%-%[%[.-%]%]", commentColour ) or
131 tryWrite( sLine, "^%-%-.*", commentColour ) or
132 tryWrite( sLine, "^\".-[^\\]\"", stringColour ) or
133 tryWrite( sLine, "^\'.-[^\\]\'", stringColour ) or
134 tryWrite( sLine, "^%[%[.-%]%]", stringColour ) or
135 tryWrite( sLine, "^[%w_]+", function( match )
136 if tKeywords[ match ] then
137 return keywordColour
138 end
139 return textColour
140 end ) or
141 tryWrite( sLine, "^[^%w_]", textColour )
142 end
143end
144
145local function redrawText()
146 for y=1,h-1 do
147 term.setCursorPos( 1 - scrollX, y )
148 term.clearLine()
149
150 local sLine = tLines[ y + scrollY ]
151 if sLine ~= nil then
152 writeHighlighted( sLine )
153 end
154 end
155 term.setCursorPos( x - scrollX, y - scrollY )
156end
157
158local function redrawLine(_nY)
159 local sLine = tLines[_nY]
160 term.setCursorPos( 1 - scrollX, _nY - scrollY )
161 term.clearLine()
162 writeHighlighted( sLine )
163 term.setCursorPos( x - scrollX, _nY - scrollY )
164end
165
166local function setLeftStatus()
167end
168
169local function redrawMenu()
170 term.setCursorPos( 1, h )
171 term.clearLine()
172
173 local sLeft, sRight
174 local nLeftColour, nLeftHighlight1, nLeftHighlight2
175 if bMenu then
176 local sMenu = ""
177 for n,sItem in ipairs( tMenuItems ) do
178 if n == nMenuItem then
179 nLeftHighlight1 = sMenu:len() + 1
180 nLeftHighlight2 = sMenu:len() + sItem:len() + 2
181 end
182 sMenu = sMenu.." "..sItem.." "
183 end
184 sLeft = sMenu
185 nLeftColour = textColour
186 else
187 sLeft = sStatus
188 nLeftColour = highlightColour
189 end
190
191 -- Left goes last so that it can overwrite the line numbers.
192 sRight = "Ln "..y
193 term.setTextColour( highlightColour )
194 term.setCursorPos( w-sRight:len() + 1, h )
195 term.write(sRight)
196
197 sRight = tostring(y)
198 term.setTextColour( textColour )
199 term.setCursorPos( w-sRight:len() + 1, h )
200 term.write(sRight)
201
202 if sLeft then
203 term.setCursorPos( 1, h )
204 term.setTextColour( nLeftColour )
205 term.write(sLeft)
206 if nLeftHighlight1 then
207 term.setTextColour( highlightColour )
208 term.setCursorPos( nLeftHighlight1, h )
209 term.write( "[" )
210 term.setCursorPos( nLeftHighlight2, h )
211 term.write( "]" )
212 end
213 term.setTextColour( textColour )
214 end
215
216 -- Cursor highlights selection
217 term.setCursorPos( x - scrollX, y - scrollY )
218end
219
220local tMenuFuncs = {
221 Save=function()
222 if bReadOnly then
223 sStatus = "Access denied"
224 else
225 local ok, err = save( sPath )
226 if ok then
227 sStatus="Saved to "..sPath
228 else
229 sStatus="Error saving to "..sPath
230 end
231 end
232 redrawMenu()
233 end,
234 Print=function()
235 local sPrinterSide = nil
236 for n,sSide in ipairs(rs.getSides()) do
237 if peripheral.isPresent(sSide) and peripheral.getType(sSide) == "printer" then
238 sPrinterSide = sSide
239 break
240 end
241 end
242
243 if not sPrinterSide then
244 sStatus = "No printer attached"
245 return
246 end
247
248 local nPage = 0
249 local sName = fs.getName( sPath )
250 local printer = peripheral.wrap(sPrinterSide)
251 if printer.getInkLevel() < 1 then
252 sStatus = "Printer out of ink"
253 return
254 elseif printer.getPaperLevel() < 1 then
255 sStatus = "Printer out of paper"
256 return
257 end
258
259 local terminal = {
260 getCursorPos = printer.getCursorPos,
261 setCursorPos = printer.setCursorPos,
262 getSize = printer.getPageSize,
263 write = printer.write,
264 }
265 terminal.scroll = function()
266 if nPage == 1 then
267 printer.setPageTitle( sName.." (page "..nPage..")" )
268 end
269
270 while not printer.newPage() do
271 if printer.getInkLevel() < 1 then
272 sStatus = "Printer out of ink, please refill"
273 elseif printer.getPaperLevel() < 1 then
274 sStatus = "Printer out of paper, please refill"
275 else
276 sStatus = "Printer output tray full, please empty"
277 end
278
279 term.restore()
280 redrawMenu()
281 term.redirect( terminal )
282
283 local timer = os.startTimer(0.5)
284 sleep(0.5)
285 end
286
287 nPage = nPage + 1
288 if nPage == 1 then
289 printer.setPageTitle( sName )
290 else
291 printer.setPageTitle( sName.." (page "..nPage..")" )
292 end
293 end
294
295 bMenu = false
296 term.redirect( terminal )
297 local ok, error = pcall( function()
298 term.scroll()
299 for n, sLine in ipairs( tLines ) do
300 print( sLine )
301 end
302 end )
303 term.restore()
304 if not ok then
305 print( error )
306 end
307
308 while not printer.endPage() do
309 sStatus = "Printer output tray full, please empty"
310 redrawMenu()
311 sleep( 0.5 )
312 end
313 bMenu = true
314
315 if nPage > 1 then
316 sStatus = "Printed "..nPage.." Pages"
317 else
318 sStatus = "Printed 1 Page"
319 end
320 redrawMenu()
321 end,
322 Exit=function()
323 bRunning = false
324 end
325}
326
327local function doMenuItem( _n )
328 tMenuFuncs[tMenuItems[_n]]()
329 if bMenu then
330 bMenu = false
331 term.setCursorBlink( true )
332 end
333 redrawMenu()
334end
335
336local function setCursor( x, y )
337 local screenX = x - scrollX
338 local screenY = y - scrollY
339
340 local bRedraw = false
341 if screenX < 1 then
342 scrollX = x - 1
343 screenX = 1
344 bRedraw = true
345 elseif screenX > w then
346 scrollX = x - w
347 screenX = w
348 bRedraw = true
349 end
350
351 if screenY < 1 then
352 scrollY = y - 1
353 screenY = 1
354 bRedraw = true
355 elseif screenY > h-1 then
356 scrollY = y - (h-1)
357 screenY = h-1
358 bRedraw = true
359 end
360
361 if bRedraw then
362 redrawText()
363 end
364 term.setCursorPos( screenX, screenY )
365
366 -- Statusbar now pertains to menu, it would probably be safe to redraw the menu on every key event.
367 redrawMenu()
368end
369
370-- Actual program functionality begins
371load(sPath)
372
373term.setBackgroundColour( bgColour )
374term.clear()
375term.setCursorPos(x,y)
376term.setCursorBlink( true )
377
378redrawText()
379redrawMenu()
380
381-- Handle input
382while bRunning do
383 local sEvent, param, param2, param3 = os.pullEvent()
384 if sEvent == "key" then
385 if param == keys.up then
386 -- Up
387 if not bMenu then
388 if y > 1 then
389 -- Move cursor up
390 y = y - 1
391 x = math.min( x, string.len( tLines[y] ) + 1 )
392 setCursor( x, y )
393 end
394 end
395 elseif param == keys.down then
396 -- Down
397 if not bMenu then
398 -- Move cursor down
399 if y < #tLines then
400 y = y + 1
401 x = math.min( x, string.len( tLines[y] ) + 1 )
402 setCursor( x, y )
403 end
404 end
405 elseif param == keys.tab then
406 -- Tab
407 if not bMenu then
408 local sLine = tLines[y]
409
410 -- Indent line
411 -- IN CASE OF INSERT TAB IN PLACE:
412 -- tLines[y] = string.sub(sLine,1,x-1) .. " " .. string.sub(sLine,x)
413 tLines[y]=" "..tLines[y]
414 x = x + 2
415 setCursor( x, y )
416 redrawLine(y)
417 end
418 elseif param == keys.pageUp then
419 -- Page Up
420 if not bMenu then
421 -- Move up a page
422 local sx,sy=term.getSize()
423 y=y-sy-1
424 if y<1 then y=1 end
425 x = math.min( x, string.len( tLines[y] ) + 1 )
426 setCursor( x, y )
427 end
428 elseif param == keys.pageDown then
429 -- Page Down
430 if not bMenu then
431 -- Move down a page
432 local sx,sy=term.getSize()
433 if y<#tLines-sy-1 then
434 y = y+sy-1
435 else
436 y = #tLines
437 end
438 x = math.min( x, string.len( tLines[y] ) + 1 )
439 setCursor( x, y )
440 end
441 elseif param == keys.home then
442 -- Home
443 if not bMenu then
444 -- Move cursor to the beginning
445 x=1
446 setCursor(x,y)
447 end
448 elseif param == keys["end"] then
449 -- End
450 if not bMenu then
451 -- Move cursor to the end
452 x = string.len( tLines[y] ) + 1
453 setCursor(x,y)
454 end
455 elseif param == keys.left then
456 -- Left
457 if not bMenu then
458 if x > 1 then
459 -- Move cursor left
460 x = x - 1
461 elseif x==1 and y>1 then
462 x = string.len( tLines[y-1] ) + 1
463 y = y - 1
464 end
465 setCursor( x, y )
466 else
467 -- Move menu left
468 nMenuItem = nMenuItem - 1
469 if nMenuItem < 1 then
470 nMenuItem = #tMenuItems
471 end
472 redrawMenu()
473 end
474 elseif param == keys.right then
475 -- Right
476 if not bMenu then
477 if x < string.len( tLines[y] ) + 1 then
478 -- Move cursor right
479 x = x + 1
480 elseif x==string.len( tLines[y] ) + 1 and y<#tLines then
481 x = 1
482 y = y + 1
483 end
484 setCursor( x, y )
485 else
486 -- Move menu right
487 nMenuItem = nMenuItem + 1
488 if nMenuItem > #tMenuItems then
489 nMenuItem = 1
490 end
491 redrawMenu()
492 end
493 elseif param == keys.delete then
494 -- Delete
495 if not bMenu then
496 if x < string.len( tLines[y] ) + 1 then
497 local sLine = tLines[y]
498 tLines[y] = string.sub(sLine,1,x-1) .. string.sub(sLine,x+1)
499 redrawLine(y)
500 elseif y<#tLines then
501 tLines[y] = tLines[y] .. tLines[y+1]
502 table.remove( tLines, y+1 )
503 redrawText()
504 redrawMenu()
505 end
506 end
507 elseif param == keys.backspace then
508 -- Backspace
509 if not bMenu then
510 if x > 1 then
511 -- Remove character
512 local sLine = tLines[y]
513 tLines[y] = string.sub(sLine,1,x-2) .. string.sub(sLine,x)
514 redrawLine(y)
515
516 x = x - 1
517 setCursor( x, y )
518 elseif y > 1 then
519 -- Remove newline
520 local sPrevLen = string.len( tLines[y-1] )
521 tLines[y-1] = tLines[y-1] .. tLines[y]
522 table.remove( tLines, y )
523 redrawText()
524
525 x = sPrevLen + 1
526 y = y - 1
527 setCursor( x, y )
528 end
529 end
530 elseif param == keys.enter then
531 -- Enter
532 if not bMenu then
533 -- Newline
534 local sLine = tLines[y]
535 local _,spaces=string.find(sLine,"^[ ]+")
536 if not spaces then
537 spaces=0
538 end
539 tLines[y] = string.sub(sLine,1,x-1)
540 table.insert( tLines, y+1, string.rep(' ',spaces)..string.sub(sLine,x) )
541 redrawText()
542
543 x = spaces+1
544 y = y + 1
545 setCursor( x, y )
546 else
547 -- Menu selection
548 doMenuItem( nMenuItem )
549 end
550 elseif param == keys.leftCtrl or param == keys.rightCtrl then
551 -- Menu toggle
552 bMenu = not bMenu
553 if bMenu then
554 term.setCursorBlink( false )
555 nMenuItem = 1
556 else
557 term.setCursorBlink( true )
558 end
559 redrawMenu()
560 end
561
562 elseif sEvent == "char" then
563 if not bMenu then
564 -- Input text
565 local sLine = tLines[y]
566 tLines[y] = string.sub(sLine,1,x-1) .. param .. string.sub(sLine,x)
567 redrawLine(y)
568
569 x = x + string.len( param )
570 setCursor( x, y )
571 else
572 -- Select menu items
573 for n,sMenuItem in ipairs( tMenuItems ) do
574 if string.lower(string.sub(sMenuItem,1,1)) == string.lower(param) then
575 doMenuItem( n )
576 break
577 end
578 end
579 end
580
581 elseif sEvent == "mouse_click" then
582 if not bMenu then
583 if param == 1 then
584 -- Left click
585 local cx,cy = param2, param3
586 if cy < h then
587 y = math.min( math.max( scrollY + cy, 1 ), #tLines )
588 x = math.min( math.max( scrollX + cx, 1 ), string.len( tLines[y] ) + 1 )
589 setCursor( x, y )
590 end
591 end
592 end
593
594 elseif sEvent == "mouse_scroll" then
595 if not bMenu then
596 if param == -1 then
597 -- Scroll up
598 if scrollY > 0 then
599 -- Move cursor up
600 scrollY = scrollY - 1
601 redrawText()
602 end
603
604 elseif param == 1 then
605 -- Scroll down
606 local nMaxScroll = #tLines - (h-1)
607 if scrollY < nMaxScroll then
608 -- Move cursor down
609 scrollY = scrollY + 1
610 redrawText()
611 end
612
613 end
614 end
615 end
616end
617
618-- Cleanup
619term.clear()
620term.setCursorBlink( false )
621term.setCursorPos(1,1)
622end
623
624function requestObject(url,sN,mode)
625 if not url then error('Incorrect statement!') end
626 if not sN and mode == 'get' then error('Check mode!') end
627 if mode == 'get' then
628 http.request(url)
629 local requesting = true
630 while requesting do
631 local event, url, sourceText = os.pullEvent()
632 if event == "http_success" then
633 local respondedText = sourceText.readAll()
634 temp = io.open(sN,'w')
635 temp:write(respondedText)
636 temp:close()
637 requesting = false
638 return true
639 elseif event == "http_failure" then
640 requesting = false
641 return false
642 end
643 end
644 elseif mode == 'view' then
645 write('Fetching: '..url..'... ')
646 http.request(url)
647 local requesting = true
648 while requesting do
649 local event, url, sourceText = os.pullEvent()
650 if event == "http_success" then
651 local respondedText = sourceText.readAll()
652 temp = io.open('temp','w')
653 temp:write(respondedText)
654 temp:close()
655 edit('temp')
656 fs.delete('temp')
657 requesting = false
658 return true
659 elseif event == "http_failure" then
660 requesting = false
661 return false
662 end
663 end
664 end
665end
666
667function compileURL(auth,pro,bran,pat)
668 baseURL = 'https://raw.github.com/'..auth..'/'..pro..'/'..bran..'/'..pat
669 return baseURL
670end
671
672function get(auth,reps,bran,paths,sN)
673 if not auth or not reps or not bran or not paths or not sN then error('Attempt to compile nonexistent terms!') end
674 statusCode = requestObject(compileURL(auth,reps,bran,paths),sN,'get')
675 return statusCode
676end
677
678function view(auth,reps,bran,paths)
679 if not auth or not reps or not bran or not paths then error('Attempt to compile nonexistent terms!') end
680 statusCode = requestObject(compileURL(auth,reps,bran,paths),nil,'view')
681 return statusCode
682end
683