· 9 years ago · Dec 13, 2016, 12:04 AM
1--[[
2 Name: Discover Network API
3 Author: DannySMc (dannysmc95)
4 License: I only ask that you can at least credit me somewhere for hosting the Discover Network.
5 Discover.Core -> Core operations to edit, update, set and get data in the object.
6 Discover.User -> User operations for login, register and user management.
7 Discover.Apps -> App operations, upload, download, comment and more.
8 Discover.Snippets -> Snippet operations upload, download, update and more.
9 Discover.Cloud -> Cloud storage operations to upload, download and rename files.
10 Discover.Feed -> View and post on the news feed.
11 Discover.Mail -> Mailbox operations for controlling and manipulating your mail.
12--]]
13Discover = {
14 Data = {
15 Urls = {
16 Store = "http://api.dannysmc.com/store.php";
17 User = "http://api.dannysmc.com/user.php";
18 Projects = "http://api.dannysmc.com/projects.php";
19 Distribution = "http://api.dannysmc.com/distribution.php";
20 Pastebin = "https://api.dannysmc.com/pastebin.php";
21 };
22 Headers = {
23 ["User-Agent"] = "DiscoverAPI";
24 ["User-Net"] = "DiscoverNetwork";
25 };
26 };
27 Core = {
28 Internal = {
29 Version = "0.1";
30 Build = "1";
31 Release = "Alpha";
32 };
33 Report = function( self, data )
34 local query = "cmd=report_bug&data=" .. tostring(textutils.serialize(data));
35 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
36 req = textutils.unserialize(req.readAll())
37 if req.status then
38 return true
39 else
40 return unpack({false, req.error})
41 end
42 end;
43 GetStats = function( self )
44 local query = "cmd=get_stats&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
45 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
46 req = textutils.unserialize(req.readAll())
47 if req.status then
48 Discover.User.Data.CMessage = tostring(req.message)
49 return req.data
50 else
51 Discover.User.Data.ErrorMsg = req.error
52 return false
53 end
54 end;
55 GetVersion = function( self, field )
56 if field then
57 return self.Internal[field]
58 else
59 return tostring("Version " .. self.Internal.Version .. ":" .. self.Internal.Build .. " (" .. self.Internal.Release .. ")")
60 end
61 end;
62 GetLatestError = function( self )
63 return tostring(Discover.User.Data.ErrorMsg);
64 end;
65 GetLatestMessage = function( self )
66 return tostring(Discover.User.Data.CMessage);
67 end;
68 Update = function( self, ntype, key, version )
69 if ntype == "check" then
70 local query = "cmd=check-update&key=" .. textutils.urlEncode(tostring(key))
71 local req = http.post(Discover.Data.Urls.Distribution, query, Discover.Data.Headers)
72 req = textutils.unserialize(req.readAll())
73 if req.status then
74 if tonumber(req.data) > tonumber(version) then
75 return true;
76 else
77 return false;
78 end
79 else
80 return unpack({false, req.error});
81 end
82 elseif ntype == "download" then
83 local query = "cmd=download-update&key=" .. textutils.urlEncode(tostring(key))
84 local req = http.post(Discover.Data.Urls.Distribution, query, Discover.Data.Headers)
85 req = req.readAll();
86 if req then
87 local f = fs.open(shell.getRunningProgram(), "w")
88 f.write(req)
89 f.close()
90 return true;
91 else
92 return unpack({false, "An error occured while downloading the update"});
93 end
94 end
95 end;
96 };
97 Plugins = {
98 List = function( self )
99 local query = "cmd=get-plugins";
100 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
101 req = textutils.unserialize(req.readAll())
102 if req.status then
103 return unpack({true,req.data});
104 else
105 return unpack({false,req.error});
106 end
107 end;
108 Download = function( self, id, path, filename )
109 local query = "cmd=download-plugin&id=" .. textutils.urlEncode(tostring(id));
110 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers);
111 req = req.readAll();
112 if req == "false" then
113 return unpack({false, "An error occured"});
114 else
115 if not fs.exists(path) then
116 fs.makeDir(path)
117 else
118 if not fs.isDir(path) then
119 return unpack({false,"Path is already used and not a directory, cancelling."});
120 end
121 end
122 local f = fs.open(fs.combine(path, filename), "w")
123 f.write(req)
124 f.close()
125 return true;
126 end
127 end;
128 };
129 User = {
130 Data = {
131 Username = nil;
132 Password = nil;
133 AuthKey = nil;
134 ErrorMsg = nil;
135 LoggedIn = false;
136 CMessage = nil;
137 Rank = nil;
138 };
139 GetField = function( self, field )
140 return tostring(self.Data[field])
141 end;
142 GetRank = function( self )
143 return tostring(self.Data.Rank);
144 end;
145 Reset = function( self )
146 self.Data.Username = nil;
147 self.Data.Password = nil;
148 self.Data.AuthKey = nil;
149 self.Data.LoggedIn = false;
150 self.Data.Rank = nil;
151 return true;
152 end;
153 LoggedIn = function( self )
154 if self.Data.LoggedIn then
155 return true
156 else
157 return false
158 end
159 end;
160 ManualLogin = function( self, username, password )
161 if username then
162 self.Data.Username = username
163 end
164 if password then
165 self.Data.Password = password
166 end
167 if self.Data.Username and self.Data.Password then
168 local query = "cmd=login&username="..textutils.urlEncode(tostring(self.Data.Username)).."&password="..textutils.urlEncode(tostring(self.Data.Password))
169 local res = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
170 res = textutils.unserialize(res.readAll())
171 if res.status == true then
172 self.Data.AuthKey = res.authkey
173 self.Data.LoggedIn = true;
174 self.Data.Rank = res.rank;
175 return true
176 elseif res.status == false then
177 self.Data.ErrorMsg = res.error
178 return false
179 end
180 else
181 return false
182 end
183 end;
184 Login = function( self, username, password )
185 if username then
186 self.Data.Username = username
187 end
188 if password then
189 self.Data.Password = Discover.Crypto:Sha256(password);
190 end
191 if self.Data.Username and self.Data.Password then
192 local query = "cmd=login&username="..textutils.urlEncode(tostring(self.Data.Username)).."&password="..textutils.urlEncode(tostring(self.Data.Password))
193 local res = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
194 res = textutils.unserialize(res.readAll())
195 if res.status == true then
196 self.Data.AuthKey = res.authkey
197 self.Data.LoggedIn = true;
198 self.Data.Rank = res.rank;
199 return true
200 elseif res.status == false then
201 self.Data.ErrorMsg = res.error
202 return false
203 end
204 else
205 return false
206 end
207 end;
208 Register = function( self, username, password, email )
209 if username and password and email then
210 if password then
211 password = Discover.Crypto:Sha256(password);
212 end
213 local query = "cmd=register&username="..textutils.urlEncode(tostring(username)).."&password="..textutils.urlEncode(tostring(password)).."&email="..textutils.urlEncode(tostring(email))
214 local req = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
215 req = textutils.unserialize(req.readAll())
216 if req.status then
217 self.Data.CMessage = tostring(req.message)
218 return unpack({true,req.message});
219 else
220 return unpack({false,req.error});
221 end
222 else
223 self.Data.ErrorMsg = "Please supply a username, password and email!"
224 return false
225 end
226 end;
227 Modify = function( self, field, value )
228 if field == "password" then
229 local query = "cmd=modify&field=password&key="..textutils.urlEncode(tostring(self.Data.AuthKey)) .. "&new=" .. textutils.urlEncode(tostring(Discover.Crypto:Sha256(value)))
230 local req = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
231 req = textutils.unserialize(req.readAll())
232 if req.status then
233 return unpack({true});
234 else
235 return unpack({false, req.error});
236 end
237 elseif field == "email" then
238 local query = "cmd=modify&field=email&key="..textutils.urlEncode(tostring(self.Data.AuthKey)) .. "&new=" .. textutils.urlEncode(tostring(value))
239 local req = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
240 req = textutils.unserialize(req.readAll())
241 if req.status then
242 return unpack({true});
243 else
244 return unpack({false, req.error});
245 end
246 else
247 return false;
248 end
249 end;
250 GetStatistics = function( self )
251 local query = "cmd=get_stats&key="..textutils.urlEncode(tostring(self.Data.AuthKey))
252 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
253 req = textutils.unserialize(req.readAll())
254 if req.status then
255 return unpack({true, req.data});
256 else
257 return unpack({false, req.error});
258 end
259 end;
260 GetData = function( self )
261 local query = "cmd=get-data&key="..textutils.urlEncode(tostring(self.Data.AuthKey))
262 local req = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
263 req = textutils.unserialize(req.readAll())
264 if req.status then
265 return unpack({true, req.data});
266 else
267 return unpack({false, req.error});
268 end
269 end;
270 Validate = function( self )
271 if self.Data.AuthKey then
272 local query = "cmd=validate&authkey="..textutils.urlEncode(tostring(self.Data.AuthKey))
273 local res = http.post(Discover.Data.Urls.User, query, Discover.Data.Headers)
274 res = textutils.unserialize(res.readAll())
275 if res.status == true then
276 self.Data.CMessage = res.message
277 self.Data.LoggedIn = true;
278 return true
279 elseif res.status == false then
280 self.Data.ErrorMsg = res.error
281 return false
282 end
283 else
284 return false
285 end
286 end;
287 Logout = function( self )
288 local req = http.post(Discover.Data.Urls.User, "cmd=logout&authkey="..textutils.urlEncode(tostring(self.Data.AuthKey)))
289 req = textutils.unserialize(req.readAll())
290 if req.status then
291 self.Data.LoggedIn = false
292 self.Data.Username = nil
293 self.Data.Password = nil
294 self.Data.AuthKey = nil
295 self.Data.CMessage = req.message
296 return true
297 else
298 self.Data.ErrorMsg = req.error
299 return false
300 end
301 end;
302 };
303 Profiles = {
304 View = function( self, username )
305 if username then
306 local query = "cmd=profile-view&username=".. textutils.urlEncode(tostring(username))
307 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
308 local req = textutils.unserialize(req.readAll())
309 if req.status then
310 return unpack({true, req.data})
311 else
312 return unpack({false, "Could not find profile"})
313 end
314 else
315 return unpack({false, "Please give username as argument"})
316 end
317 end;
318 Edit = function( self, name, birthday, location, bio, website )
319 if name and birthday and location and bio and website then
320 local query = "cmd=profile-edit&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&name=" .. textutils.urlEncode(tostring(name)) .. "&birthday=" .. textutils.urlEncode(tostring(birthday)) .. "&location=" .. textutils.urlEncode(tostring(location)) .. "&bio=" .. textutils.urlEncode(tostring(bio)) .. "&website=" .. textutils.urlEncode(tostring(website))
321 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
322 local req = textutils.unserialize(req.readAll())
323 if req.status then
324 return unpack({true, "Profile edit was successful"})
325 else
326 return unpack({false, "Could not edit profile"})
327 end
328 else
329 return unpack({false, "Please give all arguments"})
330 end
331 end;
332 List = function( self )
333 local query = "cmd=profile-list";
334 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
335 local req = textutils.unserialize(req.readAll())
336 if req.status then
337 return unpack({true, req.data})
338 else
339 return unpack({false, "Could not list profiles"})
340 end
341 end;
342 };
343 Tickets = {
344 Create = function( self, title, message )
345 local query = "cmd=ticket-create&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&title=" .. textutils.urlEncode(tostring(title)) .. "&message=" .. textutils.urlEncode(tostring(message));
346 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
347 local req = textutils.unserialize(req.readAll())
348 if req.status then
349 return unpack({true, req.message})
350 else
351 return unpack({false, req.error})
352 end
353 end;
354 List = function( self )
355 local query = "cmd=ticket-list";
356 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
357 local req = textutils.unserialize(req.readAll())
358 if req.status then
359 return unpack({true, req.data})
360 else
361 return unpack({false, "Could not list tickets"})
362 end
363 end;
364 };
365 Chat = {
366 Send = function( self, ctype, cid, message, create, async )
367 if ctype == "global" then
368 if async then
369 local query = "cmd=chat-send&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=global&message=" .. textutils.urlEncode(tostring(cid));
370 http.request(Discover.Data.Urls.Store, query, Discover.Data.Header);
371 return true;
372 else
373 local query = "cmd=chat-send&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=global&message=" .. textutils.urlEncode(tostring(cid));
374 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
375 local req = textutils.unserialize(req.readAll())
376 if req.status then
377 return unpack({true, req.data})
378 else
379 return unpack({false, req.error})
380 end
381 end
382 elseif ctype == "group" then
383 if async then
384 local query = "";
385 if create then
386 query = "cmd=chat-send&create=true&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=group&cid=" .. textutils.urlEncode(tostring(cid)) .. "&message=" .. textutils.urlEncode(tostring(message));
387 else
388 query = "cmd=chat-send&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=group&cid=" .. textutils.urlEncode(tostring(cid)) .. "&message=" .. textutils.urlEncode(tostring(message));
389 end
390 http.request(Discover.Data.Urls.Store, query, Discover.Data.Header);
391 return true;
392 else
393 local query = "";
394 if create then
395 query = "cmd=chat-send&create=true&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=group&cid=" .. textutils.urlEncode(tostring(cid)) .. "&message=" .. textutils.urlEncode(tostring(message));
396 else
397 query = "cmd=chat-send&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=group&cid=" .. textutils.urlEncode(tostring(cid)) .. "&message=" .. textutils.urlEncode(tostring(message));
398 end
399 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
400 local req = textutils.unserialize(req.readAll())
401 if req.status then
402 return unpack({true, req.data})
403 else
404 return unpack({false, req.error})
405 end
406 end
407 end
408 end;
409 View = function( self, ctype, cid, async )
410 if ctype == "global" then
411 if not async then
412 local query = "cmd=chat-list&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=global";
413 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
414 local req = textutils.unserialize(req.readAll())
415 if req.status then
416 return unpack({true, req.data})
417 else
418 return unpack({false, req.error})
419 end
420 else
421 local query = "cmd=chat-list&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=global";
422 http.request(Discover.Data.Urls.Store, query, Discover.Data.Headers)
423 end
424 elseif ctype == "group" then
425 local query = "cmd=chat-list&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&ntype=group&cid=" .. textutils.urlEncode(tostring(cid));
426 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
427 local req = textutils.unserialize(req.readAll())
428 if req.status then
429 return unpack({true, req.data})
430 else
431 return unpack({false, req.error})
432 end
433 end
434 end;
435 List = function( self, ntype )
436 if ntype == "group" then
437 local query = "cmd=chat-list-groups&key=" .. textutils.urlEncode(tostring(Discover.User.Data.AuthKey));
438 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
439 local req = textutils.unserialize(req.readAll())
440 if req.status then
441 return unpack({true, req.data})
442 else
443 return unpack({false, req.error})
444 end
445 end
446 end;
447 Handle = function( self, data )
448 if data then
449 local data = textutils.unserialize(data)
450 if data.status then
451 return unpack({true, data.data});
452 else
453 return unpack({false, data.error});
454 end
455 end
456 end;
457 };
458 Forums = {
459 List = function( self, ltype )
460 -- Ltype is either 'global', 'categories', 'sub-categories'
461 --[[
462 So on list on global it should list all global categories
463 on a category it should list all sub-categories if it is a parent,
464 if not parent list all posts
465 Once in a post, list all comments and data, which will then be parsed by Lua in a markdown fashion for rendering on screen.
466 ]]
467 end;
468 Create = function( self )
469 -- type is category, sub-category or post
470 end;
471 Pin = function( self )
472 -- Allowing pinning for posts, categories or sub-categories
473 end;
474 Stats = function( self )
475 -- List all stats
476 end;
477 };
478 Apps = {
479 Upload = function( self, appname, appdesc, appvers, appcate, appstat, appdata, appraw )
480 if not appraw then
481 local f = fs.open(appdata, "r");
482 appdata = f.readAll();
483 f.close();
484 end
485 local query = "cmd=upload&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&name="..textutils.urlEncode(tostring(appname)).."&desc="..textutils.urlEncode(tostring(appdesc)).."&vers="..textutils.urlEncode(tostring(appvers)).."&cate="..textutils.urlEncode(tostring(appcate)).."&status="..textutils.urlEncode(tostring(appstat)).."&data="..textutils.urlEncode(tostring(appdata))
486 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
487 req = textutils.unserialize(req.readAll())
488 if req.status then
489 Discover.User.Data.CMessage = req.message
490 return true
491 else
492 Discover.User.Data.ErrorMsg = req.error
493 return false
494 end
495 end;
496 Update = function( self, appid, vers, stat, data )
497 if appid and vers and stat and data then
498 local query = "cmd=update&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&appid="..textutils.urlEncode(tostring(appid)).."&vers="..textutils.urlEncode(tostring(vers)).."&status="..textutils.urlEncode(tostring(stat)).."&data="..textutils.urlEncode(tostring(data))
499 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
500 req = textutils.unserialize(req.readAll())
501 if req.status then
502 Discover.User.Data.CMessage = tostring(req.message)
503 return true
504 else
505 Discover.User.Data.ErrorMsg = tostring(req.error)
506 return false
507 end
508 else
509 Discover.User.Data.ErrorMsg = "Please fill in all fields"
510 return false
511 end
512 end;
513 Edit = function( self, appid, name, desc, cate, stat )
514 if appid and name and desc and stat and cate then
515 local query = "cmd=edit&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&appid="..textutils.urlEncode(tostring(appid)).."&status="..textutils.urlEncode(tostring(stat)).."&name="..textutils.urlEncode(tostring(name)).."&desc="..textutils.urlEncode(tostring(desc)).."&category="..textutils.urlEncode(tostring(cate))
516 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
517 req = textutils.unserialize(req.readAll())
518 if req.status then
519 Discover.User.Data.CMessage = tostring(req.message)
520 return true
521 else
522 Discover.User.Data.ErrorMsg = req.error
523 return false
524 end
525 else
526 Discover.User.Data.ErrorMsg = "Please fill in all fields"
527 return false
528 end
529 end;
530 List = function( self, ListType )
531 -- ListType: apps/categories/versions/owned
532 if ListType == "owned" then
533 if not username then
534 query = "cmd=list_apps_user&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
535 else
536 query = "cmd=list_apps_user&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&username="..textutils.urlEncode(tostring(username))
537 end
538 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
539 req = textutils.unserialize(req.readAll())
540 if req.status then
541 return unpack({true, req.data})
542 else
543 Discover.User.Data.ErrorMsg = req.error
544 return false
545 end
546 elseif ListType == "apps" then
547 local ret = http.post(Discover.Data.Urls.Store, "cmd=list_apps", Discover.Data.Headers)
548 ret = textutils.unserialize(ret.readAll())
549 if ret.status == true then
550 return unpack({true, ret.data})
551 else
552 return false
553 end
554 elseif ListType == "categories" then
555 local ret = http.post(Discover.Data.Urls.Store, "cmd=list_categories", Discover.Data.Headers)
556 ret = textutils.unserialize(ret.readAll())
557 if ret.status == true then
558 return unpack({true, ret.data})
559 else
560 return false
561 end
562 elseif ListType == "versions" then
563 local ret = http.post(Discover.Data.Urls.Store, "cmd=list_versions", Discover.Data.Headers)
564 ret = textutils.unserialize(ret.readAll())
565 if ret.status == true then
566 return unpack({true, ret.data})
567 else
568 return false
569 end
570 elseif ListType == "packages" then
571 local ret = http.post(Discover.Data.Urls.Store, "cmd=list_packages", Discover.Data.Headers)
572 ret = textutils.unserialize(ret.readAll())
573 if ret.status == true then
574 return unpack({true, ret.data})
575 else
576 return false
577 end
578 elseif ListType == "downloads" then
579 local ret = http.post(Discover.Data.Urls.Store, "cmd=list_downloads", Discover.Data.Headers)
580 ret = textutils.unserialize(ret.readAll())
581 if ret.status == true then
582 return unpack({true, ret.data})
583 else
584 return false
585 end
586 end
587 end;
588 Download = function( self, appid, filename )
589 local query = "cmd=download&appid="..textutils.urlEncode(tostring(appid))
590 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
591 if fs.exists(filename) then
592 return unpack({false, "File already exists"})
593 else
594 local f = fs.open(filename, "w")
595 f.write(req.readAll())
596 f.close()
597 return true
598 end
599 end;
600 Delete = function( self, appid )
601 if appid then
602 local query = "cmd=delete&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&appid="..textutils.urlEncode(tostring(appid))
603 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
604 req = textutils.unserialize(req.readAll())
605 if req.status then
606 Discover.User.Data.CMessage = tostring(req.message)
607 return true
608 else
609 Discover.User.Data.ErrorMsg = req.error
610 return false
611 end
612 else
613 Discover.User.Data.ErrorMsg = "Please fill in all fields"
614 return false
615 end
616 end;
617 Comment = function( self, ListType, appid, comment )
618 if ListType == "add" then
619 local query = "cmd=add_comment&appid="..textutils.urlEncode(tostring(appid)).."&comment="..textutils.urlEncode(tostring(comment)).."&authkey="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
620 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
621 req = textutils.unserialize(req.readAll())
622 if req.status then
623 Discover.User.Data.CMessage = req.message
624 return true
625 else
626 Discover.User.Data.ErrorMsg = req.error
627 return false
628 end
629 elseif ListType == "list" then
630 local query = "cmd=view_comments&appid="..textutils.urlEncode(tostring(appid))
631 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
632 req = textutils.unserialize(req.readAll())
633 if req.status == true then
634 Discover.User.Data.CMessage = "Successful"
635 return unpack({true, req.data})
636 else
637 Discover.User.Data.ErrorMsg = req.error
638 return false
639 end
640 end
641 end;
642 };
643 Snippets = {
644 List = function( self, ListType)
645 --ListType: all/owned
646 if ListType == "all" then
647 local query = "cmd=snippets_view"
648 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
649 req = textutils.unserialize(req.readAll())
650 if req.status then
651 return unpack({true, req.data})
652 else
653 Discover.User.Data.ErrorMsg = req.error
654 return false
655 end
656 elseif ListType == "owned" then
657 local query = "cmd=snippets_list_user&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
658 local req = http.post(Discover.Data.Urls.Store, query)
659 req = textutils.unserialize(req.readAll())
660 if req.status then
661 return unpack({true, req.data})
662 else
663 Discover.User.Data.ErrorMsg = req.error
664 return false
665 end
666 end
667 end;
668 Upload = function( self, name, desc, vers, stat, path )
669 local f = fs.open(path, "r")
670 tdata = f.readAll()
671 f.close()
672 local query = "cmd=snippets_upload&auth="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&name="..textutils.urlEncode(tostring(name)).."&desc="..textutils.urlEncode(tostring(vers)).."&vers="..textutils.urlEncode(tostring(vers)).."&stat="..textutils.urlEncode(tostring(stat)).."&data="..textutils.urlEncode(tostring(tdata))
673 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
674 req = textutils.unserialize(req.readAll())
675 if req.status then
676 return true
677 else
678 Discover.User.Data.ErrorMsg = req.error
679 return false
680 end
681 end;
682 Download = function( self, snipid, filename )
683 local query = "cmd=snippets_download&id="..textutils.urlEncode(tostring(snipid))
684 local req = http.post(Discover.Data.Urls.Store, query, Discover.Dat)
685 req = req.readAll()
686 if fs.exists(filename) then
687 return unpack({false, "Could not download snippet"})
688 else
689 local f = fs.open(filename, "w")
690 f.write(req)
691 f.close()
692 return true
693 end
694 end;
695 Delete = function( self, id )
696 local query = "cmd=snippets_delete&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(Discover.User.Data.Authkey))
697 local req = http.post(self.data.urls.store, query)
698 req = textutils.unserialize(req.readAll())
699 if req.status then
700 self.data.cmessage = tostring(req.message)
701 return true
702 else
703 self.data.errormsg = req.error
704 return false
705 end
706 end;
707 };
708 Cloud = {
709 List = function( self )
710 local query = "cmd=cloud_get&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
711 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
712 req = textutils.unserialize(req.readAll())
713 if req.status then
714 return unpack({true, req.data})
715 else
716 return unpack({false, req.error})
717 end
718 end;
719 Delete = function( self, id )
720 local query = "cmd=cloud_delete&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
721 local req = http.post(Discover.Data.Urls.Store, query)
722 req = textutils.unserialize(req.readAll())
723 if req.status then
724 Discover.User.Data.CMessage = tostring(req.message)
725 return true
726 else
727 Discover.User.Data.ErrorMsg = req.error
728 return false
729 end
730 end;
731 Create = function( self, filepath )
732 if filepath then
733 if not fs.exists(filepath) then
734 Discover.User.Data.ErrorMsg = "File: "..filepath.." was not found"
735 return false
736 end
737 local filename = filepath
738 local f = fs.open(filepath, "r")
739 filedata = f.readAll()
740 f.close()
741 filedata = Discover.Crypto:Base64("encode", filedata)
742 local query = "cmd=cloud_upload&filename="..textutils.urlEncode(tostring(filename)).."&filedata="..textutils.urlEncode(tostring(filedata)).."&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
743 local req = http.post(Discover.Data.Urls.Store, query)
744 req = textutils.unserialize(req.readAll())
745 if req.status then
746 Discover.User.Data.CMessage = tostring(req.message)
747 return true
748 else
749 Discover.User.Data.ErrorMsg = req.error
750 return false
751 end
752 else
753 self.data.errormsg = "Please supply all fields"
754 return false
755 end
756 end;
757 Rename = function( self, id, name )
758 local query = "cmd=cloud_rename&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)).."&newname="..textutils.urlEncode(tostring(name))
759 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
760 req = textutils.unserialize(req.readAll())
761 if req.status then
762 Discover.User.Data.CMessage = tostring(req.message)
763 return true
764 else
765 Discover.User.Data.ErrorMsg = tostring(req.error)
766 return false
767 end
768 end;
769 Install = function( self, data )
770 if type(data) == "table" then
771 local f = fs.open(data.filename, "w")
772 f.write(Discover.Crypto:Base64("decode", data.filedata))
773 f.close()
774 return true
775 else
776 return unpack({false, "DAPI:CLOUD:INSTALL: Wrong format for table input"})
777 end
778 end;
779 };
780 Feed = {
781 Create = function( self, message )
782 local query = "cmd=feed_send&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&message=" .. textutils.urlEncode(tostring(message))
783 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
784 req = textutils.unserialize(req.readAll())
785 if req.status then
786 return true
787 else
788 Discover.User.Data.ErrorMsg = req.error;
789 return false
790 end
791 end;
792 List = function( self )
793 local query = "cmd=feed_view&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
794 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
795 req = textutils.unserialize(req.readAll())
796 if req.status then
797 return unpack({true, req.data})
798 else
799 return false
800 end
801 end;
802 };
803 Mail = {
804 Create = function( self, recipient, subject, message, attachments )
805 if attachments then
806 local f = fs.open(attachments, "r")
807 local d = f.readAll()
808 f.close()
809 attachments = d
810 end
811 local query = "cmd=mail_send&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&recipient=" ..textutils.urlEncode(tostring(recipient)) .. "&subject=" ..textutils.urlEncode(tostring(subject)) .. "&message=" ..textutils.urlEncode(tostring(message)) .. "&attachments=" ..textutils.urlEncode(tostring(attachments))
812 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
813 req = textutils.unserialize(req.readAll())
814 if req.status then
815 return true
816 else
817 return unpack({false, req.error})
818 end
819 end;
820 List = function( self, ListType )
821 if ListType == "inbox" then
822 local query = "cmd=mail_view_received&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
823 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
824 req = textutils.unserialize(req.readAll())
825 if req.status then
826 return unpack({true, req.data})
827 else
828 return false
829 end
830 elseif ListType == "sent" then
831 local query = "cmd=mail_view_sent&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
832 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
833 req = textutils.unserialize(req.readAll())
834 if req.status then
835 return unpack({true, req.data})
836 else
837 return false
838 end
839 end
840 end;
841 Read = function( self, mailid )
842 local query = "cmd=mail_view&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&id=" ..textutils.urlEncode(tostring(mailid))
843 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
844 req = textutils.unserialize(req.readAll())
845 if req.status then
846 return true
847 else
848 return false
849 end
850 return true;
851 end;
852 Delete = function( self, mailid )
853 local query = "cmd=mail_delete&key=" ..textutils.urlEncode(tostring(Discover.User.Data.AuthKey)) .. "&id=" ..textutils.urlEncode(tostring(mailid))
854 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
855 req = textutils.unserialize(req.readAll())
856 if req.status then
857 return true
858 else
859 return unpack({false, req.error})
860 end
861 end;
862 };
863 Notifications = {
864 List = function( self )
865 local query = "cmd=notifications_view&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
866 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
867 req = textutils.unserialize(req.readAll())
868 if req.status then
869 Discover.User.Data.CMessage = tostring(req.message)
870 return unpack({true, req.data})
871 else
872 self.data.errormsg = req.error
873 return false
874 end
875 end;
876 Delete = function( self, id )
877 if not id then
878 return false
879 end
880 local query = "cmd=notifications_delete&id="..textutils.urlEncode(tostring(id)).."&key="..textutils.urlEncode(tostring(Discover.User.Data.AuthKey))
881 local req = http.post(Discover.Data.Urls.Store, query, Discover.Data.Headers)
882 req = textutils.unserialize(req.readAll())
883 if req.status then
884 Discover.User.Data.CMessage = tostring(req.message)
885 return true
886 else
887 Discover.User.Data.ErrorMsg = req.error
888 return false
889 end
890 end;
891 };
892 Crypto = {
893 Base64 = function( self, encode, data )
894 function lsh(value,shift)
895 return (value*(2^shift)) % 256
896 end
897 function rsh(value,shift)
898 return math.floor(value/2^shift) % 256
899 end
900 function bit(x,b)
901 return (x % 2^b - x % 2^(b-1) > 0)
902 end
903 function lor(x,y)
904 result = 0
905 for p=1,8 do result = result + (((bit(x,p) or bit(y,p)) == true) and 2^(p-1) or 0) end
906 return result
907 end
908 local base64chars = {[0]='A',[1]='B',[2]='C',[3]='D',[4]='E',[5]='F',[6]='G',[7]='H',[8]='I',[9]='J',[10]='K',[11]='L',[12]='M',[13]='N',[14]='O',[15]='P',[16]='Q',[17]='R',[18]='S',[19]='T',[20]='U',[21]='V',[22]='W',[23]='X',[24]='Y',[25]='Z',[26]='a',[27]='b',[28]='c',[29]='d',[30]='e',[31]='f',[32]='g',[33]='h',[34]='i',[35]='j',[36]='k',[37]='l',[38]='m',[39]='n',[40]='o',[41]='p',[42]='q',[43]='r',[44]='s',[45]='t',[46]='u',[47]='v',[48]='w',[49]='x',[50]='y',[51]='z',[52]='0',[53]='1',[54]='2',[55]='3',[56]='4',[57]='5',[58]='6',[59]='7',[60]='8',[61]='9',[62]='-',[63]='_'}
909 local base64bytes = {['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,['J']=9,['K']=10,['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['-']=62,['_']=63,['=']=nil}
910 if encode == "encode" then
911 function encode(data)
912 local bytes = {}
913 local result = ""
914 for spos=0,string.len(data)-1,3 do
915 for byte=1,3 do bytes[byte] = string.byte(string.sub(data,(spos+byte))) or 0 end
916 result = string.format('%s%s%s%s%s',result,base64chars[rsh(bytes[1],2)],base64chars[lor(lsh((bytes[1] % 4),4), rsh(bytes[2],4))] or "=",((#data-spos) > 1) and base64chars[lor(lsh(bytes[2] % 16,2), rsh(bytes[3],6))] or "=",((#data-spos) > 2) and base64chars[(bytes[3] % 64)] or "=")
917 end
918 return result
919 end
920 return encode(data)
921 elseif encode == "decode" then
922 function decode(data)
923 local chars = {}
924 local result=""
925 for dpos=0,string.len(data)-1,4 do
926 for char=1,4 do chars[char] = base64bytes[(string.sub(data,(dpos+char),(dpos+char)) or "=")] end
927 result = string.format('%s%s%s%s',result,string.char(lor(lsh(chars[1],2), rsh(chars[2],4))),(chars[3] ~= nil) and string.char(lor(lsh(chars[2],4), rsh(chars[3],2))) or "",(chars[4] ~= nil) and string.char(lor(lsh(chars[3],6) % 192, (chars[4]))) or "")
928 end
929 return result
930 end
931 return decode(data)
932 end
933 end;
934 Sha256 = function( self, msg )
935 local MOD = 2^32
936 local MODM = MOD-1
937 local function memoize(f)
938 local mt = {}
939 local t = setmetatable({}, mt)
940 function mt:__index(k)
941 local v = f(k)
942 t[k] = v
943 return v
944 end
945 return t
946 end
947 local function make_bitop_uncached(t, m)
948 local function bitop(a, b)
949 local res,p = 0,1
950 while a ~= 0 and b ~= 0 do
951 local am, bm = a % m, b % m
952 res = res + t[am][bm] * p
953 a = (a - am) / m
954 b = (b - bm) / m
955 p = p*m
956 end
957 res = res + (a + b) * p
958 return res
959 end
960 return bitop
961 end
962 local function make_bitop(t)
963 local op1 = make_bitop_uncached(t,2^1)
964 local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
965 return make_bitop_uncached(op2, 2 ^ (t.n or 1))
966 end
967 local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
968 local function bxor(a, b, c, ...)
969 local z = nil
970 if b then
971 a = a % MOD
972 b = b % MOD
973 z = bxor1(a, b)
974 if c then z = bxor(z, c, ...) end
975 return z
976 elseif a then return a % MOD
977 else return 0 end
978 end
979 local function band(a, b, c, ...)
980 local z
981 if b then
982 a = a % MOD
983 b = b % MOD
984 z = ((a + b) - bxor1(a,b)) / 2
985 if c then z = bit32_band(z, c, ...) end
986 return z
987 elseif a then return a % MOD
988 else return MODM end
989 end
990 local function bnot(x) return (-1 - x) % MOD end
991 local function rshift1(a, disp)
992 if disp < 0 then return lshift(a,-disp) end
993 return math.floor(a % 2 ^ 32 / 2 ^ disp)
994 end
995 local function rshift(x, disp)
996 if disp > 31 or disp < -31 then return 0 end
997 return rshift1(x % MOD, disp)
998 end
999 local function lshift(a, disp)
1000 if disp < 0 then return rshift(a,-disp) end
1001 return (a * 2 ^ disp) % 2 ^ 32
1002 end
1003 local function rrotate(x, disp)
1004 x = x % MOD
1005 disp = disp % 32
1006 local low = band(x, 2 ^ disp - 1)
1007 return rshift(x, disp) + lshift(low, 32 - disp)
1008 end
1009 local k = {
1010 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
1011 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1012 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
1013 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
1014 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
1015 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
1016 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
1017 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
1018 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
1019 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
1020 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
1021 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
1022 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
1023 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
1024 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
1025 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
1026 }
1027 local function str2hexa(s)
1028 return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
1029 end
1030 local function num2s(l, n)
1031 local s = ""
1032 for i = 1, n do
1033 local rem = l % 256
1034 s = string.char(rem) .. s
1035 l = (l - rem) / 256
1036 end
1037 return s
1038 end
1039 local function s232num(s, i)
1040 local n = 0
1041 for i = i, i + 3 do n = n*256 + string.byte(s, i) end
1042 return n
1043 end
1044 local function preproc(msg, len)
1045 local extra = 64 - ((len + 9) % 64)
1046 len = num2s(8 * len, 8)
1047 msg = msg .. "\128" .. string.rep("\0", extra) .. len
1048 assert(#msg % 64 == 0)
1049 return msg
1050 end
1051 local function initH256(H)
1052 H[1] = 0x6a09e667
1053 H[2] = 0xbb67ae85
1054 H[3] = 0x3c6ef372
1055 H[4] = 0xa54ff53a
1056 H[5] = 0x510e527f
1057 H[6] = 0x9b05688c
1058 H[7] = 0x1f83d9ab
1059 H[8] = 0x5be0cd19
1060 return H
1061 end
1062 local function digestblock(msg, i, H)
1063 local w = {}
1064 for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
1065 for j = 17, 64 do
1066 local v = w[j - 15]
1067 local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
1068 v = w[j - 2]
1069 w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
1070 end
1071 local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
1072 for i = 1, 64 do
1073 local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
1074 local maj = bxor(band(a, b), band(a, c), band(b, c))
1075 local t2 = s0 + maj
1076 local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
1077 local ch = bxor (band(e, f), band(bnot(e), g))
1078 local t1 = h + s1 + ch + k[i] + w[i]
1079 h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
1080 end
1081 H[1] = band(H[1] + a)
1082 H[2] = band(H[2] + b)
1083 H[3] = band(H[3] + c)
1084 H[4] = band(H[4] + d)
1085 H[5] = band(H[5] + e)
1086 H[6] = band(H[6] + f)
1087 H[7] = band(H[7] + g)
1088 H[8] = band(H[8] + h)
1089 end
1090 function sha256(msg)
1091 msg = preproc(msg, #msg)
1092 local H = initH256({})
1093 for i = 1, #msg, 64 do digestblock(msg, i, H) end
1094 return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
1095 num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
1096 end
1097 return sha256(msg);
1098 end;
1099 };
1100}