Simple libtorrent Python client - python-2.7

I tried creating a simple libtorrent python client (for magnet uri), and I failed, the program never continues past the "downloading metadata".
If you may help me write a simple client it would be amazing.
P.S. When I choose a save path, is the save path the folder which I want my data to be saved in? or the path for the data itself.
(I used a code someone posted here)
import libtorrent as lt
import time
ses = lt.session()
ses.listen_on(6881, 6891)
params = {
'save_path': '/home/downloads/',
'storage_mode': lt.storage_mode_t(2),
'paused': False,
'auto_managed': True,
'duplicate_is_error': True}
link = "magnet:?xt=urn:btih:4MR6HU7SIHXAXQQFXFJTNLTYSREDR5EI&tr=http://tracker.vodo.net:6970/announce"
handle = lt.add_magnet_uri(ses, link, params)
ses.start_dht()
print 'downloading metadata...'
while (not handle.has_metadata()):
time.sleep(1)
print 'got metadata, starting torrent download...'
while (handle.status().state != lt.torrent_status.seeding):
s = handle.status()
state_str = ['queued', 'checking', 'downloading metadata', \
'downloading', 'finished', 'seeding', 'allocating']
print '%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d) %s %.3' % \
(s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, \
s.num_peers, state_str[s.state], s.total_download/1000000)
time.sleep(5)

What happens it is that the first while loop becomes infinite because the state does not change.
You have to add a s = handle.status (); for having the metadata the status changes and the loop stops. Alternatively add the first while inside the other while so that the same will happen.

