~free.ekanayaka/landscape-client/ensure-version

« back to all changes in this revision

Viewing changes to landscape/lib/fetch.py

  • Committer: Free Ekanayaka
  • Date: 2009-10-15 07:05:36 UTC
  • mfrom: (146.2.4 fetch-many-async)
  • Revision ID: free.ekanayaka@canonical.com-20091015070536-6g8vhpcrn22uv3c3
Merge fetch-many-async [f=50629] [r=sidnei,therve]

- Add helper fetch function to retrieve a list of URLs at once.
- Factor the code to parse lsb-release in its one function

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import sys
 
3
 
1
4
from optparse import OptionParser
2
5
from StringIO import StringIO
3
 
import sys
4
6
 
5
7
import pycurl
6
8
 
7
9
from twisted.internet.threads import deferToThread
 
10
from twisted.internet.defer import DeferredList
8
11
 
9
12
 
10
13
class FetchError(Exception):
107
110
 
108
111
 
109
112
def fetch_async(*args, **kwargs):
 
113
    """Retrieve a URL asynchronously.
 
114
 
 
115
    @return: A C{Deferred} resulting in the URL content.
 
116
    """
110
117
    return deferToThread(fetch, *args, **kwargs)
111
118
 
112
119
 
 
120
def fetch_many_async(urls, callback=None, errback=None, **kwargs):
 
121
    """
 
122
    Retrieve a list of URLs asynchronously.
 
123
 
 
124
    @param callback: Optionally, a function that will be fired one time for
 
125
        each successful URL, and will be passed its content and the URL itself.
 
126
    @param errback: Optionally, a function that will be fired one time for each
 
127
        failing URL, and will be passed the failure and the URL itself.
 
128
    @return: A C{DeferredList} whose callback chain will be fired as soon as
 
129
        all downloads have terminated. If an error occurs, the errback chain
 
130
        of the C{DeferredList} will be fired immediatly.
 
131
    """
 
132
    results = []
 
133
    for url in urls:
 
134
        result = fetch_async(url, **kwargs)
 
135
        if callback:
 
136
            result.addCallback(callback, url)
 
137
        if errback:
 
138
            result.addErrback(errback, url)
 
139
        results.append(result)
 
140
    return DeferredList(results, fireOnOneErrback=True, consumeErrors=True)
 
141
 
 
142
 
 
143
def fetch_to_files(urls, directory, logger=None, **kwargs):
 
144
    """
 
145
    Retrieve a list of URLs and save their content as files in a directory.
 
146
 
 
147
    @param urls: The list URLs to fetch.
 
148
    @param directory: The directory to save the files to, the name of the file
 
149
        will equal the last fragment of the URL.
 
150
    @param logger: Optional function to be used to log errors for failed URLs.
 
151
    """
 
152
 
 
153
    def write(data, url):
 
154
        filename = os.path.join(directory, url.rstrip("/").split("/")[-1])
 
155
        fd = open(filename, "w")
 
156
        fd.write(data)
 
157
        fd.close()
 
158
 
 
159
    def log_error(failure, url):
 
160
        if logger:
 
161
            logger("Couldn't fetch file from %s (%s)" % (
 
162
                url, str(failure.value)))
 
163
        return failure
 
164
 
 
165
    return fetch_many_async(urls, callback=write, errback=log_error, **kwargs)
 
166
 
 
167
 
113
168
if __name__ == "__main__":
114
169
    test(sys.argv[1:])