<commit_before>#include <iostream>

#include <btBulletDynamicsCommon.h>

extern "C" {

btDiscreteDynamicsWorld *createDynamicsWorld() {
    // TODO we should package up broadphase, collisionConfig, dispatcher and solver
    // into a struct and free them all with a destroyBullet function

    btBroadphaseInterface* broadphase = new btDbvtBroadphase();

    btDefaultCollisionConfiguration* collisionConfig = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfig);

    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

    btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);

    dynamicsWorld->setGravity(btVector3(0, -10, 0));

    return dynamicsWorld;
}

int testBullet(btDiscreteDynamicsWorld *dynamicsWorld)
{
    btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 1);

    btCollisionShape* fallShape = new btSphereShape(1);

    btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, -1, 0)));
    btRigidBody::btRigidBodyConstructionInfo
            groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0, 0, 0));
    btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
    dynamicsWorld->addRigidBody(groundRigidBody);

    btDefaultMotionState* fallMotionState =
            new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50, 0)));
    btScalar mass = 1;
    btVector3 fallInertia(0, 0, 0);
    fallShape->calculateLocalInertia(mass, fallInertia);
    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, fallInertia);
    btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
    dynamicsWorld->addRigidBody(fallRigidBody);

    for (int i = 0; i < 300; i++) {
            dynamicsWorld->stepSimulation(1 / 60.f, 10);

            btTransform trans;
            fallRigidBody->getMotionState()->getWorldTransform(trans);

            std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
    }

    dynamicsWorld->removeRigidBody(fallRigidBody);
    delete fallRigidBody->getMotionState();
    delete fallRigidBody;

    dynamicsWorld->removeRigidBody(groundRigidBody);
    delete groundRigidBody->getMotionState();
    delete groundRigidBody;

    delete fallShape;

    delete groundShape;

    return 0;
}

void destroyBullet(btDiscreteDynamicsWorld *dynamicsWorld) {
    delete dynamicsWorld;
        // delete solver;
        // delete collisionConfiguration;
        // delete dispatcher;
        // delete broadphase;
}

}<commit_msg>Remove old cbits<commit_after><|endoftext|>


<commit_before>#pragma once

#include <exception>
#include <regex>

// ----------------------------------------------------------------------

namespace virus_name
{
    namespace _internal
    {
#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#endif

        const std::regex cdc{"^([A-Z][A-Z][A-Z]?) "};

          // [1] - type+subtype, [2] - host, [3] - location, [4] - isolation-number (omitting leading zeros), [5] - century, [6] - year (2 last digit), [7] - reassortant and passage
        const std::regex international{"^([AB][^/]*)/(?:([^/]+)/)?([^/]+)/0*([^/]+)/(19|20)?(\\d\\d)(?:(?:\\s+|__)(.+))?$"};

        inline std::string make_year(const std::smatch& m)
        {
            std::string year;
            if (m[5].length())
                year = m[5].str() + m[6].str();
            else if (m[6].str()[0] > '2')
                year = "19" + m[6].str();
            else
                year = "20" + m[6].str();
            return year;
        }

#pragma GCC diagnostic pop
    }

// ----------------------------------------------------------------------

    class Unrecognized : public std::runtime_error { public: using std::runtime_error::runtime_error; };

// ----------------------------------------------------------------------

    std::string normalize(std::string name);

// ----------------------------------------------------------------------

    std::string normalize(std::string name);

      // returned cdc abbreviation starts with #
    inline std::string location(std::string name)
    {
        using namespace _internal;
        std::string location;
        std::smatch m;
        if (std::regex_search(name, m, cdc))
            location = "#" + m[1].str();
        else if (std::regex_match(name, m, international))
            location = m[3].str();
        else
            throw Unrecognized{"No location in " + name};
        return location;
    }

// ----------------------------------------------------------------------

    inline std::string virus_type(std::string name)
    {
        using namespace _internal;
        std::string virus_type;
        std::smatch m;
        if (std::regex_match(name, m, international))
            virus_type = m[1].str();
        else
            throw Unrecognized{"No virus_type in " + name};
        return virus_type;

    } // AntigenSerum::virus_type

// ----------------------------------------------------------------------

    inline std::string year(std::string name)
    {
        using namespace _internal;
        std::string year;
        std::smatch m;
        if (std::regex_match(name, m, international))
            year = make_year(m);
        else
            throw Unrecognized{"No year in " + name};
        return year;

    } // AntigenSerum::year

// ----------------------------------------------------------------------

