diff --git a/onionr/api.py b/onionr/api.py
index 6590a258..647d7635 100755
--- a/onionr/api.py
+++ b/onionr/api.py
@@ -175,7 +175,7 @@ class PublicAPI:
try:
newNode = request.form['node'].encode()
except KeyError:
- logger.warn('No block specified for upload')
+ logger.warn('No node specified for upload')
pass
else:
try:
diff --git a/onionr/communicator.py b/onionr/communicator.py
index b4e68b68..54a512ac 100755
--- a/onionr/communicator.py
+++ b/onionr/communicator.py
@@ -21,12 +21,16 @@
'''
import sys, os, core, config, json, requests, time, logger, threading, base64, onionr, uuid
import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as plugins, onionrblockapi as block
-import onionrdaemontools, onionrsockets, onionr, onionrproofs
+from communicatorutils import onionrdaemontools
+import onionrsockets, onionr, onionrproofs
import binascii
+from communicatorutils import onionrcommunicatortimers
from dependencies import secrets
from defusedxml import minidom
from utils import networkmerger
+OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
+
config.reload()
class OnionrCommunicatorDaemon:
def __init__(self, onionrInst, proxyPort, developmentMode=config.get('general.dev_mode', False)):
@@ -647,48 +651,5 @@ class OnionrCommunicatorDaemon:
self.decrementThreadCount('runCheck')
-class OnionrCommunicatorTimers:
- def __init__(self, daemonInstance, timerFunction, frequency, makeThread=True, threadAmount=1, maxThreads=5, requiresPeer=False):
- self.timerFunction = timerFunction
- self.frequency = frequency
- self.threadAmount = threadAmount
- self.makeThread = makeThread
- self.requiresPeer = requiresPeer
- self.daemonInstance = daemonInstance
- self.maxThreads = maxThreads
- self._core = self.daemonInstance._core
-
- self.daemonInstance.timers.append(self)
- self.count = 0
-
- def processTimer(self):
-
- # mark how many instances of a thread we have (decremented at thread end)
- try:
- self.daemonInstance.threadCounts[self.timerFunction.__name__]
- except KeyError:
- self.daemonInstance.threadCounts[self.timerFunction.__name__] = 0
-
- # execute thread if it is time, and we are not missing *required* online peer
- if self.count == self.frequency and not self.daemonInstance.shutdown:
- try:
- if self.requiresPeer and len(self.daemonInstance.onlinePeers) == 0:
- raise onionrexceptions.OnlinePeerNeeded
- except onionrexceptions.OnlinePeerNeeded:
- pass
- else:
- if self.makeThread:
- for i in range(self.threadAmount):
- if self.daemonInstance.threadCounts[self.timerFunction.__name__] >= self.maxThreads:
- logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timerFunction.__name__)
- else:
- self.daemonInstance.threadCounts[self.timerFunction.__name__] += 1
- newThread = threading.Thread(target=self.timerFunction)
- newThread.start()
- else:
- self.timerFunction()
- self.count = -1 # negative 1 because its incremented at bottom
- self.count += 1
-
def startCommunicator(onionrInst, proxyPort):
OnionrCommunicatorDaemon(onionrInst, proxyPort)
\ No newline at end of file
diff --git a/onionr/communicatorutils/onionrcommunicatortimers.py b/onionr/communicatorutils/onionrcommunicatortimers.py
new file mode 100644
index 00000000..c15f20fc
--- /dev/null
+++ b/onionr/communicatorutils/onionrcommunicatortimers.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+'''
+ Onionr - P2P Anonymous Storage Network
+
+ This file contains timer control for the communicator
+'''
+'''
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+'''
+import threading, onionrexceptions, logger
+class OnionrCommunicatorTimers:
+ def __init__(self, daemonInstance, timerFunction, frequency, makeThread=True, threadAmount=1, maxThreads=5, requiresPeer=False):
+ self.timerFunction = timerFunction
+ self.frequency = frequency
+ self.threadAmount = threadAmount
+ self.makeThread = makeThread
+ self.requiresPeer = requiresPeer
+ self.daemonInstance = daemonInstance
+ self.maxThreads = maxThreads
+ self._core = self.daemonInstance._core
+
+ self.daemonInstance.timers.append(self)
+ self.count = 0
+
+ def processTimer(self):
+
+ # mark how many instances of a thread we have (decremented at thread end)
+ try:
+ self.daemonInstance.threadCounts[self.timerFunction.__name__]
+ except KeyError:
+ self.daemonInstance.threadCounts[self.timerFunction.__name__] = 0
+
+ # execute thread if it is time, and we are not missing *required* online peer
+ if self.count == self.frequency and not self.daemonInstance.shutdown:
+ try:
+ if self.requiresPeer and len(self.daemonInstance.onlinePeers) == 0:
+ raise onionrexceptions.OnlinePeerNeeded
+ except onionrexceptions.OnlinePeerNeeded:
+ pass
+ else:
+ if self.makeThread:
+ for i in range(self.threadAmount):
+ if self.daemonInstance.threadCounts[self.timerFunction.__name__] >= self.maxThreads:
+ logger.debug('%s is currently using the maximum number of threads, not starting another.' % self.timerFunction.__name__)
+ else:
+ self.daemonInstance.threadCounts[self.timerFunction.__name__] += 1
+ newThread = threading.Thread(target=self.timerFunction)
+ newThread.start()
+ else:
+ self.timerFunction()
+ self.count = -1 # negative 1 because its incremented at bottom
+ self.count += 1
diff --git a/onionr/onionrdaemontools.py b/onionr/communicatorutils/onionrdaemontools.py
similarity index 100%
rename from onionr/onionrdaemontools.py
rename to onionr/communicatorutils/onionrdaemontools.py
diff --git a/onionr/onionrevents.py b/onionr/onionrevents.py
index 0a2c48f1..3301a3ac 100755
--- a/onionr/onionrevents.py
+++ b/onionr/onionrevents.py
@@ -67,7 +67,6 @@ def call(plugin, event_name, data = None, pluginapi = None):
return True
except Exception as e:
- logger.debug(str(e))
return False
else:
return True
diff --git a/onionr/static-data/www/mail/index.html b/onionr/static-data/www/mail/index.html
index 53530968..16b95db9 100755
--- a/onionr/static-data/www/mail/index.html
+++ b/onionr/static-data/www/mail/index.html
@@ -33,6 +33,9 @@
From: Signature:
+
+
+
diff --git a/onionr/static-data/www/mail/mail.css b/onionr/static-data/www/mail/mail.css
index a8d27120..0334de30 100755
--- a/onionr/static-data/www/mail/mail.css
+++ b/onionr/static-data/www/mail/mail.css
@@ -87,6 +87,17 @@ input{
color: black;
}
+#replyBtn{
+ margin-top: 1em;
+}
+
+.primaryBtn{
+ border-radius: 3px;
+ padding: 3px;
+ color: black;
+ width: 5%;
+}
+
.successBtn{
background-color: #28a745;
border-radius: 3px;
diff --git a/onionr/static-data/www/mail/mail.js b/onionr/static-data/www/mail/mail.js
index c7f266ce..71b75c6c 100755
--- a/onionr/static-data/www/mail/mail.js
+++ b/onionr/static-data/www/mail/mail.js
@@ -24,8 +24,27 @@ threadPlaceholder = document.getElementById('threadPlaceholder')
tabBtns = document.getElementById('tabBtns')
threadContent = {}
myPub = httpGet('/getActivePubkey')
+replyBtn = document.getElementById('replyBtn')
-function openThread(bHash, sender, date, sigBool){
+function openReply(bHash){
+ var inbox = document.getElementsByClassName('threadEntry')
+ var entry = ''
+ var friendName = ''
+ var key = ''
+ for(var i = 0; i < inbox.length; i++) {
+ if (inbox[i].getAttribute('data-hash') === bHash){
+ entry = inbox[i]
+ }
+ }
+ if (entry.getAttribute('data-nameSet') == 'true'){
+ document.getElementById('friendSelect').value = entry.getElementsByTagName('input')[0].value
+ }
+ key = entry.getAttribute('data-pubkey')
+ document.getElementById('draftID').value = key
+ setActiveTab('send message')
+}
+
+function openThread(bHash, sender, date, sigBool, pubkey){
var messageDisplay = document.getElementById('threadDisplay')
var blockContent = httpGet('/getblockbody/' + bHash)
document.getElementById('fromUser').value = sender
@@ -43,6 +62,9 @@ function openThread(bHash, sender, date, sigBool){
}
sigEl.innerText = sigMsg
overlay('messageDisplay')
+ replyBtn.onclick = function(){
+ openReply(bHash)
+ }
}
function setActiveTab(tabName){
@@ -60,7 +82,7 @@ function setActiveTab(tabName){
}
}
-function loadInboxEntrys(bHash){
+function loadInboxEntries(bHash){
fetch('/getblockheader/' + bHash, {
headers: {
"token": webpass
@@ -87,11 +109,14 @@ function loadInboxEntrys(bHash){
validSig.innerText = 'Signature Validity: Bad'
validSig.style.color = 'red'
}
+ entry.setAttribute('data-nameSet', true)
if (senderInput.value == ''){
senderInput.value = resp['meta']['signer']
+ entry.setAttribute('data-nameSet', false)
}
bHashDisplay.innerText = bHash.substring(0, 10)
- entry.setAttribute('hash', bHash)
+ entry.setAttribute('data-hash', bHash)
+ entry.setAttribute('data-pubkey', resp['meta']['signer'])
senderInput.readOnly = true
dateStr.innerText = humanDate.toString()
if (metadata['subject'] === undefined || metadata['subject'] === null) {
@@ -110,7 +135,7 @@ function loadInboxEntrys(bHash){
entry.classList.add('threadEntry')
entry.onclick = function(){
- openThread(entry.getAttribute('hash'), senderInput.value, dateStr.innerText, resp['meta']['validSig'])
+ openThread(entry.getAttribute('data-hash'), senderInput.value, dateStr.innerText, resp['meta']['validSig'], entry.getAttribute('data-pubkey'))
}
}.bind(bHash))
@@ -127,7 +152,7 @@ function getInbox(){
threadPlaceholder.style.display = 'none'
showed = true
}
- loadInboxEntrys(pms[i])
+ loadInboxEntries(pms[i])
}
if (! showed){
threadPlaceholder.style.display = 'block'
@@ -145,6 +170,9 @@ function getSentbox(){
var entry = document.createElement('div')
var entryUsed;
for(var k in resp) keys.push(k);
+ if (keys.length == 0){
+ threadPart.innerHTML = "nothing to show here yet."
+ }
for (var i = 0; i < keys.length; i++){
var entry = document.createElement('div')
var obj = resp[i];
@@ -195,7 +223,6 @@ tabBtns.onclick = function(event){
setActiveTab(event.target.innerText.toLowerCase())
}
-
var idStrings = document.getElementsByClassName('myPub')
for (var i = 0; i < idStrings.length; i++){
if (idStrings[i].tagName.toLowerCase() == 'input'){
diff --git a/onionr/static-data/www/shared/main/style.css b/onionr/static-data/www/shared/main/style.css
index 65c378eb..ae4d87db 100755
--- a/onionr/static-data/www/shared/main/style.css
+++ b/onionr/static-data/www/shared/main/style.css
@@ -168,4 +168,8 @@ body{
.successBtn{
background-color: #4CAF50;
color: black;
+}
+
+.primaryBtn{
+ background-color:#396BAC;
}
\ No newline at end of file
diff --git a/onionr/tests/test_database_actions.py b/onionr/tests/test_database_actions.py
new file mode 100644
index 00000000..76a1350c
--- /dev/null
+++ b/onionr/tests/test_database_actions.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+import sys, os
+sys.path.append(".")
+import unittest, uuid, sqlite3
+TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
+print("Test directory:", TEST_DIR)
+os.environ["ONIONR_HOME"] = TEST_DIR
+from urllib.request import pathname2url
+import core, onionr
+
+c = core.Core()
+
+class OnionrTests(unittest.TestCase):
+
+ def test_address_add(self):
+ testAddresses = ['facebookcorewwwi.onion', '56kmnycrvepfarolhnx6t2dvmldfeyg7jdymwgjb7jjzg47u2lqw2sad.onion', '5bvb5ncnfr4dlsfriwczpzcvo65kn7fnnlnt2ln7qvhzna2xaldq.b32.i2p']
+ for address in testAddresses:
+ c.addAddress(address)
+ dbAddresses = c.listAdders()
+ for address in testAddresses:
+ self.assertIn(address, dbAddresses)
+
+ invalidAddresses = [None, '', ' ', '\t', '\n', ' test ', 24, 'fake.onion', 'fake.b32.i2p']
+ for address in invalidAddresses:
+ try:
+ c.addAddress(address)
+ except TypeError:
+ pass
+ dbAddresses = c.listAdders()
+ for address in invalidAddresses:
+ self.assertNotIn(address, dbAddresses)
+
+ def test_address_info(self):
+ adder = 'nytimes3xbfgragh.onion'
+ c.addAddress(adder)
+ self.assertNotEqual(c.getAddressInfo(adder, 'success'), 1000)
+ c.setAddressInfo(adder, 'success', 1000)
+ self.assertEqual(c.getAddressInfo(adder, 'success'), 1000)
+
+unittest.main()
\ No newline at end of file