From 74a7ec25a707c11415a3b6b5e99956cbec8b236d Mon Sep 17 00:00:00 2001 From: Inso <insomniak.fr@gmail.com> Date: Wed, 13 May 2015 09:06:39 +0200 Subject: [PATCH] Initialized QNetworkManager API --- src/cutecoin/core/net/api/__init__.py | 0 src/cutecoin/core/net/api/bma/__init__.py | 121 ++++++++++++++ .../core/net/api/bma/blockchain/__init__.py | 158 ++++++++++++++++++ .../core/net/api/bma/network/__init__.py | 35 ++++ .../net/api/bma/network/peering/__init__.py | 51 ++++++ src/cutecoin/core/net/api/bma/tx/__init__.py | 46 +++++ src/cutecoin/core/net/api/bma/wot/__init__.py | 89 ++++++++++ 7 files changed, 500 insertions(+) create mode 100644 src/cutecoin/core/net/api/__init__.py create mode 100644 src/cutecoin/core/net/api/bma/__init__.py create mode 100644 src/cutecoin/core/net/api/bma/blockchain/__init__.py create mode 100644 src/cutecoin/core/net/api/bma/network/__init__.py create mode 100644 src/cutecoin/core/net/api/bma/network/peering/__init__.py create mode 100644 src/cutecoin/core/net/api/bma/tx/__init__.py create mode 100644 src/cutecoin/core/net/api/bma/wot/__init__.py diff --git a/src/cutecoin/core/net/api/__init__.py b/src/cutecoin/core/net/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/cutecoin/core/net/api/bma/__init__.py b/src/cutecoin/core/net/api/bma/__init__.py new file mode 100644 index 00000000..ec216c55 --- /dev/null +++ b/src/cutecoin/core/net/api/bma/__init__.py @@ -0,0 +1,121 @@ +__all__ = ['api'] + +from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest +from PyQt5.QtCore import QUrl, QUrlQuery +import logging, json +# import pylibscrypt + +logger = logging.getLogger("ucoin") + + +class ConnectionHandler(object): + """Helper class used by other API classes to ease passing server connection information.""" + + def __init__(self, server, port): + """ + Arguments: + - `server`: server hostname + - `port`: port number + """ + + self.server = server + self.port = port + + def __str__(self): + return 'connection info: %s:%d' % (self.server, self.port) + + +class API(object): + """APIRequest is a class used as an interface. The intermediate derivated classes are the modules and the leaf classes are the API requests.""" + + def __init__(self, network_manager, connection_handler, module): + """ + Asks a module in order to create the url used then by derivated classes. + + Arguments: + - `module`: module name + - `connection_handler`: connection handler + """ + + self.module = module + self.network_manager = network_manager + self.connection_handler = connection_handler + self.headers = {} + + def reverse_url(self, path): + """ + Reverses the url using self.url and path given in parameter. + + Arguments: + - `path`: the request path + """ + + server, port = self.connection_handler.server, self.connection_handler.port + + url = 'http://%s:%d/%s' % (server, port, self.module) + return url + path + + def get(self, **kwargs): + """wrapper of overloaded __get__ method.""" + + return self.__get__(**kwargs) + + def post(self, **kwargs): + """wrapper of overloaded __post__ method.""" + + logger.debug('do some work with') + + data = self.__post__(**kwargs) + + logger.debug('and send back') + + return data + + def __get__(self, **kwargs): + """interface purpose for GET request""" + + pass + + def __post__(self, **kwargs): + """interface purpose for POST request""" + + pass + + def requests_get(self, path, **kwargs): + """ + Requests GET wrapper in order to use API parameters. + + Arguments: + - `path`: the request path + """ + + request = QNetworkRequest(self.reverse_url(path)) + reply = request.get(self.reverse_url(path), params=kwargs, + headers=self.headers, timeout=15) + + return reply + + def requests_post(self, path, **kwargs): + """ + Requests POST wrapper in order to use API parameters. + + Arguments: + - `path`: the request path + """ + if 'self_' in kwargs: + kwargs['self'] = kwargs.pop('self_') + + logging.debug("POST : {0}".format(kwargs)) + post_data = QUrlQuery() + for k,v in kwargs.items(): + post_data.addQueryItem(k, v); + + request = QNetworkRequest(self.reverse_url(path)) + request.setHeader(QNetworkRequest.ContentTypeHeader, + "application/x-www-form-urlencoded"); + reply = request.post(self.reverse_url(path), + post_data.toString(QUrl.FullyEncoded).toUtf8()) + + return reply + +from . import network, blockchain, tx, wot diff --git a/src/cutecoin/core/net/api/bma/blockchain/__init__.py b/src/cutecoin/core/net/api/bma/blockchain/__init__.py new file mode 100644 index 00000000..1766de67 --- /dev/null +++ b/src/cutecoin/core/net/api/bma/blockchain/__init__.py @@ -0,0 +1,158 @@ +# +# 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 <http://www.gnu.org/licenses/>. +# +# Authors: +# Caner Candan <caner@candan.fr>, http://caner.candan.fr +# + +from .. import API, logging + +logger = logging.getLogger("ucoin/blockchain") + + +class Blockchain(API): + def __init__(self, connection_handler, module='blockchain'): + super(Blockchain, self).__init__(connection_handler, module) + + +class Parameters(Blockchain): + """GET the blockchain parameters used by this node.""" + + def __get__(self, **kwargs): + return self.requests_get('/parameters', **kwargs) + + +class Membership(Blockchain): + """GET/POST a Membership document.""" + def __init__(self, connection_handler, search=None): + super().__init__(connection_handler) + self.search = search + + def __post__(self, **kwargs): + assert 'membership' in kwargs + + return self.requests_post('/membership', **kwargs) + + def __get__(self, **kwargs): + assert self.search is not None + return self.requests_get('/memberships/%s' % self.search, **kwargs) + + +class Block(Blockchain): + """GET/POST a block from/to the blockchain.""" + + def __init__(self, connection_handler, number=None): + """ + Use the number parameter in order to select a block number. + + Arguments: + - `number`: block number to select + """ + + super(Block, self).__init__(connection_handler) + + self.number = number + + def __get__(self, **kwargs): + assert self.number is not None + return self.requests_get('/block/%d' % self.number, **kwargs) + + def __post__(self, **kwargs): + assert 'block' in kwargs + assert 'signature' in kwargs + + return self.requests_post('/block', **kwargs) + + +class Current(Blockchain): + """GET, same as block/[number], but return last accepted block.""" + + def __get__(self, **kwargs): + return self.requests_get('/current', **kwargs) + + +class Hardship(Blockchain): + """GET hardship level for given member's fingerprint for writing next block.""" + + def __init__(self, connection_handler, fingerprint): + """ + Use the number parameter in order to select a block number. + + Arguments: + - `fingerprint`: member fingerprint + """ + + super(Hardship, self).__init__(connection_handler) + + self.fingerprint = fingerprint + + def __get__(self, **kwargs): + assert self.fingerprint is not None + return self.requests_get('/hardship/%s' % self.fingerprint.upper(), **kwargs) + + +class Newcomers(Blockchain): + """GET, return block numbers containing newcomers.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/newcomers', **kwargs) + + +class Certifications(Blockchain): + """GET, return block numbers containing certifications.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/certs', **kwargs) + + +class Joiners(Blockchain): + """GET, return block numbers containing joiners.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/joiners', **kwargs) + + +class Actives(Blockchain): + """GET, return block numbers containing actives.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/actives', **kwargs) + + +class Leavers(Blockchain): + """GET, return block numbers containing leavers.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/leavers', **kwargs) + + +class Excluded(Blockchain): + """GET, return block numbers containing excluded.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/excluded', **kwargs) + + +class UD(Blockchain): + """GET, return block numbers containing universal dividend.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/ud', **kwargs) + + +class TX(Blockchain): + """GET, return block numbers containing transactions.""" + + def __get__(self, **kwargs): + return self.requests_get('/with/tx', **kwargs) diff --git a/src/cutecoin/core/net/api/bma/network/__init__.py b/src/cutecoin/core/net/api/bma/network/__init__.py new file mode 100644 index 00000000..21d2735e --- /dev/null +++ b/src/cutecoin/core/net/api/bma/network/__init__.py @@ -0,0 +1,35 @@ +# +# 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 <http://www.gnu.org/licenses/>. +# +# Authors: +# Caner Candan <caner@candan.fr>, http://caner.candan.fr +# + +from .. import API, logging + +logger = logging.getLogger("ucoin/network") + + +class Network(API): + def __init__(self, connection_handler, module='network'): + super(Network, self).__init__(connection_handler, module) + + +class Peering(Network): + """GET peering information about a peer.""" + + def __get__(self, **kwargs): + return self.requests_get('/peering', **kwargs) + +from . import peering diff --git a/src/cutecoin/core/net/api/bma/network/peering/__init__.py b/src/cutecoin/core/net/api/bma/network/peering/__init__.py new file mode 100644 index 00000000..b31c63b3 --- /dev/null +++ b/src/cutecoin/core/net/api/bma/network/peering/__init__.py @@ -0,0 +1,51 @@ +# +# 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 <http://www.gnu.org/licenses/>. +# +# Authors: +# Caner Candan <caner@candan.fr>, http://caner.candan.fr +# + +from .. import Network, logging + +logger = logging.getLogger("ucoin/network/peering") + + +class Base(Network): + def __init__(self, connection_handler): + super(Base, self).__init__(connection_handler, 'network/peering') + + +class Peers(Base): + """GET peering entries of every node inside the currency network.""" + + def __get__(self, **kwargs): + """creates a generator with one peering entry per iteration.""" + + return self.requests_get('/peers') + + def __post__(self, **kwargs): + assert 'entry' in kwargs + assert 'signature' in kwargs + + return self.requests_post('/peers', **kwargs) + + +class Status(Base): + """POST a network status document to this node in order notify of its status.""" + + def __post__(self, **kwargs): + assert 'status' in kwargs + assert 'signature' in kwargs + + return self.requests_post('/status', **kwargs) diff --git a/src/cutecoin/core/net/api/bma/tx/__init__.py b/src/cutecoin/core/net/api/bma/tx/__init__.py new file mode 100644 index 00000000..6c670fa6 --- /dev/null +++ b/src/cutecoin/core/net/api/bma/tx/__init__.py @@ -0,0 +1,46 @@ +# +# 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 <http://www.gnu.org/licenses/>. +# +# Authors: +# Caner Candan <caner@candan.fr>, http://caner.candan.fr +# + +from .. import API, logging + +logger = logging.getLogger("ucoin/tx") + + +class Tx(API): + def __init__(self, connection_handler, module='tx'): + super(Tx, self).__init__(connection_handler, module) + + +class Process(Tx): + """POST a transaction.""" + + def __post__(self, **kwargs): + assert 'transaction' in kwargs + + return self.requests_post('/process', **kwargs) + + +class Sources(Tx): + """Get transaction sources.""" + def __init__(self, connection_handler, pubkey, module='tx'): + super(Tx, self).__init__(connection_handler, module) + self.pubkey = pubkey + + def __get__(self, **kwargs): + assert self.pubkey is not None + return self.requests_get('/sources/%s' % self.pubkey, **kwargs) diff --git a/src/cutecoin/core/net/api/bma/wot/__init__.py b/src/cutecoin/core/net/api/bma/wot/__init__.py new file mode 100644 index 00000000..2da4a525 --- /dev/null +++ b/src/cutecoin/core/net/api/bma/wot/__init__.py @@ -0,0 +1,89 @@ +# +# 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 <http://www.gnu.org/licenses/>. +# +# Authors: +# Caner Candan <caner@candan.fr>, http://caner.candan.fr +# + +from .. import API, logging + +logger = logging.getLogger("ucoin/wot") + + +class WOT(API): + def __init__(self, connection_handler, module='wot'): + super(WOT, self).__init__(connection_handler, module) + + +class Add(WOT): + """POST Public key data.""" + + def __post__(self, **kwargs): + assert 'pubkey' in kwargs + assert 'self_' in kwargs + assert 'other' in kwargs + + return self.requests_post('/add', **kwargs) + + +class Lookup(WOT): + """GET Public key data.""" + + def __init__(self, connection_handler, search, module='wot'): + super(WOT, self).__init__(connection_handler, module) + + self.search = search + + def __get__(self, **kwargs): + assert self.search is not None + + return self.requests_get('/lookup/%s' % self.search, **kwargs) + + +class CertifiersOf(WOT): + """GET Certification data over a member.""" + + def __init__(self, connection_handler, search, module='wot'): + super(WOT, self).__init__(connection_handler, module) + + self.search = search + + def __get__(self, **kwargs): + assert self.search is not None + + return self.requests_get('/certifiers-of/%s' % self.search, **kwargs) + + +class CertifiedBy(WOT): + """GET Certification data from a member.""" + + def __init__(self, connection_handler, search, module='wot'): + super(WOT, self).__init__(connection_handler, module) + + self.search = search + + def __get__(self, **kwargs): + assert self.search is not None + + return self.requests_get('/certified-by/%s' % self.search, **kwargs) + + +class Members(WOT): + """GET List all current members of the Web of Trust.""" + + def __init__(self, connection_handler, module='wot'): + super(WOT, self).__init__(connection_handler, module) + + def __get__(self, **kwargs): + return self.requests_get('/members', **kwargs) -- GitLab