'Initialize the recipe.
:param options: Parsed commandline options
:param log:  Logging object
:param progress_reporter: A Callable that takes two arguments: progress (a number between 0 and 1) and a string message. The message should be optional.'

def __init__(self, options, log, progress_reporter):

    self.log = ThreadSafeWrapper(log)
    if (not isinstance(self.title, unicode)):
        self.title = unicode(self.title, 'utf-8', 'replace')
    self.debug = (options.verbose > 1)
    self.output_dir = os.path.abspath(os.getcwdu())
    self.verbose = options.verbose
    self.test = options.test
    if (self.test and (not isinstance(self.test, tuple))):
        self.test = (2, 2)
    self.username = options.username
    self.password = options.password
    self.lrf = options.lrf
    self.output_profile = options.output_profile
    self.touchscreen = getattr(self.output_profile, 'touchscreen', False)
    if self.touchscreen:
        self.template_css += self.output_profile.touchscreen_news_css
    if self.test:
        self.max_articles_per_feed = self.test[1]
        self.simultaneous_downloads = min(4, self.simultaneous_downloads)
    if self.debug:
        self.verbose = True
    self.report_progress = progress_reporter
    if isinstance(self.feeds, basestring):
        self.feeds = eval(self.feeds)
        if isinstance(self.feeds, basestring):
            self.feeds = [self.feeds]
    if (self.needs_subscription and ((self.username is None) or (self.password is None) or ((not self.username) and (not self.password)))):
        if (self.needs_subscription != 'optional'):
            raise ValueError((_('The    "%s"    recipe    needs    a    username    and    password.') % self.title))
    self.browser = self.get_browser()
    (self.image_map, self.image_counter) = ({}, 1)
    self.css_map = {}
    web2disk_cmdline = ['web2disk', '--timeout', str(self.timeout), '--max-recursions', str(self.recursions), '--delay', str(self.delay)]
    if self.verbose:
        web2disk_cmdline.append('--verbose')
    if self.no_stylesheets:
        web2disk_cmdline.append('--dont-download-stylesheets')
    for reg in self.match_regexps:
        web2disk_cmdline.extend(['--match-regexp', reg])
    for reg in self.filter_regexps:
        web2disk_cmdline.extend(['--filter-regexp', reg])
    if (options.output_profile.short_name == 'default'):
        self.scale_news_images_to_device = False
    elif self.scale_news_images_to_device:
        self.scale_news_images = options.output_profile.screen_size
    self.web2disk_options = web2disk_option_parser().parse_args(web2disk_cmdline)[0]
    for extra in ('keep_only_tags', 'remove_tags', 'preprocess_regexps', 'skip_ad_pages', 'preprocess_html', 'remove_tags_after', 'remove_tags_before', 'is_link_wanted', 'compress_news_images', 'compress_news_images_max_size', 'compress_news_images_auto_size', 'scale_news_images'):
        setattr(self.web2disk_options, extra, getattr(self, extra))
    self.web2disk_options.postprocess_html = self._postprocess_html
    self.web2disk_options.preprocess_image = self.preprocess_image
    self.web2disk_options.encoding = self.encoding
    self.web2disk_options.preprocess_raw_html = self.preprocess_raw_html_
    if (self.delay > 0):
        self.simultaneous_downloads = 1
    self.navbar = (templates.TouchscreenNavBarTemplate() if self.touchscreen else templates.NavBarTemplate())
    self.failed_downloads = []
    self.partial_failures = []
