Skip to content

Instantly share code, notes, and snippets.

@devos50
Created January 11, 2018 10:34
Show Gist options
  • Save devos50/cc84bd5a99ec205890c854656fc5230a to your computer and use it in GitHub Desktop.
Save devos50/cc84bd5a99ec205890c854656fc5230a to your computer and use it in GitHub Desktop.
Twistd script
"""
This twistd plugin enables to start Tribler headless using the twistd command.
"""
from datetime import date
import os
import signal
import time
from Tribler.Core.simpledefs import NTFY_CHANNELCAST
from twisted.application.service import MultiService, IServiceMaker
from twisted.conch import manhole_tap
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks
from twisted.internet.task import deferLater, LoopingCall
from twisted.plugin import IPlugin
from twisted.python import usage
from twisted.python.log import msg
from zope.interface import implements
from Tribler.Core.Modules.process_checker import ProcessChecker
from Tribler.Core.Session import Session
from Tribler.Core.SessionConfig import SessionStartupConfig
# Register yappi profiler
from Tribler.community.allchannel.community import AllChannelCommunity
from Tribler.community.search.community import SearchCommunity
from Tribler.dispersy.utils import twistd_yappi
class Options(usage.Options):
optParameters = [
["manhole", "m", 0, "Enable manhole telnet service listening at the specified port", int],
["statedir", "s", None, "Use an alternate statedir", str],
["restapi", "p", -1, "Use an alternate port for the REST API", int],
["dispersy", "d", -1, "Use an alternate port for Dispersy", int],
["libtorrent", "l", -1, "Use an alternate port for libtorrent", int],
]
optFlags = [
["auto-join-channel", "a", "Automatically join a channel when discovered"],
["log-incoming-searches", "i", "Write information about incoming remote searches to a file"]
]
class TriblerServiceMaker(object):
implements(IServiceMaker, IPlugin)
tapname = "tribler"
description = "Tribler twistd plugin, starts Tribler as a service"
options = Options
def __init__(self):
"""
Initialize the variables of the TriblerServiceMaker and the logger.
"""
self.session = None
self._stopping = False
self.process_checker = None
def log_incoming_remote_search(self, sock_addr, keywords):
d = date.today()
with open(os.path.join(self.session.get_state_dir(), 'incoming-searches-%s' % d.isoformat()), 'a') as log_file:
log_file.write("%s %s %s %s" % (time.time(), sock_addr[0], sock_addr[1], ";".join(keywords)))
def shutdown_process(self, shutdown_message, code=1):
msg(shutdown_message)
reactor.addSystemEventTrigger('after', 'shutdown', os._exit, code)
reactor.stop()
def start_tribler(self, options):
"""
Main method to startup Tribler.
"""
def on_tribler_shutdown(_):
msg("Tribler shut down")
reactor.stop()
self.process_checker.remove_lock_file()
def signal_handler(sig, _):
msg("Received shut down signal %s" % sig)
if not self._stopping:
self._stopping = True
self.session.shutdown().addCallback(on_tribler_shutdown)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
config = SessionStartupConfig().load() # Load the default configuration file
# Check if we are already running a Tribler instance
self.process_checker = ProcessChecker()
if self.process_checker.already_running:
self.shutdown_process("Another Tribler instance is already using statedir %s" % config.get_state_dir())
return
msg("Starting Tribler")
if options["statedir"]:
config.set_state_dir(options["statedir"])
if options["restapi"] > 0:
config.set_http_api_enabled(True)
config.set_http_api_port(options["restapi"])
if options["dispersy"] > 0:
config.set_dispersy_port(options["dispersy"])
if options["libtorrent"] > 0:
config.set_listen_port(options["libtorrent"])
@inlineCallbacks
def on_tribler_started(_):
msg("STARTED TRIBLERZZ")
yield deferLater(reactor, 5, lambda: None)
# Do lookup for some torrents
torrent_db_columns = ['Torrent.torrent_id', 'infohash', 'Torrent.name', 'length', 'Torrent.category',
'num_seeders', 'num_leechers', 'last_tracker_check', 'ChannelTorrents.inserted']
channel_db_handler = self.session.open_dbhandler(NTFY_CHANNELCAST)
popular_torrents = channel_db_handler.get_random_channel_torrents(torrent_db_columns, limit=5)
for torrent in popular_torrents:
print "INFOHASH: %s" % torrent[1].encode('hex')
self.session.lm.torrent_checker.add_gui_request(torrent[1], scrape_now=True)
#self.session.lm.torrent_checker.add_gui_request('a2f4db9810064eaa5a43d062e22d0de2b53c8f8b'.decode('hex'), scrape_now=True)
msg("after scheduling checks")
yield deferLater(reactor, 5, lambda: None)
msg("HEREzz2")
yield self.session.shutdown()
msg("HEREzz1")
def print_stuff():
print "STUFF"
LoopingCall(print_stuff).start(1)
#for call in reactor.getDelayedCalls():
# msg(call)
reactor.stop()
self.session = Session(config)
self.session.start().addCallbacks(on_tribler_started, lambda failure: self.shutdown_process(failure.getErrorMessage()))
msg("Tribler started")
if "auto-join-channel" in options and options["auto-join-channel"]:
msg("Enabling auto-joining of channels")
for community in self.session.get_dispersy_instance().get_communities():
if isinstance(community, AllChannelCommunity):
community.auto_join_channel = True
if "log-incoming-searches" in options and options["log-incoming-searches"]:
msg("Logging incoming remote searches")
for community in self.session.get_dispersy_instance().get_communities():
if isinstance(community, SearchCommunity):
community.log_incoming_searches = self.log_incoming_remote_search
def makeService(self, options):
"""
Construct a Tribler service.
"""
tribler_service = MultiService()
tribler_service.setName("Tribler")
manhole_namespace = {}
if options["manhole"] > 0:
port = options["manhole"]
manhole = manhole_tap.makeService({
'namespace': manhole_namespace,
'telnetPort': 'tcp:%d:interface=127.0.0.1' % port,
'sshPort': None,
'passwd': os.path.join(os.path.dirname(__file__), 'passwd'),
})
tribler_service.addService(manhole)
reactor.callWhenRunning(self.start_tribler, options)
return tribler_service
service_maker = TriblerServiceMaker()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment