1 # Copyright (C) 2008, Thomas Leonard
2 # See the README file for details, or visit http://0install.net.
4 from logging
import info
, debug
5 import socket
, sys
, select
, tempfile
, shutil
8 from zeroinstall
.zerostore
import Stores
, NotStored
14 def fetch(host
, digests
):
16 print >>sys
.stderr
, "No digests given!"
19 client
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
, 0)
23 if host
== '<broadcast>':
24 info("Broadcasting query for %s on local network...", digests
)
25 client
.setsockopt(socket
.SOL_SOCKET
, socket
.SO_BROADCAST
, 1)
27 info("Sending query for %s to %s...", digests
, host
)
29 client
.sendto('0share\n' + '\n'.join(digests
), (host
or '<broadcast>', port
))
35 r
= select
.select([client
], [], [], 1)[0]
37 data
, addr
= client
.recvfrom(128)
39 lines
= data
.split('\n')
40 if lines
[0] == '0share-reply':
43 print "%s has %s" % (addr
, d
)
48 info("Don't need %s now", d
)
50 info("Invalid reply from %s: %s", addr
, repr(data
))
55 info("No further responses for one second")
57 info("No responses within one second")
59 print "Failed to fetch", x
63 def fetch_impl(digest
, addr
):
65 path
= stores
.lookup(digest
)
66 info("Already have %s - not fetching", path
)
71 info("Connecting to %s to request %s", addr
, digest
)
72 client
= httplib
.HTTPConnection(addr
, port
, strict
= True)
73 url
= '/implementation/' + digest
74 client
.request('GET', url
)
75 response
= client
.getresponse()
76 type = response
.getheader('Content-Type')
78 raise Exception("Missing Content-Type in response")
80 if response
.status
!= 200:
81 raise Exception("Error fetching implementation (%d): %s" % (response
.status
, response
.reason
))
83 tmp
= tempfile
.TemporaryFile(prefix
= '0share-')
85 shutil
.copyfileobj(response
, tmp
)
87 stores
.add_archive_to_cache(digest
, tmp
, url
, type = type)