refactoring and work on mail

This commit is contained in:
Kevin Froman 2019-02-27 21:02:44 -06:00
parent 9a728fb1f2
commit 11625b297a
10 changed files with 160 additions and 52 deletions

View File

@ -175,7 +175,7 @@ class PublicAPI:
try: try:
newNode = request.form['node'].encode() newNode = request.form['node'].encode()
except KeyError: except KeyError:
logger.warn('No block specified for upload') logger.warn('No node specified for upload')
pass pass
else: else:
try: try:

View File

@ -21,12 +21,16 @@
''' '''
import sys, os, core, config, json, requests, time, logger, threading, base64, onionr, uuid 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 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 import binascii
from communicatorutils import onionrcommunicatortimers
from dependencies import secrets from dependencies import secrets
from defusedxml import minidom from defusedxml import minidom
from utils import networkmerger from utils import networkmerger
OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
config.reload() config.reload()
class OnionrCommunicatorDaemon: class OnionrCommunicatorDaemon:
def __init__(self, onionrInst, proxyPort, developmentMode=config.get('general.dev_mode', False)): def __init__(self, onionrInst, proxyPort, developmentMode=config.get('general.dev_mode', False)):
@ -647,48 +651,5 @@ class OnionrCommunicatorDaemon:
self.decrementThreadCount('runCheck') 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): def startCommunicator(onionrInst, proxyPort):
OnionrCommunicatorDaemon(onionrInst, proxyPort) OnionrCommunicatorDaemon(onionrInst, proxyPort)

View File

@ -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 <https://www.gnu.org/licenses/>.
'''
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

View File

@ -67,7 +67,6 @@ def call(plugin, event_name, data = None, pluginapi = None):
return True return True
except Exception as e: except Exception as e:
logger.debug(str(e))
return False return False
else: else:
return True return True

View File

@ -33,6 +33,9 @@
<div> <div>
From: <input type='text' id='fromUser' readonly> Signature: <span id='sigValid'></span> From: <input type='text' id='fromUser' readonly> Signature: <span id='sigValid'></span>
</div> </div>
<div>
<button id='replyBtn' class='primaryBtn'>Reply</button>
</div>
<div id='signatureValidity'></div> <div id='signatureValidity'></div>
<div id='threadDisplay' class='pre messageContent'> <div id='threadDisplay' class='pre messageContent'>
</div> </div>

View File

@ -87,6 +87,17 @@ input{
color: black; color: black;
} }
#replyBtn{
margin-top: 1em;
}
.primaryBtn{
border-radius: 3px;
padding: 3px;
color: black;
width: 5%;
}
.successBtn{ .successBtn{
background-color: #28a745; background-color: #28a745;
border-radius: 3px; border-radius: 3px;

View File

@ -24,8 +24,27 @@ threadPlaceholder = document.getElementById('threadPlaceholder')
tabBtns = document.getElementById('tabBtns') tabBtns = document.getElementById('tabBtns')
threadContent = {} threadContent = {}
myPub = httpGet('/getActivePubkey') 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 messageDisplay = document.getElementById('threadDisplay')
var blockContent = httpGet('/getblockbody/' + bHash) var blockContent = httpGet('/getblockbody/' + bHash)
document.getElementById('fromUser').value = sender document.getElementById('fromUser').value = sender
@ -43,6 +62,9 @@ function openThread(bHash, sender, date, sigBool){
} }
sigEl.innerText = sigMsg sigEl.innerText = sigMsg
overlay('messageDisplay') overlay('messageDisplay')
replyBtn.onclick = function(){
openReply(bHash)
}
} }
function setActiveTab(tabName){ function setActiveTab(tabName){
@ -60,7 +82,7 @@ function setActiveTab(tabName){
} }
} }
function loadInboxEntrys(bHash){ function loadInboxEntries(bHash){
fetch('/getblockheader/' + bHash, { fetch('/getblockheader/' + bHash, {
headers: { headers: {
"token": webpass "token": webpass
@ -87,11 +109,14 @@ function loadInboxEntrys(bHash){
validSig.innerText = 'Signature Validity: Bad' validSig.innerText = 'Signature Validity: Bad'
validSig.style.color = 'red' validSig.style.color = 'red'
} }
entry.setAttribute('data-nameSet', true)
if (senderInput.value == ''){ if (senderInput.value == ''){
senderInput.value = resp['meta']['signer'] senderInput.value = resp['meta']['signer']
entry.setAttribute('data-nameSet', false)
} }
bHashDisplay.innerText = bHash.substring(0, 10) 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 senderInput.readOnly = true
dateStr.innerText = humanDate.toString() dateStr.innerText = humanDate.toString()
if (metadata['subject'] === undefined || metadata['subject'] === null) { if (metadata['subject'] === undefined || metadata['subject'] === null) {
@ -110,7 +135,7 @@ function loadInboxEntrys(bHash){
entry.classList.add('threadEntry') entry.classList.add('threadEntry')
entry.onclick = function(){ 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)) }.bind(bHash))
@ -127,7 +152,7 @@ function getInbox(){
threadPlaceholder.style.display = 'none' threadPlaceholder.style.display = 'none'
showed = true showed = true
} }
loadInboxEntrys(pms[i]) loadInboxEntries(pms[i])
} }
if (! showed){ if (! showed){
threadPlaceholder.style.display = 'block' threadPlaceholder.style.display = 'block'
@ -145,6 +170,9 @@ function getSentbox(){
var entry = document.createElement('div') var entry = document.createElement('div')
var entryUsed; var entryUsed;
for(var k in resp) keys.push(k); 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++){ for (var i = 0; i < keys.length; i++){
var entry = document.createElement('div') var entry = document.createElement('div')
var obj = resp[i]; var obj = resp[i];
@ -195,7 +223,6 @@ tabBtns.onclick = function(event){
setActiveTab(event.target.innerText.toLowerCase()) setActiveTab(event.target.innerText.toLowerCase())
} }
var idStrings = document.getElementsByClassName('myPub') var idStrings = document.getElementsByClassName('myPub')
for (var i = 0; i < idStrings.length; i++){ for (var i = 0; i < idStrings.length; i++){
if (idStrings[i].tagName.toLowerCase() == 'input'){ if (idStrings[i].tagName.toLowerCase() == 'input'){

View File

@ -168,4 +168,8 @@ body{
.successBtn{ .successBtn{
background-color: #4CAF50; background-color: #4CAF50;
color: black; color: black;
}
.primaryBtn{
background-color:#396BAC;
} }

View File

@ -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()