Compare commits
11 Commits
g1itch/ref
...
v0.6
Author | SHA1 | Date | |
---|---|---|---|
1c6d4702c0 | |||
f5fba7d1a8 | |||
f075d27fae | |||
1b8dc18ef6 | |||
06cab993d9 | |||
6f9b66ddff | |||
79efacffb1 | |||
6ee6989df2 | |||
5f9d507717 | |||
6168d63699 | |||
8ff8e0e2cb |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "packages/flatpak/shared-modules"]
|
||||||
|
path = packages/flatpak/shared-modules
|
||||||
|
url = https://github.com/flathub/shared-modules.git
|
57
packages/flatpak/org.bitmessage.BaseApp.json
Normal file
57
packages/flatpak/org.bitmessage.BaseApp.json
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"id": "org.bitmessage.BaseApp",
|
||||||
|
"branch": "19.08",
|
||||||
|
"runtime": "org.freedesktop.Platform",
|
||||||
|
"sdk": "org.freedesktop.Sdk",
|
||||||
|
"runtime-version": "19.08",
|
||||||
|
"separate-locales": false,
|
||||||
|
"modules": [
|
||||||
|
"shared-modules/python2.7/python-2.7.json",
|
||||||
|
"shared-modules/qt4/qt4-4.8.7-minimal.json",
|
||||||
|
{
|
||||||
|
"name": "python-sip",
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "archive",
|
||||||
|
"url": "https://www.riverbankcomputing.com/static/Downloads/sip/4.19.25/sip-4.19.25.tar.gz",
|
||||||
|
"sha256": "b39d93e937647807bac23579edbff25fe46d16213f708370072574ab1f1b4211"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildsystem": "simple",
|
||||||
|
"build-commands": [
|
||||||
|
"python configure.py --sip-module PyQt4.sip --no-dist-info",
|
||||||
|
"make",
|
||||||
|
"make install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "python-qt4",
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "archive",
|
||||||
|
"url": "http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.12.3/PyQt4_gpl_x11-4.12.3.tar.gz",
|
||||||
|
"sha256": "a00f5abef240a7b5852b7924fa5fdf5174569525dc076cd368a566619e56d472"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildsystem": "simple",
|
||||||
|
"build-commands": [
|
||||||
|
"python configure.py -w --confirm-license",
|
||||||
|
"make",
|
||||||
|
"make install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "PyBitmessage-dependencies",
|
||||||
|
"buildsystem" : "simple",
|
||||||
|
"build-options": {
|
||||||
|
"build-args": [
|
||||||
|
"--share=network"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"build-commands": [
|
||||||
|
"pip --version",
|
||||||
|
"pip install setuptools msgpack"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
48
packages/flatpak/org.bitmessage.PyBitmessage.json
Normal file
48
packages/flatpak/org.bitmessage.PyBitmessage.json
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"app-id": "org.bitmessage.PyBitmessage",
|
||||||
|
"runtime": "org.freedesktop.Platform",
|
||||||
|
"runtime-version": "19.08",
|
||||||
|
"branch": "stable",
|
||||||
|
"sdk": "org.freedesktop.Sdk",
|
||||||
|
"base": "org.bitmessage.BaseApp",
|
||||||
|
"command": "pybitmessage",
|
||||||
|
"base-version":"stable",
|
||||||
|
"finish-args" : [
|
||||||
|
"--share=network",
|
||||||
|
"--socket=x11",
|
||||||
|
"--share=ipc",
|
||||||
|
"--filesystem=xdg-config/PyBitmessage:create"
|
||||||
|
],
|
||||||
|
"modules": [
|
||||||
|
{
|
||||||
|
"name" : "PyBitmessage",
|
||||||
|
"buildsystem" : "simple",
|
||||||
|
"build-options": {
|
||||||
|
"build-args": [
|
||||||
|
"--share=network"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"build-commands": [
|
||||||
|
"python --version",
|
||||||
|
"pwd",
|
||||||
|
"ls",
|
||||||
|
"python checkdeps.py",
|
||||||
|
"python setup.py install --prefix=/app --exec-prefix=/app",
|
||||||
|
"sed -i 's~/usr/bin/~/app/bin/~' /app/bin/pybitmessage",
|
||||||
|
"cat /app/bin/pybitmessage",
|
||||||
|
"mv /app/share/applications/pybitmessage.desktop /app/share/applications/org.bitmessage.PyBitmessage.desktop",
|
||||||
|
"sed -i 's~Icon=pybitmessage~Icon=org.bitmessage.PyBitmessage~' /app/share/applications/org.bitmessage.PyBitmessage.desktop",
|
||||||
|
"mv /app/share/icons/hicolor/scalable/apps/pybitmessage.svg /app/share/icons/hicolor/scalable/apps/org.bitmessage.PyBitmessage.svg",
|
||||||
|
"mv /app/share/icons/hicolor/24x24/apps/pybitmessage.png /app/share/icons/hicolor/24x24/apps/org.bitmessage.PyBitmessage.png",
|
||||||
|
"which pybitmessage"
|
||||||
|
],
|
||||||
|
"sources" : [
|
||||||
|
{
|
||||||
|
"type" : "dir",
|
||||||
|
"path" : "../../"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
1
packages/flatpak/shared-modules
Submodule
1
packages/flatpak/shared-modules
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit fd4d38328ccb078b88ad4a891807e593ae8de806
|
|
@ -321,9 +321,10 @@ class Main(object):
|
||||||
receiveQueueThread = ReceiveQueueThread(i)
|
receiveQueueThread = ReceiveQueueThread(i)
|
||||||
receiveQueueThread.daemon = True
|
receiveQueueThread.daemon = True
|
||||||
receiveQueueThread.start()
|
receiveQueueThread.start()
|
||||||
announceThread = AnnounceThread()
|
if config.safeGetBoolean('bitmessagesettings', 'udp'):
|
||||||
announceThread.daemon = True
|
state.announceThread = AnnounceThread()
|
||||||
announceThread.start()
|
state.announceThread.daemon = True
|
||||||
|
state.announceThread.start()
|
||||||
state.invThread = InvThread()
|
state.invThread = InvThread()
|
||||||
state.invThread.daemon = True
|
state.invThread.daemon = True
|
||||||
state.invThread.start()
|
state.invThread.start()
|
||||||
|
|
|
@ -19,7 +19,7 @@ import widgets
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
from helper_sql import sqlExecute, sqlStoredProcedure
|
from helper_sql import sqlExecute, sqlStoredProcedure
|
||||||
from helper_startup import start_proxyconfig
|
from helper_startup import start_proxyconfig
|
||||||
from network import knownnodes
|
from network import knownnodes, AnnounceThread
|
||||||
from network.asyncore_pollchoose import set_rates
|
from network.asyncore_pollchoose import set_rates
|
||||||
from tr import _translate
|
from tr import _translate
|
||||||
|
|
||||||
|
@ -138,6 +138,8 @@ class SettingsDialog(QtGui.QDialog):
|
||||||
config.get('bitmessagesettings', 'port')))
|
config.get('bitmessagesettings', 'port')))
|
||||||
self.checkBoxUPnP.setChecked(
|
self.checkBoxUPnP.setChecked(
|
||||||
config.safeGetBoolean('bitmessagesettings', 'upnp'))
|
config.safeGetBoolean('bitmessagesettings', 'upnp'))
|
||||||
|
self.checkBoxUDP.setChecked(
|
||||||
|
config.safeGetBoolean('bitmessagesettings', 'udp'))
|
||||||
self.checkBoxAuthentication.setChecked(
|
self.checkBoxAuthentication.setChecked(
|
||||||
config.getboolean('bitmessagesettings', 'socksauthentication'))
|
config.getboolean('bitmessagesettings', 'socksauthentication'))
|
||||||
self.checkBoxSocksListen.setChecked(
|
self.checkBoxSocksListen.setChecked(
|
||||||
|
@ -326,7 +328,8 @@ class SettingsDialog(QtGui.QDialog):
|
||||||
self.lineEditTCPPort.text()):
|
self.lineEditTCPPort.text()):
|
||||||
self.config.set(
|
self.config.set(
|
||||||
'bitmessagesettings', 'port', str(self.lineEditTCPPort.text()))
|
'bitmessagesettings', 'port', str(self.lineEditTCPPort.text()))
|
||||||
if not self.config.safeGetBoolean('bitmessagesettings', 'dontconnect'):
|
if not self.config.safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'dontconnect'):
|
||||||
self.net_restart_needed = True
|
self.net_restart_needed = True
|
||||||
|
|
||||||
if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean(
|
if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean(
|
||||||
|
@ -339,11 +342,26 @@ class SettingsDialog(QtGui.QDialog):
|
||||||
upnpThread = upnp.uPnPThread()
|
upnpThread = upnp.uPnPThread()
|
||||||
upnpThread.start()
|
upnpThread.start()
|
||||||
|
|
||||||
|
udp_enabled = self.checkBoxUDP.isChecked()
|
||||||
|
if udp_enabled != self.config.safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'udp'):
|
||||||
|
self.config.set('bitmessagesettings', 'udp', str(udp_enabled))
|
||||||
|
if udp_enabled:
|
||||||
|
announceThread = AnnounceThread()
|
||||||
|
announceThread.daemon = True
|
||||||
|
announceThread.start()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
state.announceThread.stopThread()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
proxytype_index = self.comboBoxProxyType.currentIndex()
|
proxytype_index = self.comboBoxProxyType.currentIndex()
|
||||||
if proxytype_index == 0:
|
if proxytype_index == 0:
|
||||||
if self._proxy_type and state.statusIconColor != 'red':
|
if self._proxy_type and state.statusIconColor != 'red':
|
||||||
self.net_restart_needed = True
|
self.net_restart_needed = True
|
||||||
elif state.statusIconColor == 'red' and self.config.safeGetBoolean('bitmessagesettings', 'dontconnect'):
|
elif state.statusIconColor == 'red' and self.config.safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'dontconnect'):
|
||||||
self.net_restart_needed = False
|
self.net_restart_needed = False
|
||||||
elif self.comboBoxProxyType.currentText() != self._proxy_type:
|
elif self.comboBoxProxyType.currentText() != self._proxy_type:
|
||||||
self.net_restart_needed = True
|
self.net_restart_needed = True
|
||||||
|
@ -369,8 +387,11 @@ class SettingsDialog(QtGui.QDialog):
|
||||||
self.lineEditSocksPassword.text()))
|
self.lineEditSocksPassword.text()))
|
||||||
self.config.set('bitmessagesettings', 'sockslisten', str(
|
self.config.set('bitmessagesettings', 'sockslisten', str(
|
||||||
self.checkBoxSocksListen.isChecked()))
|
self.checkBoxSocksListen.isChecked()))
|
||||||
if self.checkBoxOnionOnly.isChecked() \
|
if (
|
||||||
and not self.config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'):
|
self.checkBoxOnionOnly.isChecked()
|
||||||
|
and not self.config.safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'onionservicesonly')
|
||||||
|
):
|
||||||
self.net_restart_needed = True
|
self.net_restart_needed = True
|
||||||
self.config.set('bitmessagesettings', 'onionservicesonly', str(
|
self.config.set('bitmessagesettings', 'onionservicesonly', str(
|
||||||
self.checkBoxOnionOnly.isChecked()))
|
self.checkBoxOnionOnly.isChecked()))
|
||||||
|
|
|
@ -231,7 +231,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Bandwidth limit</string>
|
<string>Bandwidth limit</string>
|
||||||
|
@ -322,7 +322,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Proxy server / Tor</string>
|
<string>Proxy server / Tor</string>
|
||||||
|
@ -432,7 +432,14 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBoxUDP">
|
||||||
|
<property name="text">
|
||||||
|
<string>Announce self by UDP</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
from addressbook import TestAddressbook
|
from addressbook import TestAddressbook
|
||||||
from main import TestMain, TestUISignaler
|
from main import TestMain, TestUISignaler
|
||||||
|
from settings import TestSettings
|
||||||
from support import TestSupport
|
from support import TestSupport
|
||||||
|
|
||||||
__all__ = ["TestAddressbook", "TestMain", "TestSupport", "TestUISignaler"]
|
__all__ = [
|
||||||
|
"TestAddressbook", "TestMain", "TestSettings", "TestSupport",
|
||||||
|
"TestUISignaler"
|
||||||
|
]
|
||||||
|
|
34
src/bitmessageqt/tests/settings.py
Normal file
34
src/bitmessageqt/tests/settings.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
from main import TestBase
|
||||||
|
from bmconfigparser import BMConfigParser
|
||||||
|
from bitmessageqt import settings
|
||||||
|
|
||||||
|
|
||||||
|
class TestSettings(TestBase):
|
||||||
|
"""A test case for the "Settings" dialog"""
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSettings, self).setUp()
|
||||||
|
self.dialog = settings.SettingsDialog(self.window)
|
||||||
|
|
||||||
|
def test_udp(self):
|
||||||
|
"""Test the effect of checkBoxUDP"""
|
||||||
|
udp_setting = BMConfigParser().safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'udp')
|
||||||
|
self.assertEqual(udp_setting, self.dialog.checkBoxUDP.isChecked())
|
||||||
|
self.dialog.checkBoxUDP.setChecked(not udp_setting)
|
||||||
|
self.dialog.accept()
|
||||||
|
self.assertEqual(
|
||||||
|
not udp_setting,
|
||||||
|
BMConfigParser().safeGetBoolean('bitmessagesettings', 'udp'))
|
||||||
|
time.sleep(5)
|
||||||
|
for thread in threading.enumerate():
|
||||||
|
if thread.name == 'Announcer': # find Announcer thread
|
||||||
|
if udp_setting:
|
||||||
|
self.fail(
|
||||||
|
'Announcer thread is running while udp set to False')
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if not udp_setting:
|
||||||
|
self.fail('No Announcer thread found while udp set to True')
|
|
@ -2,13 +2,22 @@
|
||||||
BMConfigParser class definition and default configuration settings
|
BMConfigParser class definition and default configuration settings
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
|
# python 3
|
||||||
|
import configparser as ConfigParser
|
||||||
|
SafeConfigParser = ConfigParser.ConfigParser
|
||||||
|
else:
|
||||||
|
# python 2
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
SafeConfigParser = ConfigParser.SafeConfigParser
|
||||||
|
|
||||||
|
import state
|
||||||
|
from singleton import Singleton
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import state
|
|
||||||
from singleton import Singleton
|
|
||||||
|
|
||||||
BMConfigDefaults = {
|
BMConfigDefaults = {
|
||||||
"bitmessagesettings": {
|
"bitmessagesettings": {
|
||||||
|
@ -19,30 +28,32 @@ BMConfigDefaults = {
|
||||||
"maxtotalconnections": 200,
|
"maxtotalconnections": 200,
|
||||||
"maxuploadrate": 0,
|
"maxuploadrate": 0,
|
||||||
"apiinterface": "127.0.0.1",
|
"apiinterface": "127.0.0.1",
|
||||||
"apiport": 8442
|
"apiport": 8442,
|
||||||
|
"udp": "True"
|
||||||
},
|
},
|
||||||
"threads": {
|
"threads": {
|
||||||
"receive": 3,
|
"receive": 3,
|
||||||
},
|
},
|
||||||
"network": {
|
"network": {
|
||||||
"bind": '',
|
"bind": "",
|
||||||
"dandelion": 90,
|
"dandelion": 90,
|
||||||
},
|
},
|
||||||
"inventory": {
|
"inventory": {
|
||||||
"storage": "sqlite",
|
"storage": "sqlite",
|
||||||
"acceptmismatch": False,
|
"acceptmismatch": "False",
|
||||||
},
|
},
|
||||||
"knownnodes": {
|
"knownnodes": {
|
||||||
"maxnodes": 20000,
|
"maxnodes": 20000,
|
||||||
},
|
},
|
||||||
"zlib": {
|
"zlib": {
|
||||||
'maxsize': 1048576
|
"maxsize": 1048576
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class BMConfigParser(ConfigParser.SafeConfigParser):
|
class BMConfigParser(SafeConfigParser):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
|
Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
|
||||||
with additional methods specific to bitmessage config.
|
with additional methods specific to bitmessage config.
|
||||||
|
@ -59,21 +70,42 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
|
||||||
raise ValueError("Invalid value %s" % value)
|
raise ValueError("Invalid value %s" % value)
|
||||||
return ConfigParser.ConfigParser.set(self, section, option, value)
|
return ConfigParser.ConfigParser.set(self, section, option, value)
|
||||||
|
|
||||||
def get(self, section, option, raw=False, variables=None):
|
def get(self, section, option, raw=False, vars=None):
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
# pylint: disable=arguments-differ
|
# pylint: disable=arguments-differ
|
||||||
try:
|
try:
|
||||||
if section == "bitmessagesettings" and option == "timeformat":
|
if section == "bitmessagesettings" and option == "timeformat":
|
||||||
return ConfigParser.ConfigParser.get(
|
return ConfigParser.ConfigParser.get(
|
||||||
self, section, option, raw, variables)
|
self, section, option)
|
||||||
try:
|
try:
|
||||||
return self._temp[section][option]
|
return self._temp[section][option]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return ConfigParser.ConfigParser.get(
|
return ConfigParser.ConfigParser.get(
|
||||||
self, section, option, True, variables)
|
self, section, option)
|
||||||
except ConfigParser.InterpolationError:
|
except ConfigParser.InterpolationError:
|
||||||
return ConfigParser.ConfigParser.get(
|
return ConfigParser.ConfigParser.get(
|
||||||
self, section, option, True, variables)
|
self, section, option)
|
||||||
|
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
|
||||||
|
try:
|
||||||
|
return BMConfigDefaults[section][option]
|
||||||
|
except (KeyError, ValueError, AttributeError):
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
# pylint: disable=arguments-differ
|
||||||
|
try:
|
||||||
|
if section == "bitmessagesettings" and option == "timeformat":
|
||||||
|
return ConfigParser.ConfigParser.get(
|
||||||
|
self, section, option, raw, vars)
|
||||||
|
try:
|
||||||
|
return self._temp[section][option]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
return ConfigParser.ConfigParser.get(
|
||||||
|
self, section, option, True, vars)
|
||||||
|
except ConfigParser.InterpolationError:
|
||||||
|
return ConfigParser.ConfigParser.get(
|
||||||
|
self, section, option, True, vars)
|
||||||
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
|
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
|
||||||
try:
|
try:
|
||||||
return BMConfigDefaults[section][option]
|
return BMConfigDefaults[section][option]
|
||||||
|
@ -190,3 +222,4 @@ class BMConfigParser(ConfigParser.SafeConfigParser):
|
||||||
if value < 0 or value > 8:
|
if value < 0 or value > 8:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import state
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
from network.assemble import assemble_addr
|
from network.assemble import assemble_addr
|
||||||
from network.connectionpool import BMConnectionPool
|
from network.connectionpool import BMConnectionPool
|
||||||
from network.udp import UDPSocket
|
|
||||||
from node import Peer
|
from node import Peer
|
||||||
from threads import StoppableThread
|
from threads import StoppableThread
|
||||||
|
|
||||||
|
@ -15,12 +14,13 @@ from threads import StoppableThread
|
||||||
class AnnounceThread(StoppableThread):
|
class AnnounceThread(StoppableThread):
|
||||||
"""A thread to manage regular announcing of this node"""
|
"""A thread to manage regular announcing of this node"""
|
||||||
name = "Announcer"
|
name = "Announcer"
|
||||||
|
announceInterval = 60
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
lastSelfAnnounced = 0
|
lastSelfAnnounced = 0
|
||||||
while not self._stopped and state.shutdown == 0:
|
while not self._stopped and state.shutdown == 0:
|
||||||
processed = 0
|
processed = 0
|
||||||
if lastSelfAnnounced < time.time() - UDPSocket.announceInterval:
|
if lastSelfAnnounced < time.time() - self.announceInterval:
|
||||||
self.announceSelf()
|
self.announceSelf()
|
||||||
lastSelfAnnounced = time.time()
|
lastSelfAnnounced = time.time()
|
||||||
if processed == 0:
|
if processed == 0:
|
||||||
|
|
|
@ -8,6 +8,7 @@ import time
|
||||||
import protocol
|
import protocol
|
||||||
import state
|
import state
|
||||||
from bmproto import BMProto
|
from bmproto import BMProto
|
||||||
|
from constants import MAX_TIME_OFFSET
|
||||||
from node import Peer
|
from node import Peer
|
||||||
from objectracker import ObjectTracker
|
from objectracker import ObjectTracker
|
||||||
from queues import receiveDataQueue
|
from queues import receiveDataQueue
|
||||||
|
@ -18,7 +19,6 @@ logger = logging.getLogger('default')
|
||||||
class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
|
class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
|
||||||
"""Bitmessage protocol over UDP (class)"""
|
"""Bitmessage protocol over UDP (class)"""
|
||||||
port = 8444
|
port = 8444
|
||||||
announceInterval = 60
|
|
||||||
|
|
||||||
def __init__(self, host=None, sock=None, announcing=False):
|
def __init__(self, host=None, sock=None, announcing=False):
|
||||||
# pylint: disable=bad-super-call
|
# pylint: disable=bad-super-call
|
||||||
|
@ -82,8 +82,8 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
|
||||||
decodedIP = protocol.checkIPAddress(str(ip))
|
decodedIP = protocol.checkIPAddress(str(ip))
|
||||||
if stream not in state.streamsInWhichIAmParticipating:
|
if stream not in state.streamsInWhichIAmParticipating:
|
||||||
continue
|
continue
|
||||||
if (seenTime < time.time() - self.maxTimeOffset
|
if (seenTime < time.time() - MAX_TIME_OFFSET
|
||||||
or seenTime > time.time() + self.maxTimeOffset):
|
or seenTime > time.time() + MAX_TIME_OFFSET):
|
||||||
continue
|
continue
|
||||||
if decodedIP is False:
|
if decodedIP is False:
|
||||||
# if the address isn't local, interpret it as
|
# if the address isn't local, interpret it as
|
||||||
|
@ -94,7 +94,6 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"received peer discovery from %s:%i (port %i):",
|
"received peer discovery from %s:%i (port %i):",
|
||||||
self.destination.host, self.destination.port, remoteport)
|
self.destination.host, self.destination.port, remoteport)
|
||||||
if self.local:
|
|
||||||
state.discoveredPeers[Peer(self.destination.host, remoteport)] = \
|
state.discoveredPeers[Peer(self.destination.host, remoteport)] = \
|
||||||
time.time()
|
time.time()
|
||||||
return True
|
return True
|
||||||
|
@ -125,9 +124,9 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
|
||||||
|
|
||||||
def handle_read(self):
|
def handle_read(self):
|
||||||
try:
|
try:
|
||||||
(recdata, addr) = self.socket.recvfrom(self._buf_len)
|
recdata, addr = self.socket.recvfrom(self._buf_len)
|
||||||
except socket.error as e:
|
except socket.error:
|
||||||
logger.error("socket error: %s", e)
|
logger.error("socket error on recvfrom:", exc_info=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.destination = Peer(*addr)
|
self.destination = Peer(*addr)
|
||||||
|
@ -143,7 +142,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
|
||||||
try:
|
try:
|
||||||
retval = self.socket.sendto(
|
retval = self.socket.sendto(
|
||||||
self.write_buf, ('<broadcast>', self.port))
|
self.write_buf, ('<broadcast>', self.port))
|
||||||
except socket.error as e:
|
except socket.error:
|
||||||
logger.error("socket error on sendto: %s", e)
|
logger.error("socket error on sendto:", exc_info=True)
|
||||||
retval = len(self.write_buf)
|
retval = len(self.write_buf)
|
||||||
self.slice_write_buf(retval)
|
self.slice_write_buf(retval)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import shutil
|
||||||
import socket
|
import socket
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -61,6 +62,13 @@ class TestCore(unittest.TestCase):
|
||||||
"""Test case, which runs in main pybitmessage thread"""
|
"""Test case, which runs in main pybitmessage thread"""
|
||||||
addr = 'BM-2cVvkzJuQDsQHLqxRXc6HZGPLZnkBLzEZY'
|
addr = 'BM-2cVvkzJuQDsQHLqxRXc6HZGPLZnkBLzEZY'
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Reset possible unexpected settings after test"""
|
||||||
|
knownnodes.addKnownNode(1, Peer('127.0.0.1', 8444), is_self=True)
|
||||||
|
BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
|
||||||
|
BMConfigParser().remove_option('bitmessagesettings', 'onionservicesonly')
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
|
||||||
|
|
||||||
def test_msgcoding(self):
|
def test_msgcoding(self):
|
||||||
"""test encoding and decoding (originally from helper_msgcoding)"""
|
"""test encoding and decoding (originally from helper_msgcoding)"""
|
||||||
msg_data = {
|
msg_data = {
|
||||||
|
@ -270,6 +278,36 @@ class TestCore(unittest.TestCase):
|
||||||
return
|
return
|
||||||
self.fail('Failed to connect to at least 3 nodes within 360 sec')
|
self.fail('Failed to connect to at least 3 nodes within 360 sec')
|
||||||
|
|
||||||
|
def test_udp(self):
|
||||||
|
"""check default udp setting and presence of Announcer thread"""
|
||||||
|
self.assertTrue(
|
||||||
|
BMConfigParser().safeGetBoolean('bitmessagesettings', 'udp'))
|
||||||
|
for thread in threading.enumerate():
|
||||||
|
if thread.name == 'Announcer': # find Announcer thread
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return self.fail('No Announcer thread found')
|
||||||
|
|
||||||
|
for _ in range(20): # wait for UDP socket
|
||||||
|
for sock in BMConnectionPool().udpSockets.values():
|
||||||
|
thread.announceSelf()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(1)
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.fail('UDP socket is not started')
|
||||||
|
|
||||||
|
for _ in range(20):
|
||||||
|
if state.discoveredPeers:
|
||||||
|
peer = state.discoveredPeers.keys()[0]
|
||||||
|
self.assertEqual(peer.port, 8444)
|
||||||
|
break
|
||||||
|
time.sleep(1)
|
||||||
|
else:
|
||||||
|
self.fail('No self in discovered peers')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _decode_msg(data, pattern):
|
def _decode_msg(data, pattern):
|
||||||
proto = BMProto()
|
proto = BMProto()
|
||||||
|
|
|
@ -2,11 +2,7 @@
|
||||||
Various tests for config
|
Various tests for config
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import unittest
|
import unittest
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from .test_process import TestProcessProto
|
|
||||||
from pybitmessage.bmconfigparser import BMConfigParser
|
from pybitmessage.bmconfigparser import BMConfigParser
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,32 +34,3 @@ class TestConfig(unittest.TestCase):
|
||||||
BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0)
|
BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42)
|
BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42)
|
||||||
|
|
||||||
|
|
||||||
class TestProcessConfig(TestProcessProto):
|
|
||||||
"""A test case for keys.dat"""
|
|
||||||
home = tempfile.mkdtemp()
|
|
||||||
|
|
||||||
def test_config_defaults(self):
|
|
||||||
"""Test settings in the generated config"""
|
|
||||||
self._stop_process()
|
|
||||||
self._kill_process()
|
|
||||||
config = BMConfigParser()
|
|
||||||
config.read(os.path.join(self.home, 'keys.dat'))
|
|
||||||
|
|
||||||
self.assertEqual(config.safeGetInt(
|
|
||||||
'bitmessagesettings', 'settingsversion'), 10)
|
|
||||||
self.assertEqual(config.safeGetInt(
|
|
||||||
'bitmessagesettings', 'port'), 8444)
|
|
||||||
# don't connect
|
|
||||||
self.assertTrue(config.safeGetBoolean(
|
|
||||||
'bitmessagesettings', 'dontconnect'))
|
|
||||||
# API disabled
|
|
||||||
self.assertFalse(config.safeGetBoolean(
|
|
||||||
'bitmessagesettings', 'apienabled'))
|
|
||||||
|
|
||||||
# extralowdifficulty is false
|
|
||||||
self.assertEqual(config.safeGetInt(
|
|
||||||
'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000)
|
|
||||||
self.assertEqual(config.safeGetInt(
|
|
||||||
'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000)
|
|
||||||
|
|
38
src/tests/test_config_process.py
Normal file
38
src/tests/test_config_process.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
"""
|
||||||
|
Various tests for config
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
from pybitmessage.bmconfigparser import BMConfigParser
|
||||||
|
from .test_process import TestProcessProto
|
||||||
|
|
||||||
|
|
||||||
|
class TestProcessConfig(TestProcessProto):
|
||||||
|
"""A test case for keys.dat"""
|
||||||
|
home = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
|
||||||
|
def test_config_defaults(self):
|
||||||
|
"""Test settings in the generated config"""
|
||||||
|
config = BMConfigParser()
|
||||||
|
self._stop_process()
|
||||||
|
self._kill_process()
|
||||||
|
config.read(os.path.join(self.home, 'keys.dat'))
|
||||||
|
|
||||||
|
self.assertEqual(config.safeGetInt(
|
||||||
|
'bitmessagesettings', 'settingsversion'), 10)
|
||||||
|
self.assertEqual(config.safeGetInt(
|
||||||
|
'bitmessagesettings', 'port'), 8444)
|
||||||
|
# don't connect
|
||||||
|
self.assertTrue(config.safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'dontconnect'))
|
||||||
|
# API disabled
|
||||||
|
self.assertFalse(config.safeGetBoolean(
|
||||||
|
'bitmessagesettings', 'apienabled'))
|
||||||
|
|
||||||
|
# extralowdifficulty is false
|
||||||
|
self.assertEqual(config.safeGetInt(
|
||||||
|
'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000)
|
||||||
|
self.assertEqual(config.safeGetInt(
|
||||||
|
'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000)
|
Loading…
Reference in New Issue
Block a user