Class: FCPClient

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-fcp/fcp_client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, host = "127.0.0.1", port = 9481) ⇒ FCPClient

clients name must be unique This performs NodeHello operations upon initialization. Communicator handles packet sending and recieving and sorting



15
16
17
18
# File 'lib/ruby-fcp/fcp_client.rb', line 15

def initialize(client, host = "127.0.0.1", port = 9481)
  @utils = Utils.new
  @com = Communicator.new(client,host,port)
end

Instance Attribute Details

#comObject

Returns the value of attribute com.



10
11
12
# File 'lib/ruby-fcp/fcp_client.rb', line 10

def com
  @com
end

#utilsObject

Returns the value of attribute utils.



10
11
12
# File 'lib/ruby-fcp/fcp_client.rb', line 10

def utils
  @utils
end

Instance Method Details

#closeObject

Send disconnect message and close the socket



288
289
290
# File 'lib/ruby-fcp/fcp_client.rb', line 288

def close
  @com.close
end

#ddarun(directory, read, write) ⇒ Object

performs TestDDARequest and TestDDAResponse automagically read and write are true or false values



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/ruby-fcp/fcp_client.rb', line 128

def ddarun(directory,read, write)
  @com.send_packet @utils.packet_mangler({"Directory" => directory,"WantReadDirectory" => read, "WantWriteDirectory" => write} ,"TestDDARequest")
  res = wait_for(:dda, /TestDDAReply/).pop
  content = nil
  if write
    f = File.open(res["WriteFilename"],'w+')
    f.write res["ContentToWrite"]
    f.close
  elsif read
    content = File.open(res["ReadFilename"],'r').read
  end
  @com.send_packet @utils.packet_mangler({"Directory" => directory,"ReadContent" => content}, "TestDDAResponse")
  response = wait_for(:dda ,/TestDDAComplete/).pop
  File.delete(res["WriteFilename"]) if write
  response
end

#direct_get(uri, wait = true, opts = {}) ⇒ Object



160
161
162
163
164
165
166
167
168
169
# File 'lib/ruby-fcp/fcp_client.rb', line 160

def direct_get(uri ,wait = true, opts={})
  id = @utils.id_generate
  options = {"URI" => uri, "Identifier" => id, "ReturnType" => 'direct', "Global" => false}.merge(opts)
  @com.send_packet @utils.packet_mangler(options,"ClientGet")
  if wait
   wait_for(id,/AllData|GetFailed/) 
  else
   id
  end
end

#direct_put(uri, data, wait = true, opts = {}) ⇒ Object

Another interface to ClientPut that allows you to directly put data pnto freenet data is your data

Possible values of uri:

  • CHK@ will generate and return the key your data is acessible at

  • SSK@ must have insert key provided by GenerateSSK or the method new_ssk_pair

  • KSK@filename



59
60
61
62
63
64
65
66
67
68
# File 'lib/ruby-fcp/fcp_client.rb', line 59

def direct_put(uri,data, wait = true, opts = {})
  id = @utils.id_generate
  options = {"Identifier" => id, "URI" => uri ,"UploadFrom" =>  "direct", "DataLength" => data.bytesize }.merge(opts)
  @com.send_packet @utils.packet_mangler(options,"ClientPut").sub! "EndMessage\n", "Data\n#{data}"
  if wait
    wait_for id,/PutFailed|PutSuccessful/
  else
    id
  end
end

#get_plugin_info(pluginname, detailed = false) ⇒ Object

returns information on plugin, must be full class name as listed in freenet interface Implements GetPluginInfo



172
173
174
175
176
# File 'lib/ruby-fcp/fcp_client.rb', line 172

def get_plugin_info(pluginname, detailed = false)
  id = @utils.id_generate
  @com.send_packet @utils.packet_mangler({"PluginName" => pluginname, "Identifier" => id, "Detailed" => detailed },"GetPluginInfo")
  wait_for id, /PluginInfo/
end

#identifierObject

Simple attribute reader for you ConnectionIdentifier



21
22
23
# File 'lib/ruby-fcp/fcp_client.rb', line 21

def identifier
  @com.ConnectionIdentifier
end

#killswitchObject



292
293
294
# File 'lib/ruby-fcp/fcp_client.rb', line 292

def killswitch
  @com.send_packet "Shutdown\nEndMessage\n"
end

#last_response(id) ⇒ Object

return last response from request defined by Identifier



31
32
33
# File 'lib/ruby-fcp/fcp_client.rb', line 31

def last_response(id)
  @com.responses[id].last
end

#list_persistent_requestsObject

List all persistent request just implements ListPersistentRequest



199
200
201
202
# File 'lib/ruby-fcp/fcp_client.rb', line 199

