Skip to content

Instantly share code, notes, and snippets.

@NikkyAI
Last active June 28, 2017 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save NikkyAI/9ed8c99997e89e36cf61a66ce2291d5f to your computer and use it in GitHub Desktop.
Save NikkyAI/9ed8c99997e89e36cf61a66ce2291d5f to your computer and use it in GitHub Desktop.
{.deadCodeElim: on.}
when defined(windows):
const
libname* = "libtorrent.dll"
elif defined(macosx):
const
libname* = "libtorrent.dylib"
else:
const
libname* = "libtorrent.so"
##
##
## Copyright (c) 2009, Arvid Norberg
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
##
## Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in
## the documentation and/or other materials provided with the distribution.
## Neither the name of the author nor the names of its
## contributors may be used to endorse or promote products derived
## from this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
## POSSIBILITY OF SUCH DAMAGE.
##
##
type
tags* {.size: sizeof(cint).} = enum
TAG_END = 0, SES_FINGERPRINT, ## char const*, 2 character string
SES_LISTENPORT, ## int
SES_LISTENPORT_END, ## int
SES_VERSION_MAJOR, ## int
SES_VERSION_MINOR, ## int
SES_VERSION_TINY, ## int
SES_VERSION_TAG, ## int
SES_FLAGS, ## int
SES_ALERT_MASK, ## int
SES_LISTEN_INTERFACE, ## char const*
## === add_torrent tags ===
## identifying the torrent to add
TOR_FILENAME = 0x100, ## char const*
TOR_TORRENT, ## char const*, specify size of buffer with TOR_TORRENT_SIZE
TOR_TORRENT_SIZE, ## int
TOR_INFOHASH, ## char const*, must point to a 20 byte array
TOR_INFOHASH_HEX, ## char const*, must point to a 40 byte string
TOR_MAGNETLINK, ## char const*, url
TOR_TRACKER_URL, ## char const*
TOR_RESUME_DATA, ## char const*
TOR_RESUME_DATA_SIZE, ## int
TOR_SAVE_PATH, ## char const*
TOR_NAME, ## char const*
TOR_PAUSED, ## int
TOR_AUTO_MANAGED, ## int
TOR_DUPLICATE_IS_ERROR, ## int
TOR_USER_DATA, ## void*
TOR_SEED_MODE, ## int
TOR_OVERRIDE_RESUME_DATA, ## int
TOR_STORAGE_MODE, ## int
SET_UPLOAD_RATE_LIMIT = 0x00000200, ## int
SET_DOWNLOAD_RATE_LIMIT, ## int
SET_LOCAL_UPLOAD_RATE_LIMIT, ## int
SET_LOCAL_DOWNLOAD_RATE_LIMIT, ## int
SET_MAX_UPLOAD_SLOTS, ## int
SET_MAX_CONNECTIONS, ## int
SET_SEQUENTIAL_DOWNLOAD, ## int, torrent only
SET_SUPER_SEEDING, ## int, torrent only
SET_HALF_OPEN_LIMIT, ## int, session only
SET_PEER_PROXY, ## proxy_setting const*, session_only
SET_WEB_SEED_PROXY, ## proxy_setting const*, session_only
SET_TRACKER_PROXY, ## proxy_setting const*, session_only
SET_DHT_PROXY, ## proxy_setting const*, session_only
SET_PROXY, ## proxy_setting const*, session_only
SET_ALERT_MASK ## int, session_only
type
proxy_setting* = object
hostname*: array[256, char]
port*: cint
username*: array[256, char]
password*: array[256, char]
`type`*: cint
category_t* {.size: sizeof(cint).} = enum
cat_error = 0x00000001,
cat_peer = 0x00000002,
cat_port_mapping = 0x00000004,
cat_storage = 0x00000008,
cat_tracker = 0x00000010,
cat_debug = 0x00000020,
cat_status = 0x00000040,
cat_progress = 0x00000080,
cat_ip_block = 0x00000100,
cat_performance_warning = 0x00000200,
cat_dht = 0x00000400,
cat_all_categories = 0xFFFFFFFF
type
proxy_type_t* {.size: sizeof(cint).} = enum
proxy_none, proxy_socks4, proxy_socks5, proxy_socks5_pw, proxy_http,
proxy_http_pw
type
storage_mode_t* {.size: sizeof(cint).} = enum
storage_mode_allocate = 0, storage_mode_sparse
type
state_t* {.size: sizeof(cint).} = enum
queued_for_checking, checking_files, downloading_metadata, downloading,
finished, seeding, allocating, checking_resume_data
type
torrent_status* = object
state*: state_t
paused*: cint
progress*: cfloat
error*: array[1024, char]
next_announce*: cint
announce_interval*: cint
current_tracker*: array[512, char]
total_download*: clonglong
total_upload*: clonglong
total_payload_download*: clonglong
total_payload_upload*: clonglong
total_failed_bytes*: clonglong
total_redundant_bytes*: clonglong
download_rate*: cfloat
upload_rate*: cfloat
download_payload_rate*: cfloat
upload_payload_rate*: cfloat
num_seeds*: cint
num_peers*: cint
num_complete*: cint
num_incomplete*: cint
list_seeds*: cint
list_peers*: cint
connect_candidates*: cint ## what to do?
## bitfield pieces;
num_pieces*: cint
total_done*: clonglong
total_wanted_done*: clonglong
total_wanted*: clonglong
distributed_copies*: cfloat
block_size*: cint
num_uploads*: cint
num_connections*: cint
uploads_limit*: cint
connections_limit*: cint ## enum storage_mode_t storage_mode;
up_bandwidth_queue*: cint
down_bandwidth_queue*: cint
all_time_upload*: clonglong
all_time_download*: clonglong
active_time*: cint
seeding_time*: cint
seed_rank*: cint
last_scrape*: cint
has_incoming*: cint
seed_mode*: cint
session_status* = object
has_incoming_connections*: cint
upload_rate*: cfloat
download_rate*: cfloat
total_download*: clonglong
total_upload*: clonglong
payload_upload_rate*: cfloat
payload_download_rate*: cfloat
total_payload_download*: clonglong
total_payload_upload*: clonglong
ip_overhead_upload_rate*: cfloat
ip_overhead_download_rate*: cfloat
total_ip_overhead_download*: clonglong
total_ip_overhead_upload*: clonglong
dht_upload_rate*: cfloat
dht_download_rate*: cfloat
total_dht_download*: clonglong
total_dht_upload*: clonglong
tracker_upload_rate*: cfloat
tracker_download_rate*: cfloat
total_tracker_download*: clonglong
total_tracker_upload*: clonglong
total_redundant_bytes*: clonglong
total_failed_bytes*: clonglong
num_peers*: cint
num_unchoked*: cint
allowed_upload_slots*: cint
up_bandwidth_queue*: cint
down_bandwidth_queue*: cint
up_bandwidth_bytes_queue*: cint
down_bandwidth_bytes_queue*: cint
optimistic_unchoke_counter*: cint
unchoke_counter*: cint
dht_nodes*: cint
dht_node_cache*: cint
dht_torrents*: cint
dht_global_nodes*: clonglong ## std::vector<dht_lookup> active_requests;
## the functions whose signature ends with:
## , int first_tag, ...);
## takes a tag list. The tag list is a series
## of tag-value pairs. The tags are constants
## identifying which property the value controls.
## The type of the value varies between tags.
## The enumeration above specifies which type
## it expects. All tag lists must always be
## terminated by TAG_END.
## use SES_* tags in tag list
proc session_create*(first_tag: cint): pointer {.varargs, cdecl,
importc: "session_create", dynlib: libname.}
proc session_close*(ses: pointer) {.cdecl, importc: "session_close", dynlib: libname.}
## use TOR_* tags in tag list~(cat_progress | cat_port_mapping | cat_debug | cat_performance_warning | cat_peer)
proc session_add_torrent*(ses: pointer; first_tag: cint): cint {.varargs, cdecl,
importc: "session_add_torrent", dynlib: libname.}
proc session_remove_torrent*(ses: pointer; tor: cint; flags: cint) {.cdecl,
importc: "session_remove_torrent", dynlib: libname.}
## return < 0 if there are no alerts. Otherwise returns the
## type of alert that was returned
proc session_pop_alert*(ses: pointer; dest: cstring; len: cint; category: ptr cint): cint {.
cdecl, importc: "session_pop_alert", dynlib: libname.}
proc session_get_status*(ses: pointer; s: ptr session_status; struct_size: cint): cint {.
cdecl, importc: "session_get_status", dynlib: libname.}
## use SET_* tags in tag list
proc session_set_settings*(ses: pointer; first_tag: cint): cint {.varargs, cdecl,
importc: "session_set_settings", dynlib: libname.}
proc session_get_setting*(ses: pointer; tag: cint; value: pointer; value_size: ptr cint): cint {.
cdecl, importc: "session_get_setting", dynlib: libname.}
proc torrent_get_status*(tor: cint; s: ptr torrent_status; struct_size: cint): cint {.
cdecl, importc: "torrent_get_status", dynlib: libname.}
## use SET_* tags in tag list
proc torrent_set_settings*(tor: cint; first_tag: cint): cint {.varargs, cdecl,
importc: "torrent_set_settings", dynlib: libname.}
proc torrent_get_setting*(tor: cint; tag: cint; value: pointer; value_size: ptr cint): cint {.
cdecl, importc: "torrent_get_setting", dynlib: libname.}
##
##
## Copyright (c) 2009, Arvid Norberg
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
##
## Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in
## the documentation and/or other materials provided with the distribution.
## Neither the name of the author nor the names of its
## contributors may be used to endorse or promote products derived
## from this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
## POSSIBILITY OF SUCH DAMAGE.
##
##
var quit*: cint = 0
proc stop*(signal: cint) {.cdecl.} =
quit = 1
proc main*(argc: cint; argv: ptr cstring): cint {.cdecl.} =
if argc != 2:
fprintf(stderr, "usage: ./simple_client torrent-file\x0A")
return 1
var ret: cint = 0
var ses: pointer = session_create(SES_LISTENPORT, 6881, SES_LISTENPORT_END, 6889,
SES_ALERT_MASK, not (cat_progress or
cat_port_mapping or cat_debug or cat_performance_warning or cat_peer), TAG_END)
var t: cint = session_add_torrent(ses, TOR_FILENAME, argv[1], TOR_SAVE_PATH, "./",
TAG_END)
if t < 0:
fprintf(stderr, "Failed to add torrent\x0A")
ret = 1
break exit
var st: torrent_status
printf("press ctrl-C to stop\x0A")
signal(SIGINT, addr(stop))
signal(SIGABRT, addr(stop))
signal(SIGQUIT, addr(stop))
while quit == 0:
var message: cstring = ""
var state: ptr cstring = ["queued", "checking", "downloading metadata",
"downloading", "finished", "seeding", "allocating",
"checking_resume_data"]
if torrent_get_status(t, addr(st), sizeof((st))) < 0: break
printf("\x0D%3.f%% %d kB (%5.f kB/s) up: %d kB (%5.f kB/s) peers: %d \'%s\' %s ",
cast[cdouble](st.progress * 100.0),
(int)(st.total_payload_download div 1000),
cast[cdouble](st.download_payload_rate div 1000.0),
(int)(st.total_payload_upload div 1000),
cast[cdouble](st.upload_payload_rate div 1000.0), st.num_peers,
state[st.state], message)
var msg: array[400, char]
while session_pop_alert(ses, msg, sizeof((msg)), 0) >= 0:
printf("%s\x0A", msg)
if strlen(st.error) > 0:
fprintf(stderr, "\x0AERROR: %s\x0A", st.error)
break
fflush(stdout)
usleep(1000000)
printf("\x0Aclosing\x0A")
session_close(ses)
return ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment