示例#1
0
def _code_fam_from_url(url):
    """Set url to cache and get code and family from cache.

    Site helper method.
    @param url: The site URL to get code and family
    @type url: str
    @raises SiteDefinitionError: Unknown URL
    """
    if url not in _url_cache:
        matched_sites = []
        # Iterate through all families and look, which does apply to
        # the given URL
        for fam in config.family_files:
            if fam == 'test':  # test_family.py is deprecated
                continue
            family = Family.load(fam)
            code = family.from_url(url)
            if code is not None:
                matched_sites.append((code, family))

        if not matched_sites:
            # TODO: As soon as AutoFamily is ready, try and use an
            #       AutoFamily
            raise SiteDefinitionError("Unknown URL '{0}'.".format(url))
        if len(matched_sites) > 1:
            warning('Found multiple matches for URL "{0}": {1} (use first)'
                    .format(url, ', '.join(str(s) for s in matched_sites)))
        _url_cache[url] = matched_sites[0]
    return _url_cache[url]
示例#2
0
def _code_fam_from_url(url: str):
    """Set url to cache and get code and family from cache.

    Site helper method.
    @param url: The site URL to get code and family
    @raises pywikibot.exceptions.SiteDefinitionError: Unknown URL
    """
    matched_sites = []
    # Iterate through all families and look, which does apply to
    # the given URL
    for fam in config.family_files:
        family = Family.load(fam)
        code = family.from_url(url)
        if code is not None:
            matched_sites.append((code, family))

    if not matched_sites:
        # TODO: As soon as AutoFamily is ready, try and use an
        #       AutoFamily
        raise SiteDefinitionError("Unknown URL '{}'.".format(url))
    if len(matched_sites) > 1:
        warning('Found multiple matches for URL "{}": {} (use first)'
                .format(url, ', '.join(str(s) for s in matched_sites)))
    return matched_sites[0]
示例#3
0
def Site(code=None, fam=None, user=None, sysop=None, interface=None, url=None):
    """A factory method to obtain a Site object.

    Site objects are cached and reused by this method.

    By default rely on config settings. These defaults may all be overridden
    using the method parameters.

    @param code: language code (override config.mylang)
    @type code: string
    @param fam: family name or object (override config.family)
    @type fam: string or Family
    @param user: bot user name to use on this site (override config.usernames)
    @type user: unicode
    @param sysop: sysop user to use on this site (override config.sysopnames)
    @type sysop: unicode
    @param interface: site class or name of class in pywikibot.site
        (override config.site_interface)
    @type interface: subclass of L{pywikibot.site.BaseSite} or string
    @param url: Instead of code and fam, does try to get a Site based on the
        URL. Still requires that the family supporting that URL exists.
    @type url: string
    @rtype: pywikibot.site.APISite

    """
    # Either code and fam or only url
    if url and (code or fam):
        raise ValueError('URL to the wiki OR a pair of code and family name '
                         'should be provided')
    _logger = "wiki"

    if url:
        if url not in _url_cache:
            matched_sites = []
            # Iterate through all families and look, which does apply to
            # the given URL
            for fam in config.family_files:
                family = Family.load(fam)
                code = family.from_url(url)
                if code is not None:
                    matched_sites += [(code, family)]

            if matched_sites:
                if len(matched_sites) > 1:
                    warning(
                        'Found multiple matches for URL "{0}": {1} (use first)'
                        .format(url, ', '.join(str(s) for s in matched_sites)))
                _url_cache[url] = matched_sites[0]
            else:
                # TODO: As soon as AutoFamily is ready, try and use an
                #       AutoFamily
                _url_cache[url] = None

        cached = _url_cache[url]
        if cached:
            code = cached[0]
            fam = cached[1]
        else:
            raise SiteDefinitionError("Unknown URL '{0}'.".format(url))
    else:
        # Fallback to config defaults
        code = code or config.mylang
        fam = fam or config.family

        if not isinstance(fam, Family):
            fam = Family.load(fam)

    interface = interface or fam.interface(code)

    # config.usernames is initialised with a defaultdict for each family name
    family_name = str(fam)

    code_to_user = config.usernames['*'].copy()
    code_to_user.update(config.usernames[family_name])
    user = user or code_to_user.get(code) or code_to_user.get('*')

    code_to_sysop = config.sysopnames['*'].copy()
    code_to_sysop.update(config.sysopnames[family_name])
    sysop = sysop or code_to_sysop.get(code) or code_to_sysop.get('*')

    if not isinstance(interface, type):
        # If it isnt a class, assume it is a string
        try:
            tmp = __import__('pywikibot.site', fromlist=[interface])
            interface = getattr(tmp, interface)
        except ImportError:
            raise ValueError('Invalid interface name: {0}'.format(interface))

    if not issubclass(interface, BaseSite):
        warning('Site called with interface=%s' % interface.__name__)

    user = normalize_username(user)
    key = '%s:%s:%s:%s' % (interface.__name__, fam, code, user)
    if key not in _sites or not isinstance(_sites[key], interface):
        _sites[key] = interface(code=code, fam=fam, user=user, sysop=sysop)
        debug(
            u"Instantiated %s object '%s'" % (interface.__name__, _sites[key]),
            _logger)

        if _sites[key].code != code:
            warn(
                'Site %s instantiated using different code "%s"' %
                (_sites[key], code), UserWarning, 2)

    return _sites[key]
