Class: Sinatra::Torrent::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/sinatra/torrent/activerecord.rb

Overview

This is the wrapper class used by sinatra-torrent to communicate with any database system

Defined Under Namespace

Classes: DelayedJob, Peer, Torrent

Constant Summary collapse

@@settings =

Default settings for the connection

{
  'adapter' => 'sqlite3',
  'database' => ':memory:'
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDatabase

Makes sure the table is present & ready, log in using the settings



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/sinatra/torrent/activerecord.rb', line 24

def initialize
  @db = ActiveRecord::Base.establish_connection(@@settings)

  unless Torrent.table_exists?
    ActiveRecord::Schema.define do
      create_table :torrents do |table|
        table.text :path, :null => false
        table.text :metadata, :null => false
        table.string :infohash, :null => false
        table.timestamp :timestamp, :null => false
      end
  
      add_index :torrents, :infohash, :unique => true
    end
  end
  
  unless Peer.table_exists?
    ActiveRecord::Schema.define do
      create_table :peers do |table|
        table.string :torrent_infohash, :null => false
        table.string :peer_id
        table.integer :port
        table.integer :uploaded
        table.integer :downloaded
        table.integer :left
        table.string :ip
    
        table.timestamps
      end
  
      add_index :peers, [:peer_id,:torrent_infohash], :unique => true
    end
  end
  
  unless DelayedJob.table_exists?
    ActiveRecord::Schema.define do
      create_table :delayed_jobs do |table|
        table.string :filename, :null => false
        
        table.timestamp :created_at
      end
  
      add_index :delayed_jobs, :filename, :unique => true
    end
  end
end

Class Method Details

.settings=(settings) ⇒ Object

Allows the set up of Active Record

Raises:

  • (ArgumentError)


18
19
20
21
# File 'lib/sinatra/torrent/activerecord.rb', line 18

def self.settings=(settings)
  raise ArgumentError if !settings.is_a?(Hash)
  @@settings = settings
end

Instance Method Details

#add_hashjob(filename) ⇒ Object

Registers a file to be hashed offline



153
154
155
156
157
# File 'lib/sinatra/torrent/activerecord.rb', line 153

def add_hashjob(filename)
  DelayedJob.find_or_create_by_filename(filename)
  # return eta in seconds, where possible
  nil
end

#announce(params) ⇒ Object

Announce!



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/sinatra/torrent/activerecord.rb', line 139

def announce(params)
  peer = Peer.find_or_create_by_torrent_infohash_and_peer_id(params['info_hash'],params['peer_id'])
    
  peer.ip ||= params['ip']
  peer.port ||= params['port']
  peer.uploaded = params['uploaded']
  peer.downloaded = params['downloaded']
  peer.left = params['left']
    
  peer.save
end

#list_hashjobsObject

Lists outstanding files to be hashed, by request date hopefully!



160
161
162
# File 'lib/sinatra/torrent/activerecord.rb', line 160

def list_hashjobs
  DelayedJob.find(:all,:order => 'created_at DESC').collect{|dj| dj.filename}
end

#peers_by_infohash(infohash, peer_ids = [], peers = 50) ⇒ Object

Lists the currently registered peers for a given torrent if peer_ids is populated with any peer ids then they will be excluded from the list



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/sinatra/torrent/activerecord.rb', line 113

def peers_by_infohash(infohash, peer_ids = [], peers = 50)
  begin
    # TODO: Random order & actual number of peers (if peer_ids is in returned amount)
    Peer.find_by_torrent_infohash(infohash,:limit => peers).delete_if {|peer| peer_ids.include? peer.peer_id}.map do |peer|
      {
        'peer id' => peer.peer_id,
        'ip'      => peer.ip,
        'port'    => peer.port
      }
    end
  rescue NoMethodError
    []
  end
end

#remove_hashjob(filename) ⇒ Object

Removes a file from the ‘to be hashed’ list



165
166
167
# File 'lib/sinatra/torrent/activerecord.rb', line 165

def remove_hashjob(filename)
  DelayedJob.find_by_filename(filename).delete rescue false
end

#store_torrent(path, timestamp, metadata, infohash) ⇒ Object

Stores a torrent in the database



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/sinatra/torrent/activerecord.rb', line 72

def store_torrent(path,timestamp,,infohash)
  # Make sure this path and this infohash don't already exist
  Torrent.find_by_path_and_timestamp(path,timestamp).delete rescue nil
  Torrent.find_by_infohash(infohash).delete rescue nil
    
  Torrent.new(
    :path => path,
    :metadata => ,
    :infohash => infohash,
    :timestamp => timestamp
  ).save
end

#torrent_by_infohash(infohash) ⇒ Object

Find a torrent by infohash



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/sinatra/torrent/activerecord.rb', line 86

def torrent_by_infohash(infohash)
  torrent = Torrent.find_by_infohash(infohash)
  return false if torrent.nil?
    
  {
    'metadata' => torrent.,
    'infohash' => torrent.infohash,
    'path'     => torrent.path,
    'timestamp'=> torrent.timestamp
  }
end

#torrent_by_path_and_timestamp(path, timestamp) ⇒ Object

Finds a torrent by



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/sinatra/torrent/activerecord.rb', line 99

def torrent_by_path_and_timestamp(path,timestamp)
  torrent = Torrent.find_by_path_and_timestamp(path,timestamp)
  return false if torrent.nil?
    
  {
    'metadata' => torrent.,
    'infohash' => torrent.infohash,
    'path'     => torrent.path,
    'timestamp'=> torrent.timestamp
  }
end

#torrent_info(infohash) ⇒ Object

Returns information about the torrent as provided by it’s infohash



129
130
131
132
133
134
135
136
# File 'lib/sinatra/torrent/activerecord.rb', line 129

def torrent_info(infohash)
  info = Peer.find_by_sql(["SELECT (SELECT COUNT(*) FROM 'peers' WHERE `left` != 0 AND `torrent_infohash` = ?) as `incomplete`, (SELECT COUNT(*) FROM 'peers' WHERE `left` == 0 AND `torrent_infohash` = ?) as `complete`",infohash, infohash])[0]
    
  {
    'complete' => info.complete,
    'incomplete' => info.incomplete
  }
end