Beispiel #1
0
 def animate(self):
     FPS = 2
     clock = Clock(float(1) / FPS).activate()
     clock.link((clock, "outbox"), (self, "newframe"))
     for x in self.layers:
         if not self.dataReady("newframe"):
             self.pause()
         self.recv("newframe")
         print("now")
Beispiel #2
0
 def animate(self):
     FPS = 2
     clock = Clock(float(1)/FPS).activate()
     clock.link((clock, "outbox"), (self, "newframe"))
     for x in self.layers:
         if not self.dataReady("newframe"):
             self.pause()
         self.recv("newframe")
         print ("now")
Beispiel #3
0
class HTTPResourceMonitor(AdaptiveCommsComponent):
    Inboxes = {"inbox"      : "",
               "control"    : "",
               "monitor"    : "",}
    
    Outboxes = {"outbox"  : "",
                "signal"  : "Shutdown signal"}

    def __init__(self, freq=1.0):
        super(HTTPResourceMonitor, self).__init__()
        self.urls = []
        self.freq = freq

    def initComponents(self):
        self.clock = CheapAndCheerfulClock(self.freq)
        self.link((self.clock, 'outbox'), (self, 'inbox'))
        self.addChildren(self.clock)
        self.clock.activate()

    def main(self):
        yield self.initComponents()

        while 1:
            if self.dataReady("control"):
                mes = self.recv("control")
                
                if isinstance(mes, shutdownMicroprocess) or \
                        isinstance(mes, producerFinished):
                    self.send(producerFinished(), "signal")
                    break

            if self.dataReady("monitor"):
                url, comp = self.recv("monitor")
                comp.activate()
                newOut = self.addOutbox("monitoredOut")
                self.link((self, newOut), (comp, 'inbox'))
                self.addChildren(comp)
                self.urls.append((url, newOut))
                
            if self.dataReady("inbox"):
                self.recv("inbox")
                for url, targetOutbox in self.urls:
                    self.send(url, targetOutbox)

            if not self.anyReady():
                self.pause()
  
            yield 1
Beispiel #4
0
                msg = self.recv("control")
                if (isinstance(msg, producerFinished) or
                   isinstance(msg, shutdownMicroprocess)):
                    self.send(msg, "signal")
                    break
            if not self.anyReady():
                self.pause()
            yield 1 

if __name__ == "__main__":
    from Kamaelia.Util.Clock import CheapAndCheerfulClock as Clock
    from Kamaelia.Util.Console import ConsoleEchoer

    FPS = 60
    
    clock = Clock(float(1)/FPS).activate()
    clock2 = Clock(float(1)/FPS).activate()
    xyPad = XYPad().activate()
    xyPad2 = XYPad(size=(200, 200), bouncingPuck = False, position = (210, 0),
                   bgcolour=(0, 0, 0), fgcolour=(255, 255, 255),
                   positionMsg="p2").activate()
    ce = ConsoleEchoer().activate()
    clock.link((clock, "outbox"), (xyPad, "newframe"))
    clock2.link((clock2, "outbox"), (xyPad2, "newframe"))
    xyPad.link((xyPad, "outbox"), (ce,"inbox"))
    xyPad2.link((xyPad2, "outbox"), (ce,"inbox"))
    Axon.Scheduler.scheduler.run.runThreads()  

#    from Kamaelia.Chassis.Graphline import Graphline
#    from Kamaelia.Util.Clock import CheapAndCheerfulClock as Clock
#    from Kamaelia.Apps.Jam.Protocol.Midi import Midi
Beispiel #5
0
 def initComponents(self):
     self.clock = CheapAndCheerfulClock(self.freq)
     self.link((self.clock, 'outbox'), (self, 'inbox'))
     self.addChildren(self.clock)
     self.clock.activate()