def list_persistent_requests
  @com.send_packet "ListPersistentRequests\nEndMessage\n"
  wait_for :default ,/EndListPersistentRequests/
end

#listpeersObject

Straigt forward, ListPeers, sometimes it may choke up and give you end list peers before your peers, in that case check the id



179
180
181
182
183
# File 'lib/ruby-fcp/fcp_client.rb', line 179

def listpeers
  id = @utils.id_generate
  @com.send_packet @utils.packet_mangler({"Identifier" => id, "WithMetaData" => true, "WithVolatile" => false},"ListPeers")
  wait_for id, /EndListPeers/
end

#modify_persistent_request(id, clienttoken, priorityclass) ⇒ Object



204
205
206
207
# File 'lib/ruby-fcp/fcp_client.rb', line 204

def modify_persistent_request(id,clienttoken,priorityclass)
  @com.send_packet @utils.packet_mangler({"Identifier" => id,"ClientToken" => clienttoken, "PriorityClass" => priorityclass}, "ModifyPersistentRequest")
  wait_for id, /PersistentRequestModified/
end

#new_ssk_pairObject

Uses GenerateSSK



186
187
188
189
190
# File 'lib/ruby-fcp/fcp_client.rb', line 186

def new_ssk_pair
  id = @utils.id_generate
  @com.send_packet @utils.packet_mangler({"Identifier" => id}, "GenerateSSK")
  wait_for id, /SSKKeypair/
end

#peerinfo(peer) ⇒ Object

returns information on a given peer not peers implements ListPeer



193
194
195
196
# File 'lib/ruby-fcp/fcp_client.rb', line 193

def peerinfo(peer)
  @com.send_packet @utils.packet_mangler({"NodeIdentifier" => peer,"WithVolatile" => false,"WithMetadata" => true}, "ListPeer")
  wait_for :peer, /Peer/
end

#proberequest(type, hopstolive = 25, wait = true) ⇒ Object



225
226
227
228
229
230
231
232
233
# File 'lib/ruby-fcp/fcp_client.rb', line 225

def proberequest(type,hopstolive=25,wait = true)
  id = @utils.id_generate
  @com.send_packet @utils.packet_mangler({"Identifier" => id,"Type" => type,"HopsToLive" => hopstolive}, "ProbeRequest")
  if wait
    wait_for id,/Probe/
  else
   id
  end
end

#put_complex_dir(uri, files, wait = true, opts = {}) ⇒ Object

simpler staight forward interface to ClientPutComplexDir, you provide with

Possible values of uri:

  • CHK@ will generate and return the key your data is acessible at

  • SSK@ must have insert key provided by GenerateSSK or the method new_ssk_pair

  • KSK@filename

As well as a list of hashes for files you want to put

File hashlist format:

  • name: lib/hello or index.html, / will interperate as directory nesting

  • filename: in case of disk location of file on disk

  • uploadfrom: ‘direct’, ‘disk’ or ‘redirect’

  • targeturi: in case of redirect, the location your are redirecting to

  • mimetype: not needed, but can be helpful

  • data: only nessecery in direct mode



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/ruby-fcp/fcp_client.rb', line 101

def put_complex_dir(uri, files, wait = true,opts = {})
  dirs = []
  id = @utils.id_generate
  files.each{ |f| dirs << f[:filename].split(File::SEPARATOR)[0...-1].join(File::SEPARATOR) + File::SEPARATOR if f.has_key? :filename }
  (dirs.uniq).each { |dir| ddarun(dir,true,false) }
  options = {"URI" => uri, "Identifier" => id}.merge(opts)
  files.each_with_index do |file, index|
    options["Files.#{index}.Name"] = file[:name]
    options["Files.#{index}.UploadFrom"] = file[:uploadfrom]
    options["Files.#{index}.DataLength"] = file[:data].bytesize if file.has_key? :data
    options["Files.#{index}.Filename"] = file[:filename] if file[:uploadfrom].include? 'disk'
    options["Files.#{index}.TargetURI"] = file[:targeturi] if file[:uploadfrom].include? 'redirect'
    options["Files.#{index}.Metadata.ContentType"] = file[:mimetype] if file.has_key? :mimetype
  end
  message = @utils.packet_mangler(options,"ClientPutComplexDir")
  files.each { |f| message << f[:data] if f.has_key? :data}
  puts message
  @com.send_packet message
  if wait
   wait_for(id,/PutFailed|PutSuccessful/)  
  else
   id
  end
end

#responsesObject

Simple attribute reader to display all responses recieved



26
27
28
# File 'lib/ruby-fcp/fcp_client.rb', line 26

def responses
  @com.responses
end

#simple_dir_put(uri, dir, wait = true, opts = {}) ⇒ Object

