@@ -0,0 +1,2606 @@
+#!/usr/bin/env python3%0A# -*- encoding: utf-8 -*-%0A%0Aimport asyncio%0Aimport collections%0A%0Aimport aiohttp%0Afrom aiohttp import web%0Aimport tqdm%0Afrom concurrency_futures.flags2_common import main, HTTPStatus, Result, save_flag%0A%0A# default set low to avoid errors from remote site, such as%0A# 503 - Service Temporarily Unavailable%0ADEFAULT_CONCUR_REQ = 5%0AMAX_CONCUR_REQ = 1000%0A%0A%0Aclass FetchError(Exception):%0A    def __init__(self, country_code):%0A        self.country_code = country_code%0A%0A%0A@asyncio.coroutine%0Adef get_flag(base_url, cc):%0A    url = '%7B%7D/%7Bcc%7D/%7Bcc%7D.gif'.format(base_url, cc=cc.lower())%0A    resp = yield from aiohttp.request('GET', url)%0A    if resp.status == 200:%0A        image = yield from resp.read()%0A        return image%0A    elif resp.status == 404:%0A        raise web.HTTPNotFound()%0A    else:%0A        raise aiohttp.ServerConnectionError(Exception(code=resp.status, message=resp.reason, headers=resp.headers))%0A%0A%0A@asyncio.coroutine%0Adef download_one(cc, base_url, semaphore, verbose):%0A    try:%0A        with (yield from semaphore):%0A            image = yield from get_flag(base_url, cc)%0A    except web.HTTPNotFound:%0A        status = HTTPStatus.not_found%0A        msg = 'not found'%0A    except Exception as exc:%0A        raise FetchError(cc) from exc%0A    else:%0A        save_flag(image, cc.lower() + '.gif')%0A        status = HTTPStatus.ok%0A        msg = 'OK'%0A%0A    if verbose and msg:%0A        print(cc, msg)%0A%0A    return Result(status, cc)%0A%0A%0A@asyncio.coroutine%0Adef downloader_coro(cc_list, base_url, verbose, concur_req):%0A    counter = collections.Counter()%0A    semaphore = asyncio.Semaphore(concur_req)%0A    to_do_iter = %5Bdownload_one(cc, base_url, semaphore, verbose) for cc in sorted(cc_list)%5D%0A    for future in to_do_iter:%0A        try:%0A            res = yield from future%0A        except FetchError as exc:%0A            country_code = exc.country_code%0A            try:%0A                error_msg = exc.__cause__.args%5B0%5D%0A            except IndexError:%0A                error_msg = exc.__cause__.__class__.__name__%0A            if verbose and error_msg:%0A                msg = '*** Error for %7B%7D: %7B%7D'%0A                print(msg.format(country_code, error_msg))%0A            status = HTTPStatus.error%0A        else:%0A            status = res.status%0A%0A        counter%5Bstatus%5D += 1%0A    return counter%0A%0A%0Adef download_many(cc_list, base_url, verbose, concur_req):%0A    loop = asyncio.get_event_loop()%0A    coro = downloader_coro(cc_list, base_url, verbose, concur_req)%0A    counts = loop.run_until_complete(coro)%0A    loop.close()%0A%0A    return counts%0A%0A%0Aif __name__ == '__main__':%0A    main(download_many, DEFAULT_CONCUR_REQ, MAX_CONCUR_REQ)%0A

Add flag2_asyncio