Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added working client implentation and entry point definitions.

  • Loading branch information...
commit 4305c5538d65ba874208cf8d24ac0af754fc6c49 1 parent da6d518
udoprog authored
View
48 README.md
@@ -1,7 +1,3 @@
-THIS IS THE type-test branch
-
-See TYPE-TEST heading for differences
-
This is suppose to be a complete implementation for the Advanced Direct Connect protocol.
The parts marked with a plus (+) have been implemented, the minus parts are TODO:
@@ -49,7 +45,49 @@ If you want to play around with the parser, run:
Note: the command_name 'ART' does not really exist.
-TYPE-TEST
+CLIENT
+---
+This package comes with an experimental DC client implemented with a client-server approach.
+
+The idea is that a constant service is running in the background which controls
+the Direct Connect process, and it is administered by connecting to it via one,
+or a set of clients.
+
+To try it out, run the following to start the service:
+
+ #> bin/adc-server <port>
+
+And the following to run the client:
+
+ #> bin/adc-client <host> <port>
+
+The current protocol is just a simple rpc protocol using newlines as delimiters, and by pickling and base64 encoding the following construct:
+
+frame = {
+ 'method': "remote_method",
+ 'argv': ["argument 1"],
+ 'kw': {'kw1': "value1"}
+};
+
+The result frame has the following format:
+
+result = {
+ 'ok': False,
+ 'error': "Error message describing problem"
+ 'result': <the return value of the result method>
+}
+
+'''A couple of important points to understand before using the client:'''
+
+* The Pickle/Base64 approach is very flexible for defining remote protocols,
+but '''extremely''' unsafe. This is an experimental client, DO NOT USE IT
+AGAINST POTENTIALLY UNSAFE CLIENTS, YOUR COMPUTER CAN LITERALLY BE DESTROYED.
+In the future this might be fixed by defining a proper protocol, but in the
+meantime beware, here be dragons.
+* There is no authentication, I have no plans to create a multiuser environment
+since I find that unethical against DC common sense.
+
+ARGUMENT TYPING SUGGESTION FOR ADC 2.0:
---
This is an experimental branch where I've implemented type declaration for each argument passed through the protocol
Try it out by doing the following INF (also see; example-message.py):
View
18 adc/__init__.py
@@ -1 +1,19 @@
from parser import ADCParser
+
+from printer import Printer;
+
+class entrypoint:
+ out = None;
+ err = None;
+
+ @classmethod
+ def method(klass, argv):
+ klass.err.println("no entrypoint method defined");
+ return 250;
+
+ @classmethod
+ def run(klass):
+ import sys;
+ klass.out = Printer(stream=sys.stdout);
+ klass.err = Printer(stream=sys.stdout);
+ klass.method(klass(), sys.argv[1:]);
View
37 adc/factory/remote.py → adc/factory/client.py
@@ -5,18 +5,8 @@
import readline
from ..protocol.remote import RemoteProtocol
-
-from pytermcaps import TermCaps
-
-class Printer(TermCaps):
- def notice(self, *s):
- self._writeall(self.c.bold, self.c.magenta, self._join(s), self.c.sgr0, "\n");
-
- def error(self, *s):
- self._writeall(self.c.bold, self.c.red, self._join(s), self.c.sgr0, "\n");
-
- def message(self, *s):
- self._writeall(self.c.bold, self.c.green, self._join(s), self.c.sgr0, "\n");
+from ..printer import Printer
+from .. import entrypoint
def parse_input(s):
r_i = s.find(' ')
@@ -83,23 +73,26 @@ def clientConnectionLost(self, connector, reason):
print 'connection lost:', reason.getErrorMessage()
reactor.stop()
-def main():
- import sys;
- if len(sys.argv) < 3:
- sys.stderr.write("Usage: adc.factory <service-host> <service-port>\n");
- sys.exit(1);
+def main(app, argv):
+ if len(argv) < 2:
+ app.err.println("Usage: adc.factory <service-host> <service-port>");
+ return 1;
- host = sys.argv[1];
+ host = argv[0];
try:
- port = int(sys.argv[2]);
+ port = int(argv[1]);
except:
- print "Bad numeric:", sys.argv[2];
- sys.exit(2);
+ app.err.println("Bad numeric:", argv[1]);
+ return 2;
readline.parse_and_bind('tab: complete');
reactor.connectTCP(host, port, RemoteClientFactory())
reactor.run()
+def entry():
+ entrypoint.method = main;
+ entrypoint.run();
+
if __name__ == '__main__':
- main()
+ entry();
View
28 adc/factory/service.py → adc/factory/server.py
@@ -2,6 +2,7 @@
from twisted.internet import reactor
from ..protocol import ServiceProtocol
+from .. import entrypoint
class ServiceFactory(Factory):
protocol = ServiceProtocol
@@ -36,27 +37,30 @@ def remote_send(self, conn, host, port, *text):
else:
return "could not find peer: " + host + ":" + str(port);
-def main():
- import sys;
- if len(sys.argv) < 2:
- sys.stderr.write("Usage: adc.factory <service-port>\n");
- sys.exit(1);
+def main(self, argv):
+ if len(argv) < 1:
+ self.out.println("Usage: adc-server <service-port>");
+ return 1;
try:
- port = int(sys.argv[1]);
+ port = int(argv[0]);
except:
- print "Bad numeric:", sys.argv[1];
- sys.exit(2);
+ self.err.println("Bad numeric:", argv[0]);
+ return 2;
- print "Starting to listen on tcp port:", port
+ self.out.println("Starting to listen on tcp port:", port);
try:
reactor.listenTCP(port, ServiceFactory())
reactor.run()
except Exception, e:
- print "Exception Caught:", str(e);
+ self.err.println("Exception Caught:", str(e));
- print "Stopped listening on tcp port:", port
+ self.out.println("Stopped listening on tcp port:", port);
+
+def entry():
+ entrypoint.method = main;
+ entrypoint.run();
if __name__ == "__main__":
- main();
+ entry();
View
20 adc/interactive.py
@@ -1,20 +0,0 @@
-import code
-
-import factory
-import parser
-
-banner="""Python-ADC Interactive Console
-avaible modules:
- parser - adc.parser
- factory - factory for creating connections
-"""
-
-locals={
- 'factory': factory,
- 'parser': parser,
-};
-
-if __name__ == "__main__":
- import rlcompleter, readline
- readline.parse_and_bind('tab: complete')
- code.interact(banner, raw_input, locals);
View
20 base32.py
@@ -1,20 +0,0 @@
-# case 1: initial of a byte
-# case 2: offset
-
-base32string="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
-
-def b32encode(s):
- c1 = 0;
- c2 = 0;
- c3 = 0;
-
- for c in s:
- o = ord(c);
-
- c1 = base32string[o >> 3]
- c2 += (o & 0x07) <<
-
- return c1;
-
-if __name__ == "__main__":
- print b32encode("T");
View
4 bin/remote → bin/adc-client
@@ -2,5 +2,5 @@
import sys, os
sys.path.append(os.path.abspath(os.path.dirname(os.path.dirname(__file__))));
-import adc.factory.remote
-adc.factory.remote.main();
+import adc.factory.client
+adc.factory.client.entry();
View
4 bin/service → bin/adc-server
@@ -2,5 +2,5 @@
import sys, os
sys.path.append(os.path.abspath(os.path.dirname(os.path.dirname(__file__))));
-import adc.factory.service
-adc.factory.service.main();
+import adc.factory.server
+adc.factory.server.entry();
View
9 setup.py
@@ -22,7 +22,10 @@
"pyparsing",
"ipy"
],
- entry_points="""
- # -*- Entry points: -*-
- """,
+ entry_points={
+ 'console_scripts': [
+ 'adc-server = adc.factory.server:entry',
+ 'adc-client = adc.factory.client:entry'
+ ],
+ }
)
Please sign in to comment.
Something went wrong with that request. Please try again.