示例#4
0
def Site(code=None, fam=None, user=None, sysop=None, interface=None, url=None):
    """A factory method to obtain a Site object.

    Site objects are cached and reused by this method.

    By default rely on config settings. These defaults may all be overridden
    using the method parameters.

    @param code: language code (override config.mylang)
    @type code: string
    @param fam: family name or object (override config.family)
    @type fam: string or Family
    @param user: bot user name to use on this site (override config.usernames)
    @type user: unicode
    @param sysop: sysop user to use on this site (override config.sysopnames)
    @type sysop: unicode
    @param interface: site class or name of class in pywikibot.site
        (override config.site_interface)
    @type interface: subclass of L{pywikibot.site.BaseSite} or string
    @param url: Instead of code and fam, does try to get a Site based on the
        URL. Still requires that the family supporting that URL exists.
    @type url: string
    """
    # Either code and fam or only url
    assert (not url or (not code and not fam))
    _logger = "wiki"

    if url:
        if url in _url_cache:
            cached = _url_cache[url]
            if cached:
                code = cached[0]
                fam = cached[1]
            else:
                raise SiteDefinitionError("Unknown URL '{0}'.".format(url))
        else:
            # Iterate through all families and look, which does apply to
            # the given URL
            for fam in config.family_files:
                try:
                    family = pywikibot.family.Family.load(fam)
                    code = family.from_url(url)
                    if code:
                        _url_cache[url] = (code, fam)
                        break
                except Exception as e:
                    pywikibot.warning('Error in Family(%s).from_url: %s' %
                                      (fam, e))
            else:
                _url_cache[url] = None
                # TODO: As soon as AutoFamily is ready, try and use an
                #       AutoFamily
                raise SiteDefinitionError("Unknown URL '{0}'.".format(url))
    else:
        # Fallback to config defaults
        code = code or config.mylang
        fam = fam or config.family
    interface = interface or config.site_interface

    # config.usernames is initialised with a dict for each family name
    family_name = str(fam)
    if family_name in config.usernames:
        user = user or config.usernames[family_name].get(code) \
            or config.usernames[family_name].get('*')
        sysop = sysop or config.sysopnames[family_name].get(code) \
            or config.sysopnames[family_name].get('*')

    if not isinstance(interface, type):
        # If it isnt a class, assume it is a string
        try:
            tmp = __import__('pywikibot.site', fromlist=[interface])
            interface = getattr(tmp, interface)
        except ImportError:
            raise ValueError("Invalid interface name '%(interface)s'" %
                             locals())

    if not issubclass(interface, pywikibot.site.BaseSite):
        warning('Site called with interface=%s' % interface.__name__)

    user = pywikibot.tools.normalize_username(user)
    key = '%s:%s:%s:%s' % (interface.__name__, fam, code, user)
    if key not in _sites or not isinstance(_sites[key], interface):
        _sites[key] = interface(code=code, fam=fam, user=user, sysop=sysop)
        debug(
            u"Instantiated %s object '%s'" % (interface.__name__, _sites[key]),
            _logger)

        if _sites[key].code != code:
            warn(
                'Site %s instantiated using different code "%s"' %
                (_sites[key], code), UserWarning, 2)

    return _sites[key]