refactoring and work on mail
parent
9a728fb1f2
commit
11625b297a
|
@ -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:
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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'){
|
||||||
|
|
|
@ -169,3 +169,7 @@ body{
|
||||||
background-color: #4CAF50;
|
background-color: #4CAF50;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.primaryBtn{
|
||||||
|
background-color:#396BAC;
|
||||||
|
}
|
|
@ -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()
|
Loading…
Reference in New Issue