Yes, the save path you specify is the one that the torrents will be downloaded to.
As for the metadata downloading part, I would add the following extensions first:
ses.add_extension(lt.create_metadata_plugin)
ses.add_extension(lt.create_ut_metadata_plugin)
Second, I would add a DHT bootstrap node:
ses.add_dht_router("router.bittorrent.com", 6881)
Finally, I would begin debugging the application by seeing if my network interface is binding or if any other errors come up (my experience with BitTorrent download problems, in general, is that they are network related). To get an idea of what's happening I would use libtorrent-rasterbar's alert system:
ses.set_alert_mask(lt.alert.category_t.all_categories)
And make a thread (with the following code) to collect the alerts and display them:
while True:
ses.wait_for_alert(500)
alert = lt_session.pop_alert()
if not alert:
continue
print "[%s] %s" % (type(alert), alert.__str__())
Even with all this working correctly, make sure that torrent you are trying to download actually has peers. Even if there are a few peers, none may be configured correctly or support metadata exchange (exchanging metadata is not a standard BitTorrent feature). Try to load a torrent file (which doesn't require downloading metadata) and see if you can download successfully (to rule out some network issues).

Related

Connect to multiple queue managers in different servers

I am trying to connect a C++ application (using MQCONNX) based on a PaaS IBM MQ client to two different queue managers, each one based on a different server (one in a PaaS server and the other one in a Unix server). Unfortunately I am not able to do it as I am getting a message when I try to connect to the second server saying that it is not possible as it is connected to the first queue manager. I am using two different MQHCONN connections, one for each queue manager, but the problem is still there.
I have taken a look into this link, but I still have some doubts, as for example, from which server should I copy the CCDT to the client?
https://www.ibm.com/support/pages/connecting-mq-clients-multiple-queue-managers-client-channel-definition-table-ccdt
Any help would be much appreciated, or even a quick sample of how to use CCDT, as right now I am completely stuck.
Many thanks in advance for any help.
Assuming Queue Manager 1 is called MQG1 and Queue Manager 2 is called MQG2 and these can be found using connection names of machine1.com(1701) and machine2.com(1702) respectively, and using channel names MQG1.SVRCONN and MQG2.SVRCONN respectively, you can create your CCDT, on your client application machine, thus:-
runmqsc -n
issue these commands into runmqsc:-
DEFINE CHANNEL(MQG1.SVRCONN) CHLTYPE(CLNTCONN) CONNAME('machine1.com(1701)') QMNAME(MQG1)
DEFINE CHANNEL(MQG2.SVRCONN) CHLTYPE(CLNTCONN) CONNAME('machine2.com(1702)') QMNAME(MQG2)
Then you can code your 2 x MQCONN (or MQCONNX if you need to specify any additional things on the connection) thus:-
#include <cmqc.h> /* Includes for MQI constants */
#include <cmqstrc.h> /* Convert MQRC into string */
MQHCONN hConn1 = MQHC_UNUSABLE_HCONN;
MQHCONN hConn2 = MQHC_UNUSABLE_HCONN;
MQCHAR QMName1[MQ_Q_MGR_NAME_LENGTH] = "MQG1";
MQCHAR QMName2[MQ_Q_MGR_NAME_LENGTH] = "MQG2";
MQLONG CompCode, Reason;
MQCONN(QMName1,
&hConn1,
&CompCode,
&Reason);
if (CompCode)
{
printf("MQCONN to %s failed with reason code %s (%d)\n", QMName1, MQRC_STR(Reason), Reason);
}
MQCONN(QMName2,
&hConn2,
&CompCode,
&Reason);
if (CompCode)
{
printf("MQCONN to %s failed with reason code %s (%d)\n", QMName2, MQRC_STR(Reason), Reason);
}
Take care with how you are linking your program. If you try to make two local connections, you will get a return code of MQRC_ANOTHER_Q_MGR_CONNECTED. Ensure you either link with the client library, set connection option MQCNO_CLIENT (which means you must use MQCONNX) or set the environment variable MQ_CONNECT_TYPE=CLIENT.
You might find the following blog post useful additional reading:-
IBM MQ Little Gem #30: MQ_CONNECT_TYPE

How to properly organize a work of threads in Coldfusion in my example

I have a Coldfusion app and page where I generate and download a file. There are cases when that process takes a lot of time. I would like to implement it so that the whole process looks like this:
start the process of generating and downloading a file
if the file is generated within a certain time (e.g. 10 sec.), then provide it to the user immediately
if not, then after the expiration of the allowable time for generation, display a message that the file will be sent to the user email.
I think the CF threads can help me, but I haven't used it earlier.
thread action="run" name="generateFile" {
var createFileResult = myService.createFile();
}
thread action="join" name="generateFile" timeout="10000"; // 10 sec.
if (generateFile.status != "COMPLETED") {
thread action="terminate" name="generateFile";
var createFileResult = new CreateFileResult(message="We will produce the file and send you a link to download.");
}
Currently, I show a message if the file has not generated, but at the same time, I lose the ability to generate the file on the first request.
I'm interested in the following: how without killing the thread in which the file is generated (if it is possible), complete the file generation in the background for a user and immediately to send it to a user email?
I want to implement it in this way because I want to use the server resources rationally and not ignore the result of the work done if the file wasn't generated at the first user request and don't load the server again when the same file is generated for sending to email.

Poloniex & websockets

===SIMPLE & SHORT===
Does anybody have working application that talks with Poloniex through WAMP in these days (January, 2018)?
===MORE SPECIFIC===
I used several info sources to make it work using combo: autobahn-cpp & C++. Windows 10 OS.
I was able to connect to wss://api.poloniex.com, realm1. Plus I was able to subscribe and get subscription ID. But I never got any events even when everything established.
===RESEARCH===
During research in the web I saw a lot of controversial information:
1. Claims, that wss://api2.poloniex.com should be used, and channels names are actually numbers - How to connect to poloniex.com websocket api using a python library
2. This answer gave me base code, but I am getting anything more than just connections, also by following this answer - wss://api.poloniex.com is correct address - Connecting to Poloniex Push-API
3. I saw post (sorry, lost the link), there were comments made that websockets implementation are basically broken on poloniex. They were posted 6 months ago.
===SPECS===
1. Windows 10
2. Autobahn-Cpp
3. wss://api.poloniex.com:443 ; realm1
4. Different subscriptions: ticker, BTC_ETH, 148, 1002, etc..
5. Source code I got from here
===WILL HELP AS WELL===
Is there any way to get all valid subscriptions or, probably, those, that have more than 0 subscribers? I mean, does WAMP have a way to do that?
Is there any known issues with Autobahn-Cpp and poloniex combo?
Is there any simpler way to test WAMP elsewhere to make sure Autobahn isn't a problem? Like any other well documented & supported online projects that accept WAMP websocket communication?
I can receive the correct tick order book data from wss://api2.poloniex.com use python3
but sometime The channel 1002 may stop sending the new tick info.
wss://api.poloniex.com:443 ; realm1
This may be the issue as I've been using api2 and here is the code that works, and has been working for the past 2 quarters non-stop. Its in python, but should be easy enough to port to C++.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import websocket
import json
def on_error(ws, error):
print(error)
def on_close(ws):
print("### closed ###")
connection.close()
def on_open(ws):
print("ONOPEN")
ws.send(json.dumps({'command':'subscribe','channel':'BTC_ETH'}))
def on_message(ws, message):
message = json.loads(message)
print(message)
websocket.enableTrace(True)
ws = websocket.WebSocketApp("wss://api2.poloniex.com/",
on_message = on_message,
on_error = on_error,
on_close = on_close)
ws.on_open = on_open
ws.run_forever()
the code is pretty much self-explanatory (You can check all channels/pairs on Poloniex API website), just save it and run in terminal
python3 fileName.py
should provide You with BTCETH raw stream of orders and trades on console output.
Playing with the message/subscriptions You can then do as You please with it.
It seems that websockets in Poloniex are unstable. Therefore I can stop my attempts make Autobahn-Cpp work with it at least by now and move on.

Grabbing list of nicks in IRC channel with Phenny bot

Whee first question! hi5
So, I have my own version of the Phenny python IRC bot (https://github.com/sbp/phenny). What I'm trying to do is have phenny query the IRC server for a list of nicks who are in a given channel.
I know (from looking at some of phenny's modules) that I can query the server using the following command:
phenny.write(['NAMES'], channel)
Where I'm having trouble is in getting the response from the server and parsing it into a list of nicks. I recognize that the answer I want is probably in the bot.py or irc.py phenny modules, but I've only been writing Python for about 2 months and can't quite get my mind around it.
Any help would be appreciated, thank you!!
OK, so I found a way to do it, which (mostly) works.
I have a routine which triggers on a '353' event, which is how the server responds to /NAMES commands. It stores the list of nicks into a shelve db, indexed by channel.
def nametrigger(phenny, input):
names = re.split(' ', input)
names = [n.split('!')[0] for n in names]
names = [n.replace('~','') for n in names]
namesdb = shelve.open(phenny.logdir+'/nicks')
namesdb[input.args[2]] = names
namesdb.close()
nametrigger.event = '353'
nametrigger.rule = '(.*)'
nametrigger.priority = 'high'
I wrote some utility commands to call /NAMES whenever joining a channel, and whenever someone else joins, leaves, or changes nicks. That should keep the db up to date, though it doesn't seem to work 100% yet.
Then, whenever I want the list of nicks, I can just load the db.

Django: Gracefully restart nginx + fastcgi sites to reflect code changes?

Common situation: I have a client on my server who may update some of the code in his python project. He can ssh into his shell and pull from his repository and all is fine -- but the code is stored in memory (as far as I know) so I need to actually kill the fastcgi process and restart it to have the code change.
I know I can gracefully restart fcgi but I don't want to have to manually do this. I want my client to update the code, and within 5 minutes or whatever, to have the new code running under the fcgi process.
Thanks
First off, if uptime is important to you, I'd suggest making the client do it. It can be as simple as giving him a command called deploy-code. Using your method, if there is an error in their code, your method requires a 10 minute turnaround (read: downtime) for fixing it, assuming he gets it correct.
That said, if you actually want to do this, you should create a daemon which will look for files modified within the last 5 minutes. If it detects one, it will execute the reboot command.
Code might look something like:
import os, time
CODE_DIR = '/tmp/foo'
while True:
if restarted = True:
restarted = False
time.sleep(5*60)
for root, dirs, files in os.walk(CODE_DIR):
if restarted=True:
break
for filename in files:
if restared=True:
break
updated_on = os.path.getmtime(os.path.join(root, filename))
current_time = time.time()
if current_time - updated_on <= 6 * 60: # 6 min
# 6 min could offer false negatives, but that's better
# than false positives
restarted = True
print "We should execute the restart command here."