Simple directory upload, upload one directory all at once automates the TestDDA for you just provide uri and directory Implements ClientPutDiskDir

  • CHK@ will generate and return the key your data is acessible at

  • SSK@ must have insert key provided by GenerateSSK or the method new_ssk_pair

  • KSK@filename



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ruby-fcp/fcp_client.rb', line 76

def simple_dir_put(uri, dir, wait = true, opts={})
  id = @utils.id_generate
  ddarun(dir,true,false)
  options = {"Identifier" => id,"URI" => uri,"Filename" => dir, "Global" => 'true', "AllowUnreadableFiles" => 'true', "IncludeHiddenValues" => 'false'}.merge(opts)
  @com.send_packet @utils.packet_mangler(options,"ClientPutDiskDir")
  if wait
    wait_for(id,/PutFailed|PutSuccessful/) 
  else
    id
  end
end

#simple_get(uri, directory, wait = true, opts = {}) ⇒ Object

just provide uri and download path/directory Implements ClientGet



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/ruby-fcp/fcp_client.rb', line 147

def simple_get(uri,directory,wait = true, opts={})
  id = @utils.id_generate
  saveloc = File.join directory, uri.split('/')[-1]
  ddarun(directory,false, true)
  options = {"URI" => uri, "Identifier" => id, "ReturnType" => 'disk', "Filename" => saveloc, "TempFilename" => saveloc+".tmp" , "Persistence" => 'forever', "Global" => false, "Verbosity" => 1111111}.merge(opts)
  @com.send_packet @utils.packet_mangler(options,"ClientGet")
  if wait
   wait_for(id,/GetFailed|DataFound/) 
  else
   id
  end
end

#simple_put(uri, filename, wait = true, opts = {}) ⇒ Object

Simple interface to put a single file onto freenet from your disk uses ClientPut message

Possible values of uri:

  • CHK@ will generate and return the key your data is acessible at

  • SSK@ must have insert key provided by GenerateSSK or the method new_ssk_pair

  • KSK@filename



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ruby-fcp/fcp_client.rb', line 40

def simple_put(uri, filename, wait = true, opts = {})
  id = @utils.id_generate
  options = { "URI" => uri, "Identifier" => id, "UploadFrom" => 'disk', "Filename" => filename, "FileHash" => @utils.filehash_maker(id, filename,identifier), "Verbosity" => "111111111" }.merge(opts)
  options["TargetFilename"] = filename.split(File::SEPARATOR)[-1] if uri =~ /CHK@/
  @com.send_packet @utils.packet_mangler(options,"ClientPut")
  #@com.fcpackets.client_put uri, id, options
  if wait
    wait_for id, /PutFailed|PutSuccessful/
  else
    id
  end
end

#subscribe_usk(uri, wait = false, opts = {}) ⇒ Object

subscirbe to a usk, have to poll it yourself by using responses



210
211
212
213
214
215
216
217
218
# File 'lib/ruby-fcp/fcp_client.rb', line 210

def subscribe_usk(uri, wait = false ,opts ={})
  id = @utils.id_generate
  @com.send_packet @utils.packet_mangler({"URI" => uri, "Identifier" => id} ,"SubscribeUSK")
  if wait
    wait_for id, /SubscribedUSKUpdate/
  else
    id
  end
end

#unsubscribe_usk(id) ⇒ Object



220
221
222
223
# File 'lib/ruby-fcp/fcp_client.rb', line 220

def unsubscribe_usk(id)
  @com.send_packet "UnsubscribeUSK\nIdentifier=#{id}\nEndMessage\n"
  id
end

#wait_for(id, pattern) ⇒ Object

Waits for a specific pattern in a message identified by ID



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/ruby-fcp/fcp_client.rb', line 236

def wait_for(id, pattern)
  response = [ ]
  loop do
    begin
    x = @com.responses[id].pop
    print @com.responses[:error].pop
    rescue
    sleep(2)
    end
    unless x.nil?
      if x[:head] =~ pattern
        response << x
        x.each { |key, value| puts "#{key}=#{value}" }
        break
      elsif x[:head] =~ /ProtocolError/
        response << x
        x.each { |key, value| puts "#{key}=#{value}" }
        break
      else
        response << x
        x.each { |key, value| puts "#{key}=#{value}" }
      end
    else
      sleep(1)
    end
  end
  response
end

#wait_for_ever(id) ⇒ Object

Just wait and wait given a id



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/ruby-fcp/fcp_client.rb', line 266

def wait_for_ever(id)
  loop do
    begin
      x = @com.responses[id].pop
    rescue
      print '.'
      sleep(2)
      print @com.responses[:error]
      print @com.responses[:default]
    end
    unless x.nil?
      x.each { |key, value| puts "#{key}=#{value}" }
    else
      print '.'
      sleep(1)
      puts @com.responses[:error]
      print @com.responses[:default]
    end
  end
end