fargo 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +49 -1
- data/bin/fargo +5 -0
- data/ext/fargo/base32.c +0 -25
- data/ext/fargo/base32.h +0 -8
- data/ext/fargo/tiger.c +0 -24
- data/ext/fargo/tiger.h +0 -8
- data/ext/fargo/tigertree.c +0 -36
- data/ext/fargo/tigertree.h +0 -6
- data/ext/fargo/tth.h +0 -8
- data/ext/readline/extconf.rb +9 -0
- data/ext/readline/fargo_cli.c +28 -0
- data/ext/readline/screen.c +77 -0
- data/ext/readline/screen.h +3 -0
- data/lib/fargo.rb +3 -1
- data/lib/fargo/cli.rb +84 -0
- data/lib/fargo/cli/completion.rb +41 -0
- data/lib/fargo/cli/downloads.rb +57 -0
- data/lib/fargo/cli/help.rb +80 -0
- data/lib/fargo/cli/info.rb +55 -0
- data/lib/fargo/cli/logging.rb +87 -0
- data/lib/fargo/cli/nick_browser.rb +159 -0
- data/lib/fargo/cli/searches.rb +63 -0
- data/lib/fargo/cli/stats.rb +16 -0
- data/lib/fargo/client.rb +33 -8
- data/lib/fargo/ext/irb.rb +33 -0
- data/lib/fargo/ext/readline.rb +18 -0
- data/lib/fargo/ext/struct.rb +7 -0
- data/lib/fargo/protocol/peer_download.rb +7 -4
- data/lib/fargo/supports/chat.rb +15 -0
- data/lib/fargo/supports/downloads.rb +5 -1
- data/lib/fargo/supports/local_file_list.rb +42 -36
- data/lib/fargo/supports/remote_file_list.rb +9 -7
- data/lib/fargo/supports/searches.rb +6 -0
- data/lib/fargo/version.rb +1 -1
- data/spec/fargo/protocol/hub_spec.rb +1 -1
- data/spec/fargo/protocol/peer_upload_spec.rb +1 -1
- data/spec/fargo/search_spec.rb +6 -1
- data/spec/fargo/supports/chat_spec.rb +7 -0
- data/spec/fargo/supports/local_file_list_spec.rb +32 -1
- data/spec/spec_helper.rb +6 -3
- metadata +65 -26
data/README.md
CHANGED
@@ -6,7 +6,51 @@ This gem is an implementation of the [Direct Connect (DC) protocol](http://en.wi
|
|
6
6
|
|
7
7
|
`gem install fargo`
|
8
8
|
|
9
|
-
##
|
9
|
+
## Configuration
|
10
|
+
|
11
|
+
For a full list of configuration options, see [the source](http://github.com/alexcrichton/fargo/blob/master/lib/fargo/client.rb).
|
12
|
+
|
13
|
+
Whatever the configuration directory is (by default `~/.fargo`), if there is a file called 'config' located in it, it will be eval'ed when Fargo is started. This way you can call `Fargo.configure` to set a nick, the hub address, share directories, and such.
|
14
|
+
|
15
|
+
The configuration directory will also be used as a location to store the local file list caches.
|
16
|
+
|
17
|
+
## CLI Usage
|
18
|
+
|
19
|
+
The CLI for Fargo works like an IRB session (it actually is an IRB session!). It's got helper methods and tab completion, however, to make things a lot easier.
|
20
|
+
|
21
|
+
Here's a synopsis of what the console has for you:
|
22
|
+
|
23
|
+
* `search 'str'` - search for a string on the hub. You will be notified when results arrive
|
24
|
+
* `results 'str'` - see the results for the given search
|
25
|
+
* `download 0, str=nil` - download the 0th numbered result from the search for 'str'. By default this uses the last given search
|
26
|
+
* `get 0, str=nil` - same as `download`
|
27
|
+
* `who 'str'=nil` - show a list of users on the hub when no argument is given. Otherwise print out specific information for the given user. If the user is 'name' or 'size', the users will be sorted based off of that attribute
|
28
|
+
* `browse 'nick'` - download nick's file list and begin browsing them. This works like a regular shell where you have a current directory and you 'cd' and 'ls' all the time
|
29
|
+
* `cd 'dir'` - change directorires
|
30
|
+
* `ls 'dir'` - list a directory
|
31
|
+
* `get 'file'` - begin downloading of a file (relative to the current dir)
|
32
|
+
* `download 'file'` - same as 'get "file"'
|
33
|
+
* `transfers` - see what's being downloaded/uploaded (percentages included)
|
34
|
+
* `status` - show some information about what you're sharing
|
35
|
+
* `say 'msg'` - say 'msg' on the hub (also `send_chat`)
|
36
|
+
|
37
|
+
All of the methods are just wrappers around the `client` object available in the IRB session. They just manipulate the return values, provide tab completion, and format results.
|
38
|
+
|
39
|
+
If you wanna get lower level access, the `client` method returns the client to interact with.
|
40
|
+
|
41
|
+
### Multiple Instances
|
42
|
+
|
43
|
+
By default, the CLI tries to connect to an instance of Fargo over DRb at 'localhost:8082'. If this fails, the CLI spawns a new thread with the EventMachine reactor running inside of it to use.
|
44
|
+
|
45
|
+
If you would like to have multiple applications using the same instance of Fargo on the same machine, simply have one process start up and call
|
46
|
+
|
47
|
+
<pre>
|
48
|
+
DRb.start_service 'druby://localhost:8082', Fargo::Client.new
|
49
|
+
</pre>
|
50
|
+
|
51
|
+
You can also [configure it](http://github.com/alexcrichton/cohort_radio/blob/master/lib/fargo/daemon.rb) or do whatever in the process as well.
|
52
|
+
|
53
|
+
## Programmatic Usage
|
10
54
|
|
11
55
|
<pre>
|
12
56
|
require 'fargo'
|
@@ -38,6 +82,10 @@ EventMachine.run {
|
|
38
82
|
|
39
83
|
See `lib/fargo/client.rb` for a full list of configuration options
|
40
84
|
|
85
|
+
## Compatibility
|
86
|
+
|
87
|
+
Fargo should run on both ruby 1.8 and ruby 1.9. It's been tested on 1.8.7 and 1.9.2
|
88
|
+
|
41
89
|
## MIT License
|
42
90
|
|
43
91
|
Copyright (c) 2010 Alex Crichton
|
data/bin/fargo
ADDED
data/ext/fargo/base32.c
CHANGED
@@ -34,28 +34,3 @@ char* base32_encode(const unsigned char* buffer, int len)
|
|
34
34
|
}
|
35
35
|
return digest;
|
36
36
|
}
|
37
|
-
|
38
|
-
#if 0
|
39
|
-
char* base32_decode(const unsigned char* buffer, int len)
|
40
|
-
{
|
41
|
-
int i, j = 0;
|
42
|
-
int bits_remain = 0;
|
43
|
-
unsigned short value = 0;
|
44
|
-
|
45
|
-
for (i = 0; i < len; i++) {
|
46
|
-
value |= (buffer[i] << bits_remain);
|
47
|
-
bits_remain += 8;
|
48
|
-
while (bits_remain > 5 && j < 1023) {
|
49
|
-
base32_digest[j++] = (value & 0x1F) < 26 ? 'A'+(value & 0x1F) : '2' + (value & 0x1F);
|
50
|
-
value >>= 5;
|
51
|
-
bits_remain -= 5;
|
52
|
-
}
|
53
|
-
}
|
54
|
-
if (bits_remain > 0) {
|
55
|
-
base32_digest[j++] = (value & 0x1F) < 26 ? 'A'+(value & 0x1F) : '2' + (value & 0x1F);
|
56
|
-
}
|
57
|
-
base32_digest[j] = '\0';
|
58
|
-
return base32_digest;
|
59
|
-
}
|
60
|
-
|
61
|
-
#endif
|
data/ext/fargo/base32.h
CHANGED
@@ -1,16 +1,8 @@
|
|
1
1
|
#ifndef __BASE32_H
|
2
2
|
#define __BASE32_H
|
3
3
|
|
4
|
-
#if defined(__cplusplus)
|
5
|
-
extern "C" {
|
6
|
-
#endif
|
7
|
-
|
8
4
|
// user must call free() funtion on pointer returned from these functions
|
9
5
|
|
10
6
|
char* base32_encode(const unsigned char* in, int inlen);
|
11
7
|
|
12
|
-
#if defined(__cplusplus)
|
13
|
-
}
|
14
|
-
#endif
|
15
|
-
|
16
8
|
#endif // ifndef __BASE32_H
|
data/ext/fargo/tiger.c
CHANGED
@@ -134,30 +134,6 @@ extern word64 table[4*256];
|
|
134
134
|
feedforward
|
135
135
|
#endif
|
136
136
|
|
137
|
-
/*
|
138
|
-
#define tiger_compress_macro(str, state) \
|
139
|
-
{ \
|
140
|
-
register word64 a, b, c, tmpa; \
|
141
|
-
word64 aa, bb, cc; \
|
142
|
-
register word64 x0, x1, x2, x3, x4, x5, x6, x7; \
|
143
|
-
register word32 i; \
|
144
|
-
int pass_no; \
|
145
|
-
\
|
146
|
-
a = state[0]; \
|
147
|
-
b = state[1]; \
|
148
|
-
c = state[2]; \
|
149
|
-
\
|
150
|
-
x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
|
151
|
-
x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7]; \
|
152
|
-
\
|
153
|
-
compress; \
|
154
|
-
\
|
155
|
-
state[0] = a; \
|
156
|
-
state[1] = b; \
|
157
|
-
state[2] = c; \
|
158
|
-
}
|
159
|
-
*/
|
160
|
-
|
161
137
|
#define tiger_compress_macro(str, state) \
|
162
138
|
{ \
|
163
139
|
register word64 a, b, c, tmpa; \
|
data/ext/fargo/tiger.h
CHANGED
data/ext/fargo/tigertree.c
CHANGED
@@ -109,43 +109,7 @@ void tt_digest(TT_CONTEXT *ctx, byte *s)
|
|
109
109
|
word64 tmp, cnt;
|
110
110
|
tt_final(ctx);
|
111
111
|
|
112
|
-
/*
|
113
|
-
dth_top0 = 0;
|
114
|
-
cnt = ctx->count;
|
115
|
-
tmp = cnt;
|
116
|
-
while(tmp == ((tmp >> 1)<<1)) {
|
117
|
-
dth_top0++;
|
118
|
-
tmp >>= 1;
|
119
|
-
}
|
120
|
-
cnt -= ((word64)1 << dth_top0);
|
121
|
-
|
122
|
-
TRACE(("ctx->top-TIGERSIZE - ctx->nodes == %d\n", ctx->top-TIGERSIZE - ctx->nodes));
|
123
|
-
*/
|
124
|
-
|
125
112
|
while( (ctx->top-TIGERSIZE) > ctx->nodes) {
|
126
|
-
/*
|
127
|
-
assert(cnt > 0);
|
128
|
-
|
129
|
-
dth_top1 = 0;
|
130
|
-
tmp = cnt;
|
131
|
-
while (tmp == ((tmp >> 1)<<1)) {
|
132
|
-
dth_top1++;
|
133
|
-
tmp >>= 1;
|
134
|
-
}
|
135
|
-
cnt -= ((word64)1 << dth_top1);
|
136
|
-
|
137
|
-
if ((ctx->depth <= dth_top1) && (ctx->depth >= dth_top0)) {
|
138
|
-
if ( dth_top1 == ctx->depth) {
|
139
|
-
TRACE(("depth = %d, dth_top0 == %d, dth_top1 == %d\n", ctx->depth, dth_top0, dth_top1));
|
140
|
-
memmove(ctx->tthl, ctx->top - 2*TIGERSIZE, 2*TIGERSIZE);
|
141
|
-
ctx->tthl += 2*TIGERSIZE;
|
142
|
-
} else {
|
143
|
-
TRACE(("depth = %d, dth_top0 == %d, dth_top1 == %d\n", ctx->depth, dth_top0, dth_top1));
|
144
|
-
memmove(ctx->tthl, ctx->top - TIGERSIZE, TIGERSIZE);
|
145
|
-
ctx->tthl += TIGERSIZE;
|
146
|
-
}
|
147
|
-
}
|
148
|
-
*/
|
149
113
|
tt_compose(ctx);
|
150
114
|
dth_top0 = dth_top1 + 1;
|
151
115
|
}
|
data/ext/fargo/tigertree.h
CHANGED
@@ -35,14 +35,8 @@ typedef struct tt_context {
|
|
35
35
|
unsigned char nodes[STACKSIZE]; /* stack of interim node values */
|
36
36
|
} TT_CONTEXT;
|
37
37
|
|
38
|
-
#if defined(__cplusplus)
|
39
|
-
extern "C" {
|
40
|
-
#endif
|
41
38
|
void tt_init(TT_CONTEXT *ctx, unsigned char *tthl, unsigned depth);
|
42
39
|
//void tt_update(TT_CONTEXT *ctx, unsigned char *buffer, word32 len);
|
43
40
|
void tt_block(TT_CONTEXT *ctx);
|
44
41
|
void tt_digest(TT_CONTEXT *ctx, unsigned char *hash);
|
45
42
|
void tt_copy(TT_CONTEXT *dest, TT_CONTEXT *src);
|
46
|
-
#if defined(__cplusplus)
|
47
|
-
}
|
48
|
-
#endif
|
data/ext/fargo/tth.h
CHANGED
@@ -3,16 +3,8 @@
|
|
3
3
|
|
4
4
|
#include "tiger.h"
|
5
5
|
|
6
|
-
#if defined(__cplusplus)
|
7
|
-
extern "C" {
|
8
|
-
#endif
|
9
|
-
|
10
6
|
// user must call free() funtion on pointer returned from these functions
|
11
7
|
|
12
8
|
char* tth(const char* filename, char **tthl, size_t *tthl_len);
|
13
9
|
|
14
|
-
#if defined(__cplusplus)
|
15
|
-
}
|
16
|
-
#endif
|
17
|
-
|
18
10
|
#endif // ifndef __TTH_H
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "screen.h"
|
3
|
+
|
4
|
+
VALUE rb_readline_clear_rl(VALUE self) {
|
5
|
+
clear_rl();
|
6
|
+
|
7
|
+
return Qtrue;
|
8
|
+
}
|
9
|
+
|
10
|
+
VALUE rb_readline_restore(VALUE self) {
|
11
|
+
restore_rl();
|
12
|
+
|
13
|
+
return Qtrue;
|
14
|
+
}
|
15
|
+
|
16
|
+
VALUE rb_readline_input(VALUE self) {
|
17
|
+
char *input = get_readline_input();
|
18
|
+
|
19
|
+
return rb_str_new(input, strlen(input));
|
20
|
+
}
|
21
|
+
|
22
|
+
Init_extra_utils() {
|
23
|
+
VALUE cReadline = rb_define_module("Readline");
|
24
|
+
|
25
|
+
rb_define_singleton_method(cReadline, "clear_rl", rb_readline_clear_rl, 0);
|
26
|
+
rb_define_singleton_method(cReadline, "restore", rb_readline_restore, 0);
|
27
|
+
rb_define_singleton_method(cReadline, "get_input", rb_readline_input, 0);
|
28
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
/* screen.c - User interface management (Readline)
|
2
|
+
*
|
3
|
+
* Copyright (C) 2004, 2005 Oskar Liljeblad
|
4
|
+
*
|
5
|
+
* This program is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
7
|
+
* the Free Software Foundation; either version 2 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU Library General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU General Public License along
|
16
|
+
* with this program; if not, write to the Free Software Foundation,
|
17
|
+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
18
|
+
*/
|
19
|
+
/* This piece of code was snatched from lftp, and modified somewhat by me.
|
20
|
+
* I suggest a function called rl_clear() be added to readline. The
|
21
|
+
* function clears the prompt and everything the user has written so far on
|
22
|
+
* the line. The cursor is positioned at the beginning of the line that
|
23
|
+
* contained the prompt. Note: This function doesn't modify the screen_state
|
24
|
+
* variable.
|
25
|
+
*/
|
26
|
+
|
27
|
+
#include <unistd.h>
|
28
|
+
#include <stdio.h>
|
29
|
+
#include <stdlib.h>
|
30
|
+
#include <signal.h>
|
31
|
+
|
32
|
+
#if defined(HAVE_READLINE_READLINE_H)
|
33
|
+
# include <readline/readline.h>
|
34
|
+
#elif defined(HAVE_READLINE_H)
|
35
|
+
# include <readline.h>
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#include "screen.h"
|
39
|
+
|
40
|
+
void clear_rl() {
|
41
|
+
|
42
|
+
extern char *rl_display_prompt;
|
43
|
+
#if HAVE__RL_MARK_MODIFIED_LINES
|
44
|
+
extern int _rl_mark_modified_lines;
|
45
|
+
int old_mark = _rl_mark_modified_lines;
|
46
|
+
#endif
|
47
|
+
int old_end = rl_end;
|
48
|
+
char *old_prompt = rl_display_prompt;
|
49
|
+
|
50
|
+
rl_end = 0;
|
51
|
+
rl_display_prompt = (char*) "";
|
52
|
+
rl_expand_prompt(rl_display_prompt);
|
53
|
+
#if HAVE__RL_MARK_MODIFIED_LINES
|
54
|
+
_rl_mark_modified_lines = 0;
|
55
|
+
#endif
|
56
|
+
|
57
|
+
rl_redisplay();
|
58
|
+
|
59
|
+
rl_end = old_end;
|
60
|
+
rl_display_prompt = old_prompt;
|
61
|
+
#if HAVE__RL_MARK_MODIFIED_LINES
|
62
|
+
_rl_mark_modified_lines = old_mark;
|
63
|
+
#endif
|
64
|
+
if (rl_display_prompt == rl_prompt)
|
65
|
+
rl_expand_prompt(rl_prompt);
|
66
|
+
}
|
67
|
+
|
68
|
+
void restore_rl() {
|
69
|
+
rl_forced_update_display();
|
70
|
+
}
|
71
|
+
|
72
|
+
char* get_readline_input() {
|
73
|
+
struct readline_state state;
|
74
|
+
rl_save_state(&state);
|
75
|
+
|
76
|
+
return state.buffer;
|
77
|
+
}
|
data/lib/fargo.rb
CHANGED
@@ -5,7 +5,6 @@ require 'active_support/core_ext/module/attribute_accessors'
|
|
5
5
|
require 'active_support/core_ext/module/delegation'
|
6
6
|
require 'active_support/buffered_logger'
|
7
7
|
require 'active_support/concern'
|
8
|
-
require 'active_support/configurable'
|
9
8
|
|
10
9
|
module Fargo
|
11
10
|
extend ActiveSupport::Autoload
|
@@ -15,6 +14,7 @@ module Fargo
|
|
15
14
|
mattr_accessor :logger
|
16
15
|
self.logger = ActiveSupport::BufferedLogger.new STDOUT
|
17
16
|
|
17
|
+
autoload :CLI
|
18
18
|
autoload :Utils
|
19
19
|
autoload :Parser
|
20
20
|
autoload :Client
|
@@ -53,3 +53,5 @@ module Fargo
|
|
53
53
|
delegate :config, :configure, :to => Client
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
require 'fargo/ext/struct'
|
data/lib/fargo/cli.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'fargo/ext/irb'
|
2
|
+
|
3
|
+
module Fargo
|
4
|
+
module CLI
|
5
|
+
extend ActiveSupport::Autoload
|
6
|
+
|
7
|
+
autoload :Completion
|
8
|
+
autoload :Downloads
|
9
|
+
autoload :Help
|
10
|
+
autoload :Info
|
11
|
+
autoload :Logging
|
12
|
+
autoload :NickBrowser
|
13
|
+
autoload :Searches
|
14
|
+
autoload :Stats
|
15
|
+
|
16
|
+
def self.start
|
17
|
+
Fargo.logger = ActiveSupport::BufferedLogger.new WrappingLogger.new
|
18
|
+
Fargo.logger.level = ActiveSupport::BufferedLogger::INFO
|
19
|
+
|
20
|
+
console = Console.new
|
21
|
+
|
22
|
+
EventMachine.error_handler { |e|
|
23
|
+
if e.message =~ /no acceptor/
|
24
|
+
puts "Couldn't open sockets for listening"
|
25
|
+
puts " Ports in question:"
|
26
|
+
[console.client.config.active_port, console.client.config.search_port,
|
27
|
+
console.client.config.websocket_port].each do |p|
|
28
|
+
puts "\t#{p}"
|
29
|
+
end
|
30
|
+
exit
|
31
|
+
else
|
32
|
+
Readline.above_prompt {
|
33
|
+
puts "ERROR!!!", e.message, e.backtrace.join("\n")
|
34
|
+
}
|
35
|
+
end
|
36
|
+
}
|
37
|
+
|
38
|
+
begin
|
39
|
+
console.client.connected?
|
40
|
+
rescue DRb::DRbConnError
|
41
|
+
current = Thread.current # Wait for the reactor to start
|
42
|
+
Thread.start{ EventMachine.run{
|
43
|
+
console.client = Fargo::Client.new
|
44
|
+
console.client.connect
|
45
|
+
current.wakeup
|
46
|
+
} }
|
47
|
+
sleep
|
48
|
+
end
|
49
|
+
|
50
|
+
console.log_published_messages
|
51
|
+
|
52
|
+
if !console.client.connected?
|
53
|
+
puts "Client couldn't connect!"
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
|
57
|
+
IRB.start_session console.instance_eval{ binding } do
|
58
|
+
console.setup_console
|
59
|
+
end
|
60
|
+
|
61
|
+
EventMachine.stop
|
62
|
+
end
|
63
|
+
|
64
|
+
class WrappingLogger
|
65
|
+
def write str
|
66
|
+
Readline.above_prompt{ puts str }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Console
|
71
|
+
|
72
|
+
include Completion
|
73
|
+
include Logging
|
74
|
+
include Searches
|
75
|
+
include Info
|
76
|
+
include Downloads
|
77
|
+
include Stats
|
78
|
+
include NickBrowser
|
79
|
+
include Help
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|