    inline void split(std::string name, std::string& virus_type, std::string& host, std::string& location, std::string& isolation, std::string& year, std::string& passage)
    {
        using namespace _internal;
        std::smatch m;
        if (std::regex_match(name, m, international)) {
            virus_type = m[1].str();
            host = m[2].str();
            location = m[3].str();
            isolation = m[4].str();
            year = make_year(m);
            passage = m[7].str();
        }
        else
            throw Unrecognized{"Cannot split " + name};
    }

}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>match_threshold development<commit_after>#pragma once

#include <exception>
#include <regex>

// ----------------------------------------------------------------------

namespace virus_name
{
    namespace _internal
    {
#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wexit-time-destructors"
#endif

        const std::regex cdc{"^([A-Z][A-Z][A-Z]?) "};

          // [1] - type+subtype, [2] - host, [3] - location, [4] - isolation-number (omitting leading zeros), [5] - century, [6] - year (2 last digit), [7] - reassortant and passage
        const std::regex international{"^([AB][^/]*)/(?:([^/]+)/)?([^/]+)/0*([^/]+)/(19|20)?(\\d\\d)(?:(?:\\s+|__)(.+))?$"};

        inline std::string make_year(const std::smatch& m)
        {
            std::string year;
            if (m[5].length())
                year = m[5].str() + m[6].str();
            else if (m[6].str()[0] > '2')
                year = "19" + m[6].str();
            else
                year = "20" + m[6].str();
            return year;
        }

#pragma GCC diagnostic pop
    }

// ----------------------------------------------------------------------

    class Unrecognized : public std::runtime_error { public: using std::runtime_error::runtime_error; };

// ----------------------------------------------------------------------

    std::string normalize(std::string name);

// ----------------------------------------------------------------------

    std::string normalize(std::string name);

      // returned cdc abbreviation starts with #
    inline std::string location(std::string name)
    {
        using namespace _internal;
        std::string location;
        std::smatch m;
        if (std::regex_search(name, m, cdc))
            location = "#" + m[1].str();
        else if (std::regex_match(name, m, international))
            location = m[3].str();
        else
            throw Unrecognized{"No location in " + name};
        return location;
    }

// ----------------------------------------------------------------------

    inline std::string virus_type(std::string name)
    {
        using namespace _internal;
        std::string virus_type;
        std::smatch m;
        if (std::regex_match(name, m, international))
            virus_type = m[1].str();
        else
            throw Unrecognized{"No virus_type in " + name};
        return virus_type;

    } // AntigenSerum::virus_type

// ----------------------------------------------------------------------

    inline std::string year(std::string name)
    {
        using namespace _internal;
        std::string year;
        std::smatch m;
        if (std::regex_match(name, m, international))
            year = make_year(m);
        else
            throw Unrecognized{"No year in " + name};
        return year;

    } // AntigenSerum::year

// ----------------------------------------------------------------------

    inline void split(std::string name, std::string& virus_type, std::string& host, std::string& location, std::string& isolation, std::string& year, std::string& passage)
    {
        std::smatch m;
        if (std::regex_match(name, m, _internal::international)) {
            virus_type = m[1].str();
            host = m[2].str();
            location = m[3].str();
            isolation = m[4].str();
            year = _internal::make_year(m);
            passage = m[7].str();
        }
        else
            throw Unrecognized{"Cannot split " + name};
    }

// ----------------------------------------------------------------------

      // Extracts virus name without passage, reassortant, extra,
      // etc. and calculates match threshold (to use with
      // acmacs_chart::Antigens::find_by_name_matching), match threshold is a square
      // of virus name length.
    inline size_t match_threshold(std::string name)
    {
        size_t result = 0;
        std::smatch m;
        if (std::regex_match(name, m, _internal::international)) {
              // find end of year (m[6])
            const auto end_of_year_offset = static_cast<size_t>(m[6].second - name.begin());
            result = end_of_year_offset * end_of_year_offset;
        }
        return result;
    }

// ----------------------------------------------------------------------

}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include "core/image.h"
#include "core/filesystem.h"
#include "core/base64.h"
#include "core/rgb.h"
#include "tests/testbase.h"

#include "catch.hpp"

// 4x4 image without transperency
// white  / red
// green / blue
const char* const TEST_IMAGE =
    "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABmJLR0QA/wD/"
    "AP+"
    "gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QgdFSAdb6CP5AAAABVJREFUCNcFw"
    "QEBAAAAgBD/TxeqIDQz2gX7fv3PJgAAAABJRU5ErkJggg==";

