vintikzzz/video-torrent-info

View on GitHub
ext/torrent_client/torrent_client.cpp

Summary

Maintainability
Test Coverage
#include <stdlib.h>
#include <csignal>
#include <sstream>
#include <iostream>
#include <exception>
#include <stdio.h>
#include <unistd.h>
#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/session.hpp"
#include "rice/Class.hpp"
#include "rice/Exception.hpp"

using namespace Rice;

struct MyException : public std::exception
{
   std::string s;
   MyException(std::string ss) : s(ss) {}
   ~MyException() throw () {}
   const char* what() const throw() { return s.c_str(); }
};
void term(int signum)
{
    exit(1);
}

void load(String torrent_path, int idx, int size, String save_path, int port1, int port2, int timeout)
{
  using namespace libtorrent;
  using namespace std;

  session s;
  libtorrent::error_code ec;
  std::ostringstream err;
  signal(SIGINT,  term);
  signal(SIGTERM, term);
  s.listen_on(std::make_pair(port1, port2), ec);
  if (ec)
  {
    err << "failed to open listen socket: " << ec.message().c_str();
    throw MyException(err.str());
  }
  add_torrent_params p;
  p.save_path = save_path.c_str();
  p.ti = new torrent_info(torrent_path.c_str(), ec);
  if (ec)
  {
    err << "failed to load torrent info: " << ec.message().c_str();
    throw MyException(err.str());
  }
  torrent_handle h = s.add_torrent(p, ec);
  if (ec)
  {
    err << "failed to add torrent: " << ec.message().c_str();
    throw MyException(err.str());
  }
  if (size > 0) {
    h.set_sequential_download(true);
  }
  int index = 0;
  for (torrent_info::file_iterator i = p.ti->begin_files(); i != p.ti->end_files(); ++i, ++index)
  {
    if (index == idx) {
      if (size > i->size) size = i->size;
    } else {
      h.file_priority(index, 0);
    }
  }

  size_type temp = 0;
  int t = 0;
  bool finish = false;

  while (true)
  {
    torrent_status st = h.status();
    if (st.is_finished == true) {
      finish = true;
    }
    if (st.total_done > temp)
    {
      // std::cout << st.total_done;
      temp = st.total_done;
    }
    if (size > 0 && temp >= size)
    {
      finish = true;
    }
    if (t >= timeout * 1000)
    {
      finish = true;
    }
    if (finish) {
      s.abort();
      return;
    }
    t++;
    usleep(1000);
  }
}
void handle_my_exception(std::exception const & ex)
{
  throw Exception(rb_eRuntimeError, ex.what());
}
extern "C"
void Init_torrent_client()
{
  Class rb_cVideoTorrentInfo = define_class("VideoTorrentInfo");
  Class rb_cTorrentClient =
    define_class_under(rb_cVideoTorrentInfo, "TorrentClient")
    .add_handler<MyException>(handle_my_exception)
    .define_method("load", &load);
}