From e2abf5f046f46aca4c48d880c2453378013c5367 Mon Sep 17 00:00:00 2001 From: Arinerron Date: Sat, 4 Aug 2018 21:09:33 -0700 Subject: [PATCH] Onionr UI updates --- onionr/onionr.py | 11 +- .../www/ui/common/onionr-timeline-post.html | 4 +- onionr/static-data/www/ui/compile.py | 75 +++--- onionr/static-data/www/ui/dist/index.html | 2 +- onionr/static-data/www/ui/dist/js/main.js | 248 ++++++++++++++++-- onionr/static-data/www/ui/dist/js/timeline.js | 106 ++------ onionr/static-data/www/ui/lang.json | 31 ++- onionr/static-data/www/ui/src/js/main.js | 244 ++++++++++++++++- onionr/static-data/www/ui/src/js/timeline.js | 106 ++------ 9 files changed, 575 insertions(+), 252 deletions(-) diff --git a/onionr/onionr.py b/onionr/onionr.py index 278ba60d..4d7f8b27 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -201,7 +201,14 @@ class Onionr: 'ui' : self.openUI, 'gui' : self.openUI, - 'getpassword': self.printWebPassword + 'getpassword': self.printWebPassword, + 'get-password': self.printWebPassword, + 'getpwd': self.printWebPassword, + 'get-pwd': self.printWebPassword, + 'getpass': self.printWebPassword, + 'get-pass': self.printWebPassword, + 'getpasswd': self.printWebPassword, + 'get-passwd': self.printWebPassword } self.cmdhelp = { @@ -211,7 +218,7 @@ class Onionr: 'start': 'Starts the Onionr daemon', 'stop': 'Stops the Onionr daemon', 'stats': 'Displays node statistics', - 'getpassword': 'Displays the web password', + 'get-password': 'Displays the web password', 'enable-plugin': 'Enables and starts a plugin', 'disable-plugin': 'Disables and stops a plugin', 'reload-plugin': 'Reloads a plugin', diff --git a/onionr/static-data/www/ui/common/onionr-timeline-post.html b/onionr/static-data/www/ui/common/onionr-timeline-post.html index 8e187b51..68440a01 100644 --- a/onionr/static-data/www/ui/common/onionr-timeline-post.html +++ b/onionr/static-data/www/ui/common/onionr-timeline-post.html @@ -22,8 +22,8 @@
- like - comment + <$= LANG.POST_LIKE $> + <$= LANG.POST_REPLY $>
diff --git a/onionr/static-data/www/ui/compile.py b/onionr/static-data/www/ui/compile.py index c93e4aa7..2667b210 100755 --- a/onionr/static-data/www/ui/compile.py +++ b/onionr/static-data/www/ui/compile.py @@ -40,53 +40,60 @@ with open('lang.json', 'r') as file: LANG = type('LANG', (), langmap) # templating -def jsTemplate(template): - with open('common/%s.html' % template, 'r') as file: - return file.read().replace('\\', '\\\\').replace('\'', '\\\'').replace('\n', "\\\n") +class Template: + def jsTemplate(template): + with open('common/%s.html' % template, 'r') as file: + return Template.parseTags(file.read().replace('\\', '\\\\').replace('\'', '\\\'').replace('\n', "\\\n")) -def htmlTemplate(template): - with open('common/%s.html' % template, 'r') as file: - return file.read() + def htmlTemplate(template): + with open('common/%s.html' % template, 'r') as file: + return Template.parseTags(file.read()) -# tag parser -def parseTags(contents): - # <$ logic $> - for match in re.findall(r'(<\$(?!=)(.*?)\$>)', contents): - try: - out = exec(match[1].strip()) - contents = contents.replace(match[0], '' if out is None else str(out)) - except Exception as e: - print('Error: Failed to execute python tag (%s): %s\n' % (filename, match[1])) - traceback.print_exc() - print('\nIgnoring this error, continuing to compile...\n') + # tag parser + def parseTags(contents): + # <$ logic $> + for match in re.findall(r'(<\$(?!=)(.*?)\$>)', contents): + try: + out = exec(match[1].strip()) + contents = contents.replace(match[0], '' if out is None else str(out)) + except Exception as e: + print('Error: Failed to execute python tag (%s): %s\n' % (filename, match[1])) + traceback.print_exc() + print('\nIgnoring this error, continuing to compile...\n') - # <$= data $> - for match in re.findall(r'(<\$=(.*?)\$>)', contents): - try: - out = eval(match[1].strip()) - contents = contents.replace(match[0], '' if out is None else str(out)) - except NameError as e: - name = match[1].strip() - print('Warning: %s does not exist, treating as an str' % name) - contents = contents.replace(match[0], name) - except Exception as e: - print('Error: Failed to execute python tag (%s): %s\n' % (filename, match[1])) - traceback.print_exc() - print('\nIgnoring this error, continuing to compile...\n') + # <$= data $> + for match in re.findall(r'(<\$=(.*?)\$>)', contents): + try: + out = eval(match[1].strip()) + contents = contents.replace(match[0], '' if out is None else str(out)) + except NameError as e: + name = match[1].strip() + print('Warning: %s does not exist, treating as an str' % name) + contents = contents.replace(match[0], name) + except Exception as e: + print('Error: Failed to execute python tag (%s): %s\n' % (filename, match[1])) + traceback.print_exc() + print('\nIgnoring this error, continuing to compile...\n') - return contents + return contents + +def jsTemplate(contents): + return Template.jsTemplate(contents) + +def htmlTemplate(contents): + return Template.htmlTemplate(contents) # get header file with open(HEADER_FILE, 'r') as file: HEADER_FILE = file.read() if settings['python_tags']: - HEADER_FILE = parseTags(HEADER_FILE) + HEADER_FILE = Template.parseTags(HEADER_FILE) # get footer file with open(FOOTER_FILE, 'r') as file: FOOTER_FILE = file.read() if settings['python_tags']: - FOOTER_FILE = parseTags(FOOTER_FILE) + FOOTER_FILE = Template.parseTags(FOOTER_FILE) # iterate dst, replace files def iterate(directory): @@ -111,7 +118,7 @@ def iterate(directory): # do python tags if settings['python_tags']: - contents = parseTags(contents) + contents = Template.parseTags(contents) # write file file.write(contents) diff --git a/onionr/static-data/www/ui/dist/index.html b/onionr/static-data/www/ui/dist/index.html index 25cbb63b..6efaac1b 100644 --- a/onionr/static-data/www/ui/dist/index.html +++ b/onionr/static-data/www/ui/dist/index.html @@ -49,7 +49,7 @@ -
+
diff --git a/onionr/static-data/www/ui/dist/js/main.js b/onionr/static-data/www/ui/dist/js/main.js index 1577beb2..75cb7f81 100644 --- a/onionr/static-data/www/ui/dist/js/main.js +++ b/onionr/static-data/www/ui/dist/js/main.js @@ -95,14 +95,34 @@ String.prototype.replaceAll = function(search, replacement) { return target.split(search).join(replacement); }; -/* sanitizes HTML in a string */ -function encodeHTML(html) { - return String(html).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +/* useful functions to sanitize data */ +class Sanitize { + /* sanitizes HTML in a string */ + static html(html) { + return String(html).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); + } + + /* URL encodes a string */ + static url(url) { + return encodeURIComponent(url); + } } -/* URL encodes a string */ -function encodeURL(url) { - return encodeURIComponent(url); +/* config stuff */ +function getWebPassword() { + return get("web-password", null); +} + +function setWebPassword(password) { + return set("web-password", password); +} + +function getTimingToken() { + return get("timing-token", null); +} + +function setTimingToken(token) { + return set("timing-token", token); } /* user class */ @@ -179,8 +199,8 @@ class Post {
\ \
\ - like\ - comment\ + like\ + reply\
\
\ \ @@ -191,13 +211,16 @@ class Post { var device = (jQuery(document).width() < 768 ? 'mobile' : 'desktop'); - postTemplate = postTemplate.replaceAll('$user-name-url', encodeHTML(encodeURL(this.getUser().getName()))); - postTemplate = postTemplate.replaceAll('$user-name', encodeHTML(this.getUser().getName())); - postTemplate = postTemplate.replaceAll('$user-id-url', encodeHTML(encodeURL(this.getUser().getID()))); - postTemplate = postTemplate.replaceAll('$user-id-truncated', encodeHTML(this.getUser().getID().split('-').slice(0, 4).join('-'))); - postTemplate = postTemplate.replaceAll('$user-id', encodeHTML(this.getUser().getID())); - postTemplate = postTemplate.replaceAll('$user-image', encodeHTML(this.getUser().getIcon())); - postTemplate = postTemplate.replaceAll('$content', encodeHTML(this.getContent())); + postTemplate = postTemplate.replaceAll('$user-name-url', Sanitize.html(Sanitize.url(this.getUser().getName()))); + postTemplate = postTemplate.replaceAll('$user-name', Sanitize.html(this.getUser().getName())); + postTemplate = postTemplate.replaceAll('$user-id-url', Sanitize.html(Sanitize.url(this.getUser().getID()))); + + postTemplate = postTemplate.replaceAll('$user-id-truncated', Sanitize.html(this.getUser().getID().substring(0, 12) + '...')); + // postTemplate = postTemplate.replaceAll('$user-id-truncated', Sanitize.html(this.getUser().getID().split('-').slice(0, 4).join('-'))); + + postTemplate = postTemplate.replaceAll('$user-id', Sanitize.html(this.getUser().getID())); + postTemplate = postTemplate.replaceAll('$user-image', Sanitize.html(this.getUser().getIcon())); + postTemplate = postTemplate.replaceAll('$content', Sanitize.html(this.getContent())); postTemplate = postTemplate.replaceAll('$date-relative', timeSince(this.getPostDate(), device) + (device === 'desktop' ? ' ago' : '')); postTemplate = postTemplate.replaceAll('$date', this.getPostDate().toLocaleString()); @@ -231,3 +254,198 @@ class Post { return this.date; } } + +/* block class */ +class Block { + constructor(type, content) { + this.type = type; + this.content = content; + } + + // returns the block hash, if any + getHash() { + return this.hash; + } + + // returns the block type + getType() { + return this.type; + } + + // returns the block header + getHeader(key, df) { // df is default + if(key !== undefined) { + if(this.getHeader().hasOwnProperty(key)) + return this.getHeader()[key]; + else + return (df === undefined ? null : df); + } else + return this.header; + } + + // returns the block metadata + getMetadata(key, df) { // df is default + if(key !== undefined) { + if(this.getMetadata().hasOwnProperty(key)) + return this.getMetadata()[key]; + else + return (df === undefined ? null : df); + } else + return this.metadata; + } + + // returns the block content + getContent() { + return this.content; + } + + // returns the parent block's hash (not Block object, for performance) + getParent() { + if(!(this.parent instanceof Block) && this.parent !== undefined && this.parent !== null) + this.parent = Block.openBlock(this.parent); // convert hash to Block object + return this.parent; + } + + // returns the date that the block was received + getDate() { + return this.date; + } + + // returns a boolean that indicates whether or not the block is valid + isValid() { + return this.valid; + } + + // returns a boolean thati ndicates whether or not the block is signed + isSigned() { + return this.signed; + } + + // returns the block signature + getSignature() { + return this.signature; + } + + // returns the block type + setType(type) { + this.type = type; + return this; + } + + // sets block metadata by key + setMetadata(key, val) { + this.metadata[key] = val; + return this; + } + + // sets block content + setContent(content) { + this.content = content; + return this; + } + + // sets the block parent by hash or Block object + setParent(parent) { + this.parent = parent; + return this; + } + + // indicates if the Block exists or not + exists() { + return !(this.hash === null || this.hash === undefined); + } + + /* static functions */ + + // recreates a block by hash + static openBlock(hash) { + return parseBlock(response); + } + + // converts an associative array to a Block + static parseBlock(val) { + var block = new Block(); + + block.type = val['type']; + block.content = val['content']; + block.header = val['header']; + block.metadata = val['metadata']; + block.date = new Date(val['date'] * 1000); + block.hash = val['hash']; + block.signature = val['signature']; + block.signed = val['signed']; + block.valid = val['valid']; + block.parent = val['parent']; + + if(block.getParent() !== null) { + // if the block data is already in the associative array + + /* + if (blocks.hasOwnProperty(block.getParent())) + block.setParent(Block.parseAssociativeArray({blocks[block.getParent()]})[0]); + */ + } + + return block; + } + + // converts an array of associative arrays to an array of Blocks + static parseBlockArray(blocks) { + var outputBlocks = []; + + for(var key in blocks) { + if(blocks.hasOwnProperty(key)) { + var val = blocks[key]; + + var block = Block.parseBlock(val); + + outputBlocks.push(block); + } + } + + return outputBlocks; + } + + static getBlocks(args, callback) { // callback is optional + args = args || {} + + var url = '/client/?action=searchBlocks&data=' + Sanitize.url(JSON.stringify(args)) + '&token=' + Sanitize.url(getWebPassword()) + '&timingToken=' + Sanitize.url(getTimingToken()); + + console.log(url); + + var http = new XMLHttpRequest(); + + if(callback !== undefined) { + // async + + http.addEventListener('load', function() { + callback(Block.parseBlockArray(JSON.parse(http.responseText)['blocks'])); + }, false); + + http.open('GET', url, true); + http.timeout = 5000; + http.send(null); + } else { + // sync + + http.open('GET', url, false); + http.send(null); + + return Block.parseBlockArray(JSON.parse(http.responseText)['blocks']); + } + } +} + +/* temporary code */ + +if(getWebPassword() === null) { + var password = ""; + while(password.length != 64) { + password = prompt("Please enter the web password (run `./RUN-LINUX.sh --get-password`)"); + } + + setTimingToken(prompt("Please enter the timing token (optional)")); + + setWebPassword(password); + window.location.reload(true); +} diff --git a/onionr/static-data/www/ui/dist/js/timeline.js b/onionr/static-data/www/ui/dist/js/timeline.js index c03ee24e..c09525e7 100644 --- a/onionr/static-data/www/ui/dist/js/timeline.js +++ b/onionr/static-data/www/ui/dist/js/timeline.js @@ -1,95 +1,27 @@ -/* write a random post to the page, for testing */ -var verbs = -[ - ["go to", "goes to", "going to", "went to", "gone to"], - ["look at", "looks at", "looking at", "looked at", "looked at"], - ["choose", "chooses", "choosing", "chose", "chosen"], - ["torrent", "downloads", "downloading", "torrented", "downloaded"], - ["detonate", "detonates", "detonating", "detonated", "detonated"], - ["run", "runs", "running", "ran", "running"], - ["program", "programs", "programming", "coded", "programmed"], - ["start", "starts", "starting", "started", "started"] -]; -var tenses = -[ - {name:"Present", singular:1, plural:0, format:"%subject %verb %complement"}, - {name:"Present", singular:1, plural:0, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement lol"}, - {name:"Past", singular:3, plural:3, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement lol"}, - {name:"Past", singular:3, plural:3, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement lol"}, - {name:"Present Continues", singular:2, plural:2, format:"%subject %be %verb %complement"} -]; -var subjects = -[ - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"My cat", be:"is", singular:0}, - {name:"My cat", be:"is", singular:0}, - {name:"My dog", be:"is", singular:0}, - {name:"My dog", be:"is", singular:0}, - {name:"My mom", be:"is", singular:0}, - {name:"My dad", be:"is", singular:0}, - {name:"You", be:"are", singular:0}, - {name:"He", be:"is", singular:1} -]; -var complementsForVerbs = -[ - ["cinema", "Egypt", "home", "concert"], - ["for a map", "them", "the stars", "the lake"], - ["a book for reading", "a dvd for tonight"], - ["the virus", "the malware", "that 0day", "Onionr"], - ["a bomb", "a nuke", "some C4", "some ammonium nitrate"], - ["the race", "towards someone", "to the stars", "on top of your roof"], - ["Onionr", "the malware", "some software", "Onionr"], - ["Onionr", "Onionr", "the race", "the timer"], -] +/* just for testing rn */ +Block.getBlocks({'type' : 'onionr-post', 'signed' : true, 'reverse' : true}, function(data) { + for(var i = 0; i < data.length; i++) { + try { + var block = data[i]; -Array.prototype.random = function(){return this[Math.floor(Math.random() * this.length)];}; + var post = new Post(); + var user = new User(); -function generate(){ - var index = Math.floor(verbs.length * Math.random()); - var tense = tenses.random(); - var subject = subjects.random(); - var verb = verbs[index]; - var complement = complementsForVerbs[index]; - var str = tense.format; - str = str.replace("%subject", subject.name).replace("%be", subject.be); - str = str.replace("%verb", verb[subject.singular ? tense.singular : tense.plural]); - str = str.replace("%complement", complement.random()); - return str; -} + var blockContent = JSON.parse(block.getContent()); -var curDate = new Date() -function addRandomPost() { - var post = new Post(); - var user = new User(); - var items = ['arinerron', 'beardog108', 'samyk', 'snowden', 'aaronswartz']; - user.setName(items[Math.floor(Math.random()*items.length)]); - user.setID('i-eat-waffles-often-its-actually-crazy-like-i-dont-know-wow'); - post.setContent(generate()); - post.setUser(user); + user.setName('unknown'); + user.setID(new String(block.getHeader('signer', 'unknown'))); + post.setContent(blockContent['content']); + post.setPostDate(block.getDate()); + post.setUser(user); - curDate = new Date(curDate - (Math.random() * 1000000)); - post.setPostDate(curDate); - - document.getElementById('onionr-timeline-posts').innerHTML += post.getHTML(); -} - -for(var i = 0; i < Math.round(50 * Math.random()); i++) - addRandomPost(); + document.getElementById('onionr-timeline-posts').innerHTML += post.getHTML(); + } catch(e) { + console.log(e); + } + } +}); function viewProfile(id, name) { document.getElementById("onionr-profile-username").innerHTML = encodeHTML(decodeURIComponent(name)); diff --git a/onionr/static-data/www/ui/lang.json b/onionr/static-data/www/ui/lang.json index 49bde688..28606a56 100644 --- a/onionr/static-data/www/ui/lang.json +++ b/onionr/static-data/www/ui/lang.json @@ -1,31 +1,40 @@ { "eng" : { "ONIONR_TITLE" : "Onionr UI", - + "TIMELINE" : "Timeline", "NOTIFICATIONS" : "Notifications", "MESSAGES" : "Messages", - - "TRENDING" : "Trending" + + "TRENDING" : "Trending", + + "POST_LIKE" : "like", + "POST_REPLY" : "reply" }, - + "spa" : { "ONIONR_TITLE" : "Onionr UI", - + "TIMELINE" : "Linea de Tiempo", "NOTIFICATIONS" : "Notificaciones", "MESSAGES" : "Mensaje", - - "TRENDING" : "Trending" + + "TRENDING" : "Trending", + + "POST_LIKE" : "me gusta", + "POST_REPLY" : "comentario" }, - + "zho" : { "ONIONR_TITLE" : "洋葱 用户界面", - + "TIMELINE" : "时间线", "NOTIFICATIONS" : "通知", "MESSAGES" : "消息", - - "TRENDING" : "趋势" + + "TRENDING" : "趋势", + + "POST_LIKE" : "喜欢", + "POST_REPLY" : "回复" } } diff --git a/onionr/static-data/www/ui/src/js/main.js b/onionr/static-data/www/ui/src/js/main.js index da969094..a99c187b 100644 --- a/onionr/static-data/www/ui/src/js/main.js +++ b/onionr/static-data/www/ui/src/js/main.js @@ -95,14 +95,34 @@ String.prototype.replaceAll = function(search, replacement) { return target.split(search).join(replacement); }; -/* sanitizes HTML in a string */ -function encodeHTML(html) { - return String(html).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +/* useful functions to sanitize data */ +class Sanitize { + /* sanitizes HTML in a string */ + static html(html) { + return String(html).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); + } + + /* URL encodes a string */ + static url(url) { + return encodeURIComponent(url); + } } -/* URL encodes a string */ -function encodeURL(url) { - return encodeURIComponent(url); +/* config stuff */ +function getWebPassword() { + return get("web-password", null); +} + +function setWebPassword(password) { + return set("web-password", password); +} + +function getTimingToken() { + return get("timing-token", null); +} + +function setTimingToken(token) { + return set("timing-token", token); } /* user class */ @@ -159,13 +179,16 @@ class Post { var device = (jQuery(document).width() < 768 ? 'mobile' : 'desktop'); - postTemplate = postTemplate.replaceAll('$user-name-url', encodeHTML(encodeURL(this.getUser().getName()))); - postTemplate = postTemplate.replaceAll('$user-name', encodeHTML(this.getUser().getName())); - postTemplate = postTemplate.replaceAll('$user-id-url', encodeHTML(encodeURL(this.getUser().getID()))); - postTemplate = postTemplate.replaceAll('$user-id-truncated', encodeHTML(this.getUser().getID().split('-').slice(0, 4).join('-'))); - postTemplate = postTemplate.replaceAll('$user-id', encodeHTML(this.getUser().getID())); - postTemplate = postTemplate.replaceAll('$user-image', encodeHTML(this.getUser().getIcon())); - postTemplate = postTemplate.replaceAll('$content', encodeHTML(this.getContent())); + postTemplate = postTemplate.replaceAll('$user-name-url', Sanitize.html(Sanitize.url(this.getUser().getName()))); + postTemplate = postTemplate.replaceAll('$user-name', Sanitize.html(this.getUser().getName())); + postTemplate = postTemplate.replaceAll('$user-id-url', Sanitize.html(Sanitize.url(this.getUser().getID()))); + + postTemplate = postTemplate.replaceAll('$user-id-truncated', Sanitize.html(this.getUser().getID().substring(0, 12) + '...')); + // postTemplate = postTemplate.replaceAll('$user-id-truncated', Sanitize.html(this.getUser().getID().split('-').slice(0, 4).join('-'))); + + postTemplate = postTemplate.replaceAll('$user-id', Sanitize.html(this.getUser().getID())); + postTemplate = postTemplate.replaceAll('$user-image', Sanitize.html(this.getUser().getIcon())); + postTemplate = postTemplate.replaceAll('$content', Sanitize.html(this.getContent())); postTemplate = postTemplate.replaceAll('$date-relative', timeSince(this.getPostDate(), device) + (device === 'desktop' ? ' ago' : '')); postTemplate = postTemplate.replaceAll('$date', this.getPostDate().toLocaleString()); @@ -199,3 +222,198 @@ class Post { return this.date; } } + +/* block class */ +class Block { + constructor(type, content) { + this.type = type; + this.content = content; + } + + // returns the block hash, if any + getHash() { + return this.hash; + } + + // returns the block type + getType() { + return this.type; + } + + // returns the block header + getHeader(key, df) { // df is default + if(key !== undefined) { + if(this.getHeader().hasOwnProperty(key)) + return this.getHeader()[key]; + else + return (df === undefined ? null : df); + } else + return this.header; + } + + // returns the block metadata + getMetadata(key, df) { // df is default + if(key !== undefined) { + if(this.getMetadata().hasOwnProperty(key)) + return this.getMetadata()[key]; + else + return (df === undefined ? null : df); + } else + return this.metadata; + } + + // returns the block content + getContent() { + return this.content; + } + + // returns the parent block's hash (not Block object, for performance) + getParent() { + if(!(this.parent instanceof Block) && this.parent !== undefined && this.parent !== null) + this.parent = Block.openBlock(this.parent); // convert hash to Block object + return this.parent; + } + + // returns the date that the block was received + getDate() { + return this.date; + } + + // returns a boolean that indicates whether or not the block is valid + isValid() { + return this.valid; + } + + // returns a boolean thati ndicates whether or not the block is signed + isSigned() { + return this.signed; + } + + // returns the block signature + getSignature() { + return this.signature; + } + + // returns the block type + setType(type) { + this.type = type; + return this; + } + + // sets block metadata by key + setMetadata(key, val) { + this.metadata[key] = val; + return this; + } + + // sets block content + setContent(content) { + this.content = content; + return this; + } + + // sets the block parent by hash or Block object + setParent(parent) { + this.parent = parent; + return this; + } + + // indicates if the Block exists or not + exists() { + return !(this.hash === null || this.hash === undefined); + } + + /* static functions */ + + // recreates a block by hash + static openBlock(hash) { + return parseBlock(response); + } + + // converts an associative array to a Block + static parseBlock(val) { + var block = new Block(); + + block.type = val['type']; + block.content = val['content']; + block.header = val['header']; + block.metadata = val['metadata']; + block.date = new Date(val['date'] * 1000); + block.hash = val['hash']; + block.signature = val['signature']; + block.signed = val['signed']; + block.valid = val['valid']; + block.parent = val['parent']; + + if(block.getParent() !== null) { + // if the block data is already in the associative array + + /* + if (blocks.hasOwnProperty(block.getParent())) + block.setParent(Block.parseAssociativeArray({blocks[block.getParent()]})[0]); + */ + } + + return block; + } + + // converts an array of associative arrays to an array of Blocks + static parseBlockArray(blocks) { + var outputBlocks = []; + + for(var key in blocks) { + if(blocks.hasOwnProperty(key)) { + var val = blocks[key]; + + var block = Block.parseBlock(val); + + outputBlocks.push(block); + } + } + + return outputBlocks; + } + + static getBlocks(args, callback) { // callback is optional + args = args || {} + + var url = '/client/?action=searchBlocks&data=' + Sanitize.url(JSON.stringify(args)) + '&token=' + Sanitize.url(getWebPassword()) + '&timingToken=' + Sanitize.url(getTimingToken()); + + console.log(url); + + var http = new XMLHttpRequest(); + + if(callback !== undefined) { + // async + + http.addEventListener('load', function() { + callback(Block.parseBlockArray(JSON.parse(http.responseText)['blocks'])); + }, false); + + http.open('GET', url, true); + http.timeout = 5000; + http.send(null); + } else { + // sync + + http.open('GET', url, false); + http.send(null); + + return Block.parseBlockArray(JSON.parse(http.responseText)['blocks']); + } + } +} + +/* temporary code */ + +if(getWebPassword() === null) { + var password = ""; + while(password.length != 64) { + password = prompt("Please enter the web password (run `./RUN-LINUX.sh --get-password`)"); + } + + setTimingToken(prompt("Please enter the timing token (optional)")); + + setWebPassword(password); + window.location.reload(true); +} diff --git a/onionr/static-data/www/ui/src/js/timeline.js b/onionr/static-data/www/ui/src/js/timeline.js index 6acd819d..c09525e7 100644 --- a/onionr/static-data/www/ui/src/js/timeline.js +++ b/onionr/static-data/www/ui/src/js/timeline.js @@ -1,95 +1,27 @@ -/* write a random post to the page, for testing */ -var verbs = -[ - ["go to", "goes to", "going to", "went to", "gone to"], - ["look at", "looks at", "looking at", "looked at", "looked at"], - ["choose", "chooses", "choosing", "chose", "chosen"], - ["torrent", "downloads", "downloading", "torrented", "downloaded"], - ["detonate", "detonates", "detonating", "detonated", "detonated"], - ["run", "runs", "running", "ran", "running"], - ["program", "programs", "programming", "coded", "programmed"], - ["start", "starts", "starting", "started", "started"] -]; -var tenses = -[ - {name:"Present", singular:1, plural:0, format:"%subject %verb %complement"}, - {name:"Present", singular:1, plural:0, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement lol"}, - {name:"Past", singular:3, plural:3, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement lol"}, - {name:"Past", singular:3, plural:3, format:"%subject %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement"}, - {name:"Past", singular:3, plural:3, format:"%subject just %verb %complement lol"}, - {name:"Present Continues", singular:2, plural:2, format:"%subject %be %verb %complement"} -]; -var subjects = -[ - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"I", be:"am", singular:0}, - {name:"My cat", be:"is", singular:0}, - {name:"My cat", be:"is", singular:0}, - {name:"My dog", be:"is", singular:0}, - {name:"My dog", be:"is", singular:0}, - {name:"My mom", be:"is", singular:0}, - {name:"My dad", be:"is", singular:0}, - {name:"You", be:"are", singular:0}, - {name:"He", be:"is", singular:1} -]; -var complementsForVerbs = -[ - ["the cinema", "Egypt", "the house", "the concert"], - ["for a map", "them", "the stars", "the lake"], - ["a book for reading", "a dvd for tonight"], - ["the virus", "the malware", "that 0day", "Onionr"], - ["a bomb", "a nuke", "some C4", "some ammonium nitrate"], - ["the race", "towards someone", "to the stars", "on top of your roof"], - ["Onionr", "the malware", "some software", "Onionr"], - ["Onionr", "Onionr", "the race", "the timer"], -] +/* just for testing rn */ +Block.getBlocks({'type' : 'onionr-post', 'signed' : true, 'reverse' : true}, function(data) { + for(var i = 0; i < data.length; i++) { + try { + var block = data[i]; -Array.prototype.random = function(){return this[Math.floor(Math.random() * this.length)];}; + var post = new Post(); + var user = new User(); -function generate(){ - var index = Math.floor(verbs.length * Math.random()); - var tense = tenses.random(); - var subject = subjects.random(); - var verb = verbs[index]; - var complement = complementsForVerbs[index]; - var str = tense.format; - str = str.replace("%subject", subject.name).replace("%be", subject.be); - str = str.replace("%verb", verb[subject.singular ? tense.singular : tense.plural]); - str = str.replace("%complement", complement.random()); - return str; -} + var blockContent = JSON.parse(block.getContent()); -var curDate = new Date() -function addRandomPost() { - var post = new Post(); - var user = new User(); - var items = ['arinerron', 'beardog108', 'samyk', 'snowden', 'aaronswartz']; - user.setName(items[Math.floor(Math.random()*items.length)]); - user.setID('i-eat-waffles-often-its-actually-crazy-like-i-dont-know-wow'); - post.setContent(generate()); - post.setUser(user); + user.setName('unknown'); + user.setID(new String(block.getHeader('signer', 'unknown'))); + post.setContent(blockContent['content']); + post.setPostDate(block.getDate()); + post.setUser(user); - curDate = new Date(curDate - (Math.random() * 1000000)); - post.setPostDate(curDate); - - document.getElementById('onionr-timeline-posts').innerHTML += post.getHTML(); -} - -for(var i = 0; i < Math.round(50 * Math.random()); i++) - addRandomPost(); + document.getElementById('onionr-timeline-posts').innerHTML += post.getHTML(); + } catch(e) { + console.log(e); + } + } +}); function viewProfile(id, name) { document.getElementById("onionr-profile-username").innerHTML = encodeHTML(decodeURIComponent(name));