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]
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]
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]
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]