self.send("Backward", "infomover_commands") self.send("Play", "infomover_commands") if __name__ == "__main__": from Kamaelia.Chassis.Graphline import Graphline from Kamaelia.Util.Console import ConsoleReader from Kamaelia.UI.PygameDisplay import PygameDisplay from Kamaelia.Community.THF.Kamaelia.UI.OpenGL.OpenGLDisplay import OpenGLDisplay from Kamaelia.Community.RJL.Kamaelia.Protocol.HTTP.HTTPClient import SimpleHTTPClient from Kamaelia.Community.RJL.Kamaelia.Protocol.Torrent.TorrentPatron import TorrentPatron ogl_display = OpenGLDisplay(limit_fps=100).activate() OpenGLDisplay.setDisplayService(ogl_display) # override pygame display service PygameDisplay.setDisplayService(ogl_display) Graphline(reader=ConsoleReader(prompt="Enter torrent location:", eol=""), httpclient=SimpleHTTPClient(), gui=TorrentOpenGLGUI(), backend=TorrentPatron(), linkages={ ("gui", "outbox"): ("backend", "inbox"), ("reader", "outbox"): ("gui", "torrent_url"), ("gui", "fetcher"): ("httpclient", "inbox"), ("httpclient", "outbox"): ("gui", "torrent_file"), ("backend", "outbox"): ("gui", "inbox") }).run() # Licensed to the BBC under a Contributor Agreement: THF
split=fanout(["toHTTP-POSTer", "toTorrentPatron"]), # fileupload uploads each message it receives to a script on a webserver. fileupload=pipeline( # convert messages received to HTTP POST requests # for the URL trackerpostuploader # (with the contents of the message as the payload/request body) HTTPMakePostRequest(trackerpostuploader), # SimpleHTTPClient then makes these requests # (connecting to the server given in the URL and sending the # POST request in an HTTP request format) # the result of which is (assuming a suitable upload script on the # webserver) .torrent files sent to this pipeline as messages # are uploaded to the webserver SimpleHTTPClient()), # TorrentPatron is a BitTorrent client which will automatically # upload chunks of the stream to users that request them bittorrentpatron=TorrentPatron(), linkages={ ("streamin", "outbox"): ("split", "inbox"), ("split", "toHTTP-POSTer"): ("fileupload", "inbox"), ("split", "toTorrentPatron"): ("bittorrentpatron", "inbox"), }).run() # BASIC TOPOLOGY # ------------------------------- # # streamin --->split----> fileupload # \
self.uploadurl = uploadurl def main(self): while 1: yield 1 while self.dataReady("inbox"): msg = self.recv("inbox") msg = {"url": self.uploadurl, "postbody": msg} self.send(msg, "outbox") while self.dataReady("control"): msg = self.recv("control") if isinstance(msg, producerFinished) or isinstance( msg, shutdown): self.send(producerFinished(self), "signal") return self.pause() if __name__ == "__main__": from Kamaelia.Util.Console import ConsoleReader, ConsoleEchoer from Kamaelia.Chassis.Pipeline import pipeline from Kamaelia.Community.RJL.Kamaelia.Protocol.HTTP.HTTPClient import SimpleHTTPClient postscript = raw_input( "Post Script URL: ") # e.g. "http://www.example.com/upload.php" pipeline(ConsoleReader(eol=""), HTTPMakePostRequest(postscript), SimpleHTTPClient()).run()
def P2PStreamer(torrentsfolder): """\ Arguments: - torrentsfolder, e.g. "http://my.server.example.org/radioFoo/" """ # Create a pipeline of components whose net result is to output the contents of a certain URL # (torrentsfolder + metafilename) every 60 seconds (the contents at the time of output, i.e. # it fetches the page every 60 seconds). poller = pipeline( # This generates a message every 60 seconds to wake TriggeredSource # allowing us to poll the meta file without busy-waiting. CheapAndCheerfulClock(60.0), # This sends the string (torrentsfolder + "meta.txt") every time it receives a message # This string will be the URL of the meta file on the torrent hosting website # e.g. "http://my.server.example.org/radioFoo/meta.txt" TriggeredSource(torrentsfolder + "meta.txt"), # SimpleHTTPClient retrieves the resource specified by the message it receives, # which will be URL string. # i.e. It fetches the page whose URL is (torrentsfolder + "meta.txt) (the string # produced by TriggeredSource) and forwards on the contents of that page. # The contents of that particular page will always be a number # (in the form of a decimal ASCII string) which represents the number of # 'chunks' of the stream that exist SimpleHTTPClient() ) # As a whole, streamer acts like a normal streaming client, outputting the contents of # a stream to its outbox, although in much larger chunks with longer in between chunks # than for a typical stream. streamer = pipeline( # fetch the P2P-stream meta file every 60 seconds and send its contents on poller, # PartsFilenameGenerator uses the number retrived by poller # i.e. the number of chunks/torrents in the stream # to generate the URLs of all the .torrent files # (torrent metadata files) that make up the stream. # (They will have been named 1.torrent, # 2.torrent, 3.torrent ... etc. on the server). PartsFilenameGenerator(torrentsfolder, ".torrent"), # Download these .torrent files (each message received by resourcefetcher # will be the URL of one .torrent file it should download). The # contents of the page downloaded it forwarded on to the next component. # NOTE: this downloads the .torrent file (metadata about part of the # stream) not the stream itself SimpleHTTPClient(), # now use BitTorrent to download the stream itself using the # metadata retrieved from .torrent files (each has information about a # section of the stream - a section itself is typically a few MB of data) # (TorrentPatron is a BitTorrent client component) TorrentPatron(), # output the names of the chunks of the stream as soon as they and # all previous chunks have been downloaded StreamReconstructor(), # read the contents of these chunks (files) TriggeredFileReader(), ) return streamer
# shutdown the TorrentPatron self.send(shutdown(), "signal") # and tell the HTTP client that we've finished which should cause # it to terminate gracefully, of its own accord self.send(producerFinished(self), "fetchersignal") __kamaelia_components__ = ( TorrentTkWindow, ) if __name__ == "__main__": from Kamaelia.Chassis.Graphline import Graphline from Kamaelia.Community.RJL.Kamaelia.Protocol.HTTP.HTTPClient import SimpleHTTPClient Graphline( gui = TorrentTkWindow(), # our GUI httpclient = SimpleHTTPClient(), # used to download .torrent files backend = TorrentPatron(), # our BitTorrent client backend linkages = { ("backend", "outbox") : ("gui", "inbox"), ("gui", "outbox") : ("backend", "inbox"), ("gui", "signal") : ("backend", "control"), ("gui", "fetchersignal") : ("httpclient", "control"), ("gui", "fetcher") : ("httpclient", "inbox"), ("httpclient", "outbox") : ("backend", "inbox"), } ).run() # BASIC TOPOLOGY # ------------------------------- #