TEST_CASE("image-load", "[img]")
{
  FileSystem fs;
  auto       catalog = FileSystemRootCatalog::AddRoot(&fs);
  catalog->RegisterFileData("white", base64::Decode(TEST_IMAGE));

  auto loaded = LoadImage(&fs, "white", AlphaLoad::Remove);
  REQUIRE(loaded.error == "");
  REQUIRE_FALSE(loaded.image.HasAlpha());

  REQUIRE(loaded.image.GetHeight() == 2);
  REQUIRE(loaded.image.GetWidth() == 2);

  // upper left
  SECTION("load-white")
  {
    const auto pixel = loaded.image.GetPixel(0, 1);
    const auto white = Rgba{1.0f, 1.0f, 1.0f, 1.0f};
    REQUIRE(pixel == approx(white));
  }

  // upper right
  SECTION("load-red")
  {
    const auto pixel = loaded.image.GetPixel(1, 1);
    const auto red   = Rgba{1.0f, 0.0f, 0.0f, 1.0f};
    REQUIRE(pixel == approx(red));
  }

  // lower left
  SECTION("load-green")
  {
    const auto pixel = loaded.image.GetPixel(0, 0);
    const auto green = Rgba{0.0f, 1.0f, 0.0f, 1.0f};
    REQUIRE(pixel == approx(green));
  }

  // lower right
  SECTION("load-blue")
  {
    const auto pixel = loaded.image.GetPixel(1, 0);
    const auto blue  = Rgba{0.0f, 0.0f, 1.0f, 1.0f};
    REQUIRE(pixel == approx(blue));
  }
}
<commit_msg>added more image tests<commit_after>#include "core/image.h"
#include "core/filesystem.h"
#include "core/base64.h"
#include "core/rgb.h"
#include "tests/testbase.h"

#include "catch.hpp"

// 4x4 image without transperency
// white  / red
// green / blue
const char* const TEST_IMAGE =
    "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABmJLR0QA/wD/"
    "AP+"
    "gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QgdFSAdb6CP5AAAABVJREFUCNcFw"
    "QEBAAAAgBD/TxeqIDQz2gX7fv3PJgAAAABJRU5ErkJggg==";

TEST_CASE("image-load", "[img]")
{
  FileSystem fs;
  auto       catalog = FileSystemRootCatalog::AddRoot(&fs);
  catalog->RegisterFileData("white", base64::Decode(TEST_IMAGE));

  auto loaded = LoadImage(&fs, "white", AlphaLoad::Remove);
  REQUIRE(loaded.error == "");
  REQUIRE_FALSE(loaded.image.HasAlpha());

  REQUIRE(loaded.image.GetHeight() == 2);
  REQUIRE(loaded.image.GetWidth() == 2);

  // upper left
  SECTION("load-white")
  {
    const auto pixel = loaded.image.GetPixel(0, 1);
    const auto white = Rgba{1.0f, 1.0f, 1.0f, 1.0f};
    REQUIRE(pixel == approx(white));
  }

  // upper right
  SECTION("load-red")
  {
    const auto pixel = loaded.image.GetPixel(1, 1);
    const auto red   = Rgba{1.0f, 0.0f, 0.0f, 1.0f};
    REQUIRE(pixel == approx(red));
  }

  // lower left
  SECTION("load-green")
  {
    const auto pixel = loaded.image.GetPixel(0, 0);
    const auto green = Rgba{0.0f, 1.0f, 0.0f, 1.0f};
    REQUIRE(pixel == approx(green));
  }

  // lower right
  SECTION("load-blue")
  {
    const auto pixel = loaded.image.GetPixel(1, 0);
    const auto blue  = Rgba{0.0f, 0.0f, 1.0f, 1.0f};
    REQUIRE(pixel == approx(blue));
  }
}

TEST_CASE("image solid", "[img]")
{
  Image img;
  img.Setup(3, 3, false);

  SECTION("default-is-black")
  {
    REQUIRE(img.GetPixel(0, 0) == approx(Rgba(0, 0, 0, 1)));
    REQUIRE(img.GetPixel(1, 0) == approx(Rgba(0, 0, 0, 1)));
  }

  SECTION("can set and get color")
  {
    REQUIRE(img.GetPixel(0, 0) == approx(Rgba(0, 0, 0, 1)));
    Rgba color{1, 1, 1, 1};
    img.SetPixel(0, 0, color);
    REQUIRE(img.GetPixel(0, 0) == approx(color));
  }
}

TEST_CASE("image transparent", "[img]")
{
  Image img;
  img.Setup(4, 4, true);

  SECTION("default-is-black")
  {
    REQUIRE(img.GetPixel(0, 0) == approx(Rgba(0, 0, 0, 0)));
    REQUIRE(img.GetPixel(1, 1) == approx(Rgba(0, 0, 0, 0)));
  }

  SECTION("can set and get color")
  {
    REQUIRE(img.GetPixel(0, 0) == approx(Rgba(0, 0, 0, 0)));
    Rgba color{1, 1, 1, 1};
    img.SetPixel(0, 0, color);
    REQUIRE(img.GetPixel(0, 0) == approx(color));
  }
}