Beispiel #6
0
    def main(self):
        """Main event loop, also handles input from other components"""
        displayservice = PygameDisplay.getDisplayService()
        self.link((self, "display_signal"), displayservice)

        self.send(self.disprequest, "display_signal")

        for _ in self.waitBox("callback"):
            yield 1
        self.display = self.recv("callback")
        self.layers.append(self.display)

        #    f = os.path.join('', "pennyarcade.gif")
        #    x = pygame.image.load(f)
        #    colorkey = x.get_at((0, 0))
        #    if colorkey is True:
        #        x.set_colorkey(colorkey, pygame.RLEACCEL)
        #    self.layers.append(x)
        #    self.display = x
        #    self.activeLayIn = len(self.layers)-1
        #    self.activeLayer = self.layers[self.activeLayIn]
        #    self.display.blit( x, (0,0) )

        layerDisp = TextDisplayer(size=(20, 20), position=(520, 10)).activate()
        self.link((self, "laynum"), (layerDisp, "inbox"))
        self.send(
            {
                "ADDLISTENEVENT": pygame.MOUSEBUTTONDOWN,
                "surface": self.display
            }, "display_signal")

        self.send(
            {
                "ADDLISTENEVENT": pygame.MOUSEBUTTONUP,
                "surface": self.display
            }, "display_signal")

        self.send(
            {
                "ADDLISTENEVENT": pygame.MOUSEMOTION,
                "surface": self.display
            }, "display_signal")

        self.send({
            "ADDLISTENEVENT": pygame.KEYDOWN,
            "surface": self.display
        }, "display_signal")
        self.activeLayer = self.layers[self.activeLayIn]
        self.send(self.activeLayIn, "laynum")
        image = pygame.Surface((20, 20))
        pygame.draw.circle(image, (1, 1, 1), (10, 10), self.toolSize, 0)
        # pygame.draw.circle(image, self.selectedColour, (10, 10), 8, 2)
        image.set_at((9, 9), (255, 255, 255))
        image.set_colorkey(0, pygame.RLEACCEL)
        cursor = GfxCursor(self.display, image, (10, 10))

        self.drawBG(True)
        self.blitToSurface()
        FPS = 1
        clock = Clock(float(1) / FPS).activate()
        clock.link((clock, "outbox"), (self, "newframe"))

        done = False
        while not done:
            dirtyrects = []
            dirtyrects.extend([cursor.hide()])
            if not self.anyReady():
                self.pause()
            yield 1
            while self.dataReady("control"):
                cmsg = self.recv("control")
                if isinstance(cmsg, producerFinished) or isinstance(
                        cmsg, shutdownMicroprocess):
                    self.send(cmsg, "signal")
                    done = True
            while self.dataReady("newframe") and self.playing:
                self.recv("newframe")
                if self.currentFrame != 0:
                    self.layers[self.currentFrame].set_alpha(0)
                self.currentFrame = self.currentFrame + 1
                if self.currentFrame == len(self.layers) - 1:
                    self.playing = False
                self.layers[self.currentFrame].set_alpha(255)
                self.blitToSurface()

            while self.dataReady("inbox"):
                for event in self.recv("inbox"):
                    if isinstance(event, tuple):
                        self.send((event, ), "outbox")
                        if event[0] == "Layer":
                            if event[1] == "Add":
                                yield WaitComplete(self.addLayer())
                                self.activeLayIn = len(self.layers) - 1
                                self.activeLayer = self.layers[
                                    self.activeLayIn]
                                self.drawBG()
                                if self.animator and len(self.layers) - 2 >= 1:
                                    for x in self.layers:
                                        s.set_alpha = 0
                                    self.activeLayer.blit(
                                        self.layers[len(self.layers) - 2],
                                        (0, 0))
                                self.blitToSurface()
                            elif event[1] == "Delete":
                                self.send(
                                    producerFinished(message=self.activeLayer),
                                    "display_signal")
                                self.layers.remove(self.activeLayer)
                                self.activeLayIn = 0
                                self.activeLayer = self.layers[
                                    self.activeLayIn]
                            #  print (self.layers)
                            if event[1] == "Next":
                                if self.animator and self.activeLayIn != 0:
                                    self.activeLayer.set_alpha(0)
                                if self.activeLayIn == len(self.layers) - 1:
                                    self.activeLayIn = 0
                                    self.activeLayer = self.layers[
                                        self.activeLayIn]
                                else:
                                    self.activeLayIn += 1
                                    self.activeLayer = self.layers[
                                        self.activeLayIn]
                                if self.animator:
                                    self.activeLayer.set_alpha(255)
                            elif event[1] == "Prev":
                                if self.animator and self.activeLayIn != 0:
                                    self.activeLayer.set_alpha(0)
                                if self.activeLayIn == 0:
                                    self.activeLayIn = len(self.layers) - 1
                                    self.activeLayer = self.layers[
                                        self.activeLayIn]
                                else:
                                    self.activeLayIn -= 1
                                    self.activeLayer = self.layers[
                                        self.activeLayIn]
                                if self.animator:
                                    self.activeLayer.set_alpha(255)
                            self.send(self.activeLayIn, "laynum")
                        elif event[0] == "Tool":
                            self.tool = event[1]
                        elif event[0] == "Size":
                            self.toolSize = event[1] / 3
                            pygame.draw.circle(image, self.selectedColour,
                                               (10, 10), self.toolSize / 3, 0)
                            image.set_at((9, 9), (255, 255, 255))
                            image.set_colorkey(0, pygame.RLEACCEL)
                            cursor = GfxCursor(self.display, image, (10, 10))
                        elif event[0] == "Alpha":
                            self.layers[self.activeLayIn].set_alpha(event[1])
                            self.blitToSurface()
                        #  print (self.activeLayer.get_alpha())
                        elif event[0] == 'Colour':
                            self.selectedColour = event[1]
                            pygame.draw.circle(image, self.selectedColour,
                                               (10, 10), self.toolSize / 3, 0)
                            image.set_at((9, 9), (255, 255, 255))
                            image.set_colorkey(0, pygame.RLEACCEL)
                            cursor = GfxCursor(self.display, image, (10, 10))
                        elif event[0] == 'Save':
                            self.save(event[1])
                        break
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        cursor.disable()
                        if self.tool == "Circle":
                            if event.button == 1:
                                self.oldpos = event.pos
                                self.drawing = True
                        if self.tool == "Eraser":
                            self.selectedColour = self.backgroundColour
                            self.tool = "Line"
                        if self.tool == "Line":
                            if event.button == 1:
                                self.drawing = True
                        if self.tool == "Bucket":
                            self.floodFill(event.pos[0], event.pos[1],
                                           self.selectedColour,
                                           self.activeLayer.get_at(event.pos))
                        if self.tool == "Eyedropper":
                            self.selectedColour = self.activeLayer.get_at(
                                event.pos)
                        if event.button == 3:
                            self.addLayer()
                            #self.oldpos = None
                            #self.drawBG()
                            #self.blitToSurface()
                            #self.send(("clear",), "outbox")
                    elif event.type == (pygame.KEYDOWN):
                        if event.key == pygame.K_c:
                            image = pygame.image.load(
                                os.path.join('', 'pennyarcade.gif'))
                            yield WaitComplete(self.addLayer())
                            self.activeLayIn = len(self.layers) - 1
                            self.activeLayer = self.layers[self.activeLayIn]
                            self.drawBG()
                            self.activeLayer.blit(image, (10, 10))
                            self.blitToSurface()
                            self.send(self.activeLayIn, "laynum")
                        elif event.key == pygame.K_s:
                            """Testing a different brushing technique, bliting a brush"""
                            print(self.size, self.toolSize)
                            yield WaitComplete(self.addBrush())
                            self.activeBrush = self.brushes[len(self.brushes) -
                                                            1]
                            self.activeBrush.fill(self.backgroundColour)
                            pygame.draw.circle(
                                self.activeBrush, self.selectedColour,
                                (self.toolSize / 2, self.toolSize / 2),
                                self.toolSize, 0)
                        elif event.key == pygame.K_a:
                            self.animator = True
                        elif event.key == pygame.K_l:
                            self.layers[1].blit(self.layers[1], (100, 100))
                #         temp = self.layers[1]
                #         self.layers[1].fill(self.backgroundColour)
                #         self.layers[1].blit( temp, (100,100) )
                        elif event.key == pygame.K_o:
                            for x in self.layers:
                                x.set_alpha(0)
                            self.layers[0].set_alpha(255)
                            self.currentFrame = 0
                            while self.dataReady(
                                    "newframe"
                            ):  # empty if there's anything there
                                self.recv("newframe")
                            self.playing = True
                            self.blitToSurface()

                    elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                        cursor.enable()
                        if self.tool == "Circle":
                            rad = int(
                                math.sqrt((
                                    (event.pos[0] - self.oldpos[0])**2) + (
                                        (event.pos[1] - self.oldpos[1])**2)))
                            pygame.draw.circle(self.activeLayer,
                                               self.selectedColour,
                                               self.oldpos, rad, 0)
                            circle = ("circle", self.oldpos, rad)
                            #   self.send((circle,), "outbox")
                            self.blitToSurface()
                        self.drawing = False
                        self.oldpos = None
                    elif event.type == pygame.MOUSEMOTION:
                        cursor.update(event)
                        if self.tool == "Line":
                            if self.drawing and self.innerRect.collidepoint(
                                    *event.pos):
                                if self.oldpos == None:
                                    self.oldpos = event.pos
                                else:
                                    # pygame.draw.circle(self.activeLayer, self.selectedColour, self.oldpos, self.toolSize, 0)
                                    r = pygame.draw.line(
                                        self.activeLayer, self.selectedColour,
                                        self.oldpos, event.pos, self.toolSize)
                                    dirtyrects.append(r)
                                    #  self.activeLayer.blit(self.activeBrush, event.pos) FAILED TECHNIQUE
                                    line = ("line", self.oldpos, event.pos)
                                    self.send((line, ), "outbox")
                                    self.oldpos = event.pos
                        self.blitToSurface()
            self.pause()
            pygame.time.delay(5)
            dirtyrects.extend([cursor.show()])
            pygame.display.update(dirtyrects)
            yield 1