// todo: add paint test
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/torrent_handle.hpp>
#include <boost/python.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().end();
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<float> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<float>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

void replace_trackers(torrent_handle& info, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    info.replace_trackers(result);
}

list get_download_queue(torrent_handle& handle)
{
    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = std::make_pair(
                boost::lexical_cast<std::string>(i->blocks[k].peer.address()), i->blocks[k].peer.port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

    return_value_policy<copy_const_reference> copy;

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", range(begin_trackers, end_trackers))
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("has_metadata", _(&torrent_handle::has_metadata))
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("pause", _(&torrent_handle::pause))
        .def("resume", _(&torrent_handle::resume))

        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))

        .def("piece_availability", piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", prioritize_pieces)
        .def("piece_prioritize", piece_priorities)
        .def("prioritize_files", prioritize_files)
        .def("use_interface", &torrent_handle::use_interface)
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
        .def("save_resume_data", _(&torrent_handle::save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", force_reannounce)
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", set_peer_upload_limit)
        .def("set_peer_download_limit", set_peer_download_limit)
        .def("connect_peer", connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(&torrent_handle::move_storage))
        .def("info_hash", _(&torrent_handle::info_hash))
        ;
}

<commit_msg>Add force_recheck to the bindings<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/torrent_handle.hpp>
#include <boost/python.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().end();
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<float> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<float>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

void replace_trackers(torrent_handle& info, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    info.replace_trackers(result);
}

list get_download_queue(torrent_handle& handle)
{
    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = std::make_pair(
                boost::lexical_cast<std::string>(i->blocks[k].peer.address()), i->blocks[k].peer.port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

    return_value_policy<copy_const_reference> copy;

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", range(begin_trackers, end_trackers))
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("has_metadata", _(&torrent_handle::has_metadata))
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("pause", _(&torrent_handle::pause))
        .def("resume", _(&torrent_handle::resume))

        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))

        .def("piece_availability", piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", prioritize_pieces)
        .def("piece_prioritize", piece_priorities)
        .def("prioritize_files", prioritize_files)
        .def("use_interface", &torrent_handle::use_interface)
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
        .def("save_resume_data", _(&torrent_handle::save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", force_reannounce)
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", set_peer_upload_limit)
        .def("set_peer_download_limit", set_peer_download_limit)
        .def("connect_peer", connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(&torrent_handle::move_storage))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        ;
}

<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <boost/python/tuple.hpp>
#include <libtorrent/torrent_handle.hpp>
#include <libtorrent/peer_info.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<size_type> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

list file_priorities(torrent_handle& handle)
{
    list ret;
    std::vector<int> priorities = handle.file_priorities();

    for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
        ret.append(*i);

    return ret;
}

void replace_trackers(torrent_handle& h, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    h.replace_trackers(result);
}

list trackers(torrent_handle &h)
{
    list ret;
    std::vector<announce_entry> const trackers = h.trackers();
    for (std::vector<announce_entry>::const_iterator i = trackers.begin(), end(trackers.end()); i != end; ++i)
    {
        dict d;
        d["url"] = i->url;
        d["tier"] = i->tier;
        d["fail_limit"] = i->fail_limit;
        d["fails"] = i->fails;
        d["source"] = i->source;
        d["verified"] = i->verified;
        d["updating"] = i->updating;
        d["start_sent"] = i->start_sent;
        d["complete_sent"] = i->complete_sent;
        ret.append(d);
    }
    return ret;
}

list get_download_queue(torrent_handle& handle)
{
    using boost::python::make_tuple;

    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = make_tuple(
                boost::lexical_cast<std::string>(i->blocks[k].peer().address()), i->blocks[k].peer().port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void add_piece(torrent_handle& th, int piece, char const *data, int flags)
{
   th.add_piece(piece, data, flags);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

    void (torrent_handle::*move_storage0)(std::string const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*rename_file0)(int, std::string const&) const = &torrent_handle::rename_file;

#if TORRENT_USE_WSTRING
    void (torrent_handle::*move_storage1)(std::wstring const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*rename_file1)(int, std::wstring const&) const = &torrent_handle::rename_file;
#endif

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", trackers)
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("pause", _(&torrent_handle::pause), arg("flags") = 0)
        .def("resume", _(&torrent_handle::resume))
        .def("clear_error", _(&torrent_handle::clear_error))
        .def("set_priority", _(&torrent_handle::set_priority))

        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
#ifndef TORRENT_NO_DEPRECATE
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("has_metadata", _(&torrent_handle::has_metadata))
#endif
        .def("add_piece", add_piece)
        .def("read_piece", _(&torrent_handle::read_piece))
        .def("set_piece_deadline", _(&torrent_handle::set_piece_deadline)
            , (arg("index"), arg("deadline"), arg("flags") = 0))
        .def("piece_availability", &piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", &prioritize_pieces)
        .def("piece_priorities", &piece_priorities)
        .def("prioritize_files", &prioritize_files)
        .def("file_priorities", &file_priorities)
        .def("use_interface", &torrent_handle::use_interface)
        .def("save_resume_data", _(&torrent_handle::save_resume_data), arg("flags") = 0)
        .def("need_save_resume_data", _(&torrent_handle::need_save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", &force_reannounce)
        .def("force_dht_announce", _(&torrent_handle::force_dht_announce))
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_mode", _(&torrent_handle::set_upload_mode))
        .def("set_share_mode", _(&torrent_handle::set_share_mode))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", &set_peer_upload_limit)
        .def("set_peer_download_limit", &set_peer_download_limit)
        .def("connect_peer", &connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(move_storage0))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        .def("rename_file", _(rename_file0))
#if TORRENT_USE_WSTRING
        .def("move_storage", _(move_storage1))
        .def("rename_file", _(rename_file1))
#endif
        ;

    enum_<torrent_handle::pause_flags_t>("pause_flags_t")
        .value("graceful_pause", torrent_handle::graceful_pause)
    ;

    enum_<torrent_handle::save_resume_flags_t>("save_resume_flags_t")
        .value("flush_disk_cache", torrent_handle::flush_disk_cache)
    ;

    enum_<torrent_handle::deadline_flags>("deadline_flags")
        .value("alert_when_available", torrent_handle::alert_when_available)
    ;

}
<commit_msg>fix torrent_handle.status in python binding<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <boost/python/tuple.hpp>
#include <libtorrent/torrent_handle.hpp>
#include <libtorrent/peer_info.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<size_type> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

list file_priorities(torrent_handle& handle)
{
    list ret;
    std::vector<int> priorities = handle.file_priorities();

    for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
        ret.append(*i);

    return ret;
}

void replace_trackers(torrent_handle& h, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    h.replace_trackers(result);
}

list trackers(torrent_handle &h)
{
    list ret;
    std::vector<announce_entry> const trackers = h.trackers();
    for (std::vector<announce_entry>::const_iterator i = trackers.begin(), end(trackers.end()); i != end; ++i)
    {
        dict d;
        d["url"] = i->url;
        d["tier"] = i->tier;
        d["fail_limit"] = i->fail_limit;
        d["fails"] = i->fails;
        d["source"] = i->source;
        d["verified"] = i->verified;
        d["updating"] = i->updating;
        d["start_sent"] = i->start_sent;
        d["complete_sent"] = i->complete_sent;
        ret.append(d);
    }
    return ret;
}

list get_download_queue(torrent_handle& handle)
{
    using boost::python::make_tuple;

    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = make_tuple(
                boost::lexical_cast<std::string>(i->blocks[k].peer().address()), i->blocks[k].peer().port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void add_piece(torrent_handle& th, int piece, char const *data, int flags)
{
   th.add_piece(piece, data, flags);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

    void (torrent_handle::*move_storage0)(std::string const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*rename_file0)(int, std::string const&) const = &torrent_handle::rename_file;

#if TORRENT_USE_WSTRING
    void (torrent_handle::*move_storage1)(std::wstring const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*rename_file1)(int, std::wstring const&) const = &torrent_handle::rename_file;
#endif

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status), arg("flags") = 0xffffffff)
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", trackers)
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("pause", _(&torrent_handle::pause), arg("flags") = 0)
        .def("resume", _(&torrent_handle::resume))
        .def("clear_error", _(&torrent_handle::clear_error))
        .def("set_priority", _(&torrent_handle::set_priority))

        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
#ifndef TORRENT_NO_DEPRECATE
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("has_metadata", _(&torrent_handle::has_metadata))
#endif
        .def("add_piece", add_piece)
        .def("read_piece", _(&torrent_handle::read_piece))
        .def("set_piece_deadline", _(&torrent_handle::set_piece_deadline)
            , (arg("index"), arg("deadline"), arg("flags") = 0))
        .def("piece_availability", &piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", &prioritize_pieces)
        .def("piece_priorities", &piece_priorities)
        .def("prioritize_files", &prioritize_files)
        .def("file_priorities", &file_priorities)
        .def("use_interface", &torrent_handle::use_interface)
        .def("save_resume_data", _(&torrent_handle::save_resume_data), arg("flags") = 0)
        .def("need_save_resume_data", _(&torrent_handle::need_save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", &force_reannounce)
        .def("force_dht_announce", _(&torrent_handle::force_dht_announce))
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_mode", _(&torrent_handle::set_upload_mode))
        .def("set_share_mode", _(&torrent_handle::set_share_mode))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", &set_peer_upload_limit)
        .def("set_peer_download_limit", &set_peer_download_limit)
        .def("connect_peer", &connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(move_storage0))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        .def("rename_file", _(rename_file0))
#if TORRENT_USE_WSTRING
        .def("move_storage", _(move_storage1))
        .def("rename_file", _(rename_file1))
#endif
        ;

    enum_<torrent_handle::pause_flags_t>("pause_flags_t")
        .value("graceful_pause", torrent_handle::graceful_pause)
    ;

    enum_<torrent_handle::save_resume_flags_t>("save_resume_flags_t")
        .value("flush_disk_cache", torrent_handle::flush_disk_cache)
    ;

    enum_<torrent_handle::deadline_flags>("deadline_flags")
        .value("alert_when_available", torrent_handle::alert_when_available)
    ;

}
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/torrent_handle.hpp>
#include <boost/python.hpp>
#include <boost/python/tuple.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().end();
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<size_type> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

list file_priorities(torrent_handle& handle)
{
    list ret;
    std::vector<int> priorities = handle.file_priorities();

    for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
        ret.append(*i);

    return ret;
}

void replace_trackers(torrent_handle& info, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    info.replace_trackers(result);
}

list get_download_queue(torrent_handle& handle)
{
    using boost::python::make_tuple;

    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = make_tuple(
                boost::lexical_cast<std::string>(i->blocks[k].peer.address()), i->blocks[k].peer.port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void add_piece(torrent_handle& th, int piece, char const *data, int flags)
{
   th.add_piece(piece, data, flags);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

    void (torrent_handle::*move_storage0)(fs::path const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*move_storage1)(fs::wpath const&) const = &torrent_handle::move_storage;

    void (torrent_handle::*rename_file0)(int, fs::path const&) const = &torrent_handle::rename_file;
    void (torrent_handle::*rename_file1)(int, fs::wpath const&) const = &torrent_handle::rename_file;

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

    return_value_policy<copy_const_reference> copy;

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", range(begin_trackers, end_trackers))
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("has_metadata", _(&torrent_handle::has_metadata))
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("pause", _(&torrent_handle::pause))
        .def("resume", _(&torrent_handle::resume))
        .def("clear_error", _(&torrent_handle::clear_error))

        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
#ifndef TORRENT_NO_DEPRECATE
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
#endif
        .def("add_piece", add_piece)
        .def("piece_availability", piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", prioritize_pieces)
        .def("piece_prioritize", piece_priorities)
        .def("prioritize_files", prioritize_files)
        .def("file_priorities", file_priorities)
        .def("use_interface", &torrent_handle::use_interface)
        .def("save_resume_data", _(&torrent_handle::save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", force_reannounce)
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", set_peer_upload_limit)
        .def("set_peer_download_limit", set_peer_download_limit)
        .def("connect_peer", connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(move_storage0))
        .def("move_storage", _(move_storage1))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        .def("rename_file", _(rename_file0))
        .def("rename_file", _(rename_file1))
        ;
}
<commit_msg>added read_piece() to python binding<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/torrent_handle.hpp>
#include <boost/python.hpp>
#include <boost/python/tuple.hpp>
#include <boost/lexical_cast.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  list url_seeds(torrent_handle& handle)
  {
      list ret;
      std::set<std::string> urls;
      {
          allow_threading_guard guard;
          urls = handle.url_seeds();
      }

      for (std::set<std::string>::iterator i(urls.begin())
          , end(urls.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_availability(torrent_handle& handle)
  {
      list ret;
      std::vector<int> avail;
      {
          allow_threading_guard guard;
          handle.piece_availability(avail);
      }

      for (std::vector<int>::iterator i(avail.begin())
          , end(avail.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  list piece_priorities(torrent_handle& handle)
  {
      list ret;
      std::vector<int> prio;
      {
          allow_threading_guard guard;
          prio = handle.piece_priorities();
      }

      for (std::vector<int>::iterator i(prio.begin())
          , end(prio.end()); i != end; ++i)
          ret.append(*i);
      return ret;
  }

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_handle& i)
  {
      allow_threading_guard guard;
      return i.trackers().end();
  }

} // namespace unnamed

list file_progress(torrent_handle& handle)
{
    std::vector<size_type> p;

    {
        allow_threading_guard guard;
        p.reserve(handle.get_torrent_info().num_files());
        handle.file_progress(p);
    }

    list result;

    for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
        result.append(*i);

    return result;
}

list get_peer_info(torrent_handle const& handle)
{
    std::vector<peer_info> pi;

    {
        allow_threading_guard guard;
        handle.get_peer_info(pi);
    }

    list result;

    for (std::vector<peer_info>::iterator i = pi.begin(); i != pi.end(); ++i)
        result.append(*i);

    return result;
}

void prioritize_pieces(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_pieces(result);
      return;
   }
}

void prioritize_files(torrent_handle& info, object o)
{
   std::vector<int> result;
   try
   {
      object iter_obj = object( handle<>( PyObject_GetIter( o.ptr() ) ));
      while( 1 )
      {
         object obj = extract<object>( iter_obj.attr( "next" )() );
         result.push_back(extract<int const>( obj ));
      }
   }
   catch( error_already_set )
   {
      PyErr_Clear();
      info.prioritize_files(result);
      return;
   }
}

list file_priorities(torrent_handle& handle)
{
    list ret;
    std::vector<int> priorities = handle.file_priorities();

    for (std::vector<int>::iterator i = priorities.begin(); i != priorities.end(); ++i)
        ret.append(*i);

    return ret;
}

void replace_trackers(torrent_handle& info, object trackers)
{
    object iter(trackers.attr("__iter__")());

    std::vector<announce_entry> result;

    for (;;)
    {
        handle<> entry(allow_null(PyIter_Next(iter.ptr())));

        if (entry == handle<>())
            break;

        result.push_back(extract<announce_entry const&>(object(entry)));
    }

    allow_threading_guard guard;
    info.replace_trackers(result);
}

list get_download_queue(torrent_handle& handle)
{
    using boost::python::make_tuple;

    list ret;

    std::vector<partial_piece_info> downloading;

    {
        allow_threading_guard guard;
        handle.get_download_queue(downloading);
    }

    for (std::vector<partial_piece_info>::iterator i = downloading.begin()
        , end(downloading.end()); i != end; ++i)
    {
        dict partial_piece;
        partial_piece["piece_index"] = i->piece_index;
        partial_piece["blocks_in_piece"] = i->blocks_in_piece;
        list block_list;
        for (int k = 0; k < i->blocks_in_piece; ++k)
        {
            dict block_info;
            block_info["state"] = i->blocks[k].state;
            block_info["num_peers"] = i->blocks[k].num_peers;
            block_info["bytes_progress"] = i->blocks[k].bytes_progress;
            block_info["block_size"] = i->blocks[k].block_size;
            block_info["peer"] = make_tuple(
                boost::lexical_cast<std::string>(i->blocks[k].peer.address()), i->blocks[k].peer.port());
            block_list.append(block_info);
        }
        partial_piece["blocks"] = block_list;

        ret.append(partial_piece);
    }

    return ret;
}

namespace
{
    tcp::endpoint tuple_to_endpoint(tuple const& t)
    {
        return tcp::endpoint(address::from_string(extract<std::string>(t[0])), extract<int>(t[1]));
    }
}

void force_reannounce(torrent_handle& th, int s)
{
    th.force_reannounce(boost::posix_time::seconds(s));
}

void connect_peer(torrent_handle& th, tuple ip, int source)
{
    th.connect_peer(tuple_to_endpoint(ip), source);
}

void set_peer_upload_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_upload_limit(tuple_to_endpoint(ip), limit);
}

void set_peer_download_limit(torrent_handle& th, tuple const& ip, int limit)
{
    th.set_peer_download_limit(tuple_to_endpoint(ip), limit);
}

void add_piece(torrent_handle& th, int piece, char const *data, int flags)
{
   th.add_piece(piece, data, flags);
}

void bind_torrent_handle()
{
    void (torrent_handle::*force_reannounce0)() const = &torrent_handle::force_reannounce;

    int (torrent_handle::*piece_priority0)(int) const = &torrent_handle::piece_priority;
    void (torrent_handle::*piece_priority1)(int, int) const = &torrent_handle::piece_priority;

    void (torrent_handle::*move_storage0)(fs::path const&) const = &torrent_handle::move_storage;
    void (torrent_handle::*move_storage1)(fs::wpath const&) const = &torrent_handle::move_storage;

    void (torrent_handle::*rename_file0)(int, fs::path const&) const = &torrent_handle::rename_file;
    void (torrent_handle::*rename_file1)(int, fs::wpath const&) const = &torrent_handle::rename_file;

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
    bool (torrent_handle::*resolve_countries0)() const = &torrent_handle::resolve_countries;
    void (torrent_handle::*resolve_countries1)(bool) = &torrent_handle::resolve_countries;
#endif

    return_value_policy<copy_const_reference> copy;

#define _ allow_threads

    class_<torrent_handle>("torrent_handle")
        .def("get_peer_info", get_peer_info)
        .def("status", _(&torrent_handle::status))
        .def("get_download_queue", get_download_queue)
        .def("file_progress", file_progress)
        .def("trackers", range(begin_trackers, end_trackers))
        .def("replace_trackers", replace_trackers)
        .def("add_url_seed", _(&torrent_handle::add_url_seed))
        .def("remove_url_seed", _(&torrent_handle::remove_url_seed))
        .def("url_seeds", url_seeds)
        .def("has_metadata", _(&torrent_handle::has_metadata))
        .def("get_torrent_info", _(&torrent_handle::get_torrent_info), return_internal_reference<>())
        .def("is_valid", _(&torrent_handle::is_valid))
        .def("is_seed", _(&torrent_handle::is_seed))
        .def("is_finished", _(&torrent_handle::is_finished))
        .def("is_paused", _(&torrent_handle::is_paused))
        .def("pause", _(&torrent_handle::pause))
        .def("resume", _(&torrent_handle::resume))
        .def("clear_error", _(&torrent_handle::clear_error))

        .def("is_auto_managed", _(&torrent_handle::is_auto_managed))
        .def("auto_managed", _(&torrent_handle::auto_managed))
        .def("queue_position", _(&torrent_handle::queue_position))
        .def("queue_position_up", _(&torrent_handle::queue_position_up))
        .def("queue_position_down", _(&torrent_handle::queue_position_down))
        .def("queue_position_top", _(&torrent_handle::queue_position_top))
        .def("queue_position_bottom", _(&torrent_handle::queue_position_bottom))

#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
        .def("resolve_countries", _(resolve_countries0))
        .def("resolve_countries", _(resolve_countries1))
#endif
        // deprecated
#ifndef TORRENT_NO_DEPRECATE
        .def("filter_piece", _(&torrent_handle::filter_piece))
        .def("is_piece_filtered", _(&torrent_handle::is_piece_filtered))
        .def("write_resume_data", _(&torrent_handle::write_resume_data))
#endif
        .def("add_piece", add_piece)
        .def("read_piece", _(&torrent_handle::read_piece))
        .def("piece_availability", piece_availability)
        .def("piece_priority", _(piece_priority0))
        .def("piece_priority", _(piece_priority1))
        .def("prioritize_pieces", prioritize_pieces)
        .def("piece_prioritize", piece_priorities)
        .def("prioritize_files", prioritize_files)
        .def("file_priorities", file_priorities)
        .def("use_interface", &torrent_handle::use_interface)
        .def("save_resume_data", _(&torrent_handle::save_resume_data))
        .def("force_reannounce", _(force_reannounce0))
        .def("force_reannounce", force_reannounce)
        .def("scrape_tracker", _(&torrent_handle::scrape_tracker))
        .def("name", _(&torrent_handle::name))
        .def("set_upload_limit", _(&torrent_handle::set_upload_limit))
        .def("upload_limit", _(&torrent_handle::upload_limit))
        .def("set_download_limit", _(&torrent_handle::set_download_limit))
        .def("download_limit", _(&torrent_handle::download_limit))
        .def("set_sequential_download", _(&torrent_handle::set_sequential_download))
        .def("set_peer_upload_limit", set_peer_upload_limit)
        .def("set_peer_download_limit", set_peer_download_limit)
        .def("connect_peer", connect_peer)
        .def("set_ratio", _(&torrent_handle::set_ratio))
        .def("save_path", _(&torrent_handle::save_path))
        .def("set_max_uploads", _(&torrent_handle::set_max_uploads))
        .def("set_max_connections", _(&torrent_handle::set_max_connections))
        .def("set_tracker_login", _(&torrent_handle::set_tracker_login))
        .def("move_storage", _(move_storage0))
        .def("move_storage", _(move_storage1))
        .def("info_hash", _(&torrent_handle::info_hash))
        .def("force_recheck", _(&torrent_handle::force_recheck))
        .def("rename_file", _(rename_file0))
        .def("rename_file", _(rename_file1))
        ;
}
<|endoftext|>


<commit_before>#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "../include/otus/app.hpp"
#include "../include/otus/server.hpp"
#include "../include/otus/render.hpp"
using namespace std;

int main() {
    // initialize
    Otus app = Otus();

    // set static folder
    app.set_static_folder("static");
    // set template folder
    app.set_template_folder("templates");

    // routing
    app.route("/", "GET", []{
        return render_template("test.html");
    }());

    app.route("/", "POST", []{
        return "OK";
    }());

    app.run("localhost", "9000");

    return 0;
}
<commit_msg>add test<commit_after>#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include "../include/otus/app.hpp"
#include "../include/otus/server.hpp"
#include "../include/otus/render.hpp"
using namespace std;

int main() {
    // initialize
    Otus app = Otus();

    // set static folder
    app.set_static_folder("static");
    // set template folder
    app.set_template_folder("templates");

    // routing
    app.route("/", "GET", []{
        return render_template("test.html");
    }());

    app.route("/", "POST", []{
        return "OK";
    }());

    //app.run("localhost", "9000");

    return 0;
}
<|endoftext|>