Beispiel #7
0
   def main(self):
      """Main event loop, also handles input from other components"""
      displayservice = PygameDisplay.getDisplayService()
      self.link((self,"display_signal"), displayservice)

      self.send( self.disprequest,"display_signal")

      for _ in self.waitBox("callback"): yield 1
      self.display = self.recv("callback")
      self.layers.append(self.display)

  #    f = os.path.join('', "pennyarcade.gif")
  #    x = pygame.image.load(f)
  #    colorkey = x.get_at((0, 0))
  #    if colorkey is True:
  #        x.set_colorkey(colorkey, pygame.RLEACCEL)
  #    self.layers.append(x)
  #    self.display = x
  #    self.activeLayIn = len(self.layers)-1
  #    self.activeLayer = self.layers[self.activeLayIn]
  #    self.display.blit( x, (0,0) )
      

      layerDisp = TextDisplayer(size = (20, 20),position = (520,10)).activate()
      self.link( (self,"laynum"), (layerDisp,"inbox") )
      self.send({ "ADDLISTENEVENT" : pygame.MOUSEBUTTONDOWN,
                  "surface" : self.display},
                  "display_signal")

      self.send({ "ADDLISTENEVENT" : pygame.MOUSEBUTTONUP,
                  "surface" : self.display},
                  "display_signal")

      self.send({ "ADDLISTENEVENT" : pygame.MOUSEMOTION,
                  "surface" : self.display},
                  "display_signal")

      self.send({ "ADDLISTENEVENT" : pygame.KEYDOWN,
		  "surface" : self.display},
		  "display_signal")
      self.activeLayer = self.layers[self.activeLayIn]
      self.send( self.activeLayIn, "laynum" )
      image = pygame.Surface((20, 20))
      pygame.draw.circle(image, (1, 1, 1), (10, 10), self.toolSize, 0)
     # pygame.draw.circle(image, self.selectedColour, (10, 10), 8, 2)
      image.set_at((9, 9), (255,255,255))
      image.set_colorkey(0, pygame.RLEACCEL)
      cursor = GfxCursor(self.display, image, (10, 10))

      self.drawBG(True)
      self.blitToSurface()
      FPS = 1
      clock = Clock(float(1)/FPS).activate()
      clock.link((clock, "outbox"), (self, "newframe"))


      done = False
      while not done:
         dirtyrects = []
         dirtyrects.extend([cursor.hide()])
         if not self.anyReady():
             self.pause()
         yield 1
         while self.dataReady("control"):
            cmsg = self.recv("control")
            if isinstance(cmsg, producerFinished) or isinstance(cmsg, shutdownMicroprocess):
               self.send(cmsg, "signal")
               done = True
         while self.dataReady("newframe") and self.playing:
             self.recv("newframe")
             if self.currentFrame != 0:
                self.layers[self.currentFrame].set_alpha(0)
             self.currentFrame = self.currentFrame + 1
             if self.currentFrame == len(self.layers)-1:
                 self.playing = False
             self.layers[self.currentFrame].set_alpha(255)
             self.blitToSurface()

         while self.dataReady("inbox"):
            for event in self.recv("inbox"):
                if isinstance(event, tuple):
                    self.send((event,),"outbox")
                    if event[0] == "Layer":
                        if event[1] == "Add":
                            yield WaitComplete( self.addLayer() )
                            self.activeLayIn = len(self.layers)-1
                            self.activeLayer = self.layers[self.activeLayIn]
                            self.drawBG()
                            if self.animator and len(self.layers)-2 >= 1:
                                for x in self.layers:
                                    s.set_alpha = 0
                                self.activeLayer.blit(self.layers[len(self.layers)-2],(0,0))
                            self.blitToSurface()
                        elif event[1] == "Delete":
                            self.send( producerFinished(message=self.activeLayer),"display_signal")
                            self.layers.remove(self.activeLayer)
                            self.activeLayIn = 0
                            self.activeLayer = self.layers[self.activeLayIn]
                          #  print (self.layers)
                        if event[1] == "Next":
                            if self.animator and self.activeLayIn != 0:
                            	self.activeLayer.set_alpha(0)
                            if self.activeLayIn == len(self.layers)-1:
                                self.activeLayIn = 0
                                self.activeLayer = self.layers[self.activeLayIn]
                            else:
                                self.activeLayIn += 1
                                self.activeLayer = self.layers[self.activeLayIn]
                            if self.animator:
                            	self.activeLayer.set_alpha(255)
                        elif event[1] == "Prev":
                            if self.animator and self.activeLayIn != 0:
                            	self.activeLayer.set_alpha(0)
                            if self.activeLayIn == 0:
                                self.activeLayIn = len(self.layers)-1
                                self.activeLayer = self.layers[self.activeLayIn]
                            else:
                                self.activeLayIn -= 1
                                self.activeLayer = self.layers[self.activeLayIn]
                            if self.animator:
                            	self.activeLayer.set_alpha(255)
                        self.send( self.activeLayIn, "laynum" )
                    elif event[0] == "Tool":
                        self.tool = event[1]
                    elif event[0] == "Size":
                        self.toolSize = event[1]/3
                        pygame.draw.circle(image, self.selectedColour, (10, 10), self.toolSize/3, 0)
                        image.set_at((9, 9), (255,255,255))
                        image.set_colorkey(0, pygame.RLEACCEL)
                        cursor = GfxCursor(self.display, image, (10, 10))
                    elif event[0] == "Alpha":
                        self.layers[self.activeLayIn].set_alpha(event[1])
                        self.blitToSurface()
                      #  print (self.activeLayer.get_alpha())
                    elif event[0] == 'Colour':
                        self.selectedColour = event[1]
                        pygame.draw.circle(image, self.selectedColour, (10, 10), self.toolSize/3, 0)
                        image.set_at((9, 9), (255,255,255))
                        image.set_colorkey(0, pygame.RLEACCEL)
                        cursor = GfxCursor(self.display, image, (10, 10))
                    elif event[0] == 'Save':
                        self.save(event[1])
                    break
                if event.type == pygame.MOUSEBUTTONDOWN:
                    cursor.disable()
                    if self.tool == "Circle":
                        if event.button == 1:
                            self.oldpos = event.pos
                            self.drawing = True
                    if self.tool == "Eraser":
                        self.selectedColour = self.backgroundColour
                        self.tool = "Line"
                    if self.tool == "Line":
                        if event.button == 1:
                            self.drawing = True
                    if self.tool == "Bucket":
                        self.floodFill(event.pos[0],event.pos[1],self.selectedColour,self.activeLayer.get_at(event.pos))
                    if self.tool == "Eyedropper":
                        self.selectedColour = self.activeLayer.get_at(event.pos)
                    if event.button == 3:
                        self.addLayer()
                        #self.oldpos = None
                        #self.drawBG()
                        #self.blitToSurface()
                        #self.send(("clear",), "outbox")
                elif event.type == (pygame.KEYDOWN):
                    if event.key == pygame.K_c:
                        image = pygame.image.load(os.path.join('', 'pennyarcade.gif'))
                        yield WaitComplete( self.addLayer() )
                        self.activeLayIn = len(self.layers)-1
                        self.activeLayer = self.layers[self.activeLayIn]
                        self.drawBG()
                        self.activeLayer.blit( image, (10,10) )
                        self.blitToSurface()
                        self.send( self.activeLayIn, "laynum" )
                    elif event.key == pygame.K_s:
                        """Testing a different brushing technique, bliting a brush"""
                        print (self.size, self.toolSize)
                        yield WaitComplete( self.addBrush() )
                        self.activeBrush = self.brushes[len(self.brushes)-1]
                        self.activeBrush.fill( self.backgroundColour )
                        pygame.draw.circle(self.activeBrush, self.selectedColour, (self.toolSize/2,self.toolSize/2), self.toolSize, 0)
                    elif event.key == pygame.K_a:
                        self.animator = True
                    elif event.key == pygame.K_l:
                        self.layers[1].blit( self.layers[1], (100,100) )
               #         temp = self.layers[1]
               #         self.layers[1].fill(self.backgroundColour)
               #         self.layers[1].blit( temp, (100,100) )
                    elif event.key == pygame.K_o:
                        for x in self.layers:
                            x.set_alpha(0)
                        self.layers[0].set_alpha(255)
                        self.currentFrame = 0
                        while self.dataReady("newframe"): # empty if there's anything there
                            self.recv("newframe")
                        self.playing = True
                        self.blitToSurface()



                elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                    cursor.enable()
                    if self.tool == "Circle":
                        rad = int(math.sqrt(((event.pos[0]-self.oldpos[0])**2)+((event.pos[1]-self.oldpos[1])**2)))
                        pygame.draw.circle(self.activeLayer, self.selectedColour, self.oldpos, rad, 0)
                        circle = ("circle", self.oldpos, rad)
                     #   self.send((circle,), "outbox")
                        self.blitToSurface()
                    self.drawing = False
                    self.oldpos = None
                elif event.type == pygame.MOUSEMOTION:
                    cursor.update(event)
                    if self.tool == "Line":
                        if self.drawing and self.innerRect.collidepoint(*event.pos):
                              if self.oldpos == None:
                                 self.oldpos = event.pos
                              else:
                                # pygame.draw.circle(self.activeLayer, self.selectedColour, self.oldpos, self.toolSize, 0)
                                 r = pygame.draw.line(self.activeLayer, self.selectedColour, self.oldpos, event.pos, self.toolSize)
                                 dirtyrects.append(r)
                               #  self.activeLayer.blit(self.activeBrush, event.pos) FAILED TECHNIQUE
                                 line = ("line", self.oldpos, event.pos)
                                 self.send((line,), "outbox")
                                 self.oldpos = event.pos
                    self.blitToSurface()
         self.pause()
         pygame.time.delay(5)
         dirtyrects.extend([cursor.show()])
         pygame.display.update(dirtyrects)
         yield 1
Beispiel #8
0
                if (isinstance(msg, producerFinished)
                        or isinstance(msg, shutdownMicroprocess)):
                    self.send(msg, "signal")
                    break
            if not self.anyReady():
                self.pause()
            yield 1


if __name__ == "__main__":
    from Kamaelia.Util.Clock import CheapAndCheerfulClock as Clock
    from Kamaelia.Util.Console import ConsoleEchoer

    FPS = 60

    clock = Clock(float(1) / FPS).activate()
    clock2 = Clock(float(1) / FPS).activate()
    xyPad = XYPad().activate()
    xyPad2 = XYPad(size=(200, 200),
                   bouncingPuck=False,
                   position=(210, 0),
                   bgcolour=(0, 0, 0),
                   fgcolour=(255, 255, 255),
                   positionMsg="p2").activate()
    ce = ConsoleEchoer().activate()
    clock.link((clock, "outbox"), (xyPad, "newframe"))
    clock2.link((clock2, "outbox"), (xyPad2, "newframe"))
    xyPad.link((xyPad, "outbox"), (ce, "inbox"))
    xyPad2.link((xyPad2, "outbox"), (ce, "inbox"))
    Axon.Scheduler.scheduler.run.runThreads()
Beispiel #9
0
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