当前位置: 首页>>代码示例>>Python>>正文


Python path.isabs函数代码示例

本文整理汇总了Python中os.path.isabs函数的典型用法代码示例。如果您正苦于以下问题:Python isabs函数的具体用法?Python isabs怎么用?Python isabs使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了isabs函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。

示例1: do_patch

    def do_patch(self):
        info('Patching package sources...', 3)

        filesdir = join(self.builddir, 'File')

        for child in self.package.xpath('b:RemoveFile', namespaces=XP_NSMAP):
            if isabs(child.get('Id')):
                error('Invalid RemoveFile action: Id attribute should not be an absolute path ("%s")' % child.get('Id'), 4)

            f = abspath(join(filesdir, child.get('Id')))

            if isfile(f):
                os.unlink(f)
            else:
                error('Invalid RemoveFile action: "%s" does not exist in "%s"' % (child.get('Id'), filesdir), 4)

        for child in self.package.xpath('b:CopyFile', namespaces=XP_NSMAP):
            if isabs(child.get('Src')):
                error('Invalid CopyFile action: Src attribute should not be an absolute path ("%s")' % child.get('Src'), 4)

            if isabs(child.get('Dest')):
                error('Invalid CopyFile action: Dest attribute should not be an absolute path ("%s")' % child.get('Dest'), 4)

            src = abspath(join(WIXDIR, child.get('Src'), child.get('Id')))
            dest = abspath(join(filesdir, child.get('Dest'), child.get('Id')))

            if isfile(src):
                copyfile(src, dest)
            else:
                error('Invalid CopyFile action: "%s" does not exist in "%s"' % (child.get('Src'), WIXDIR), 4)
开发者ID:dieterv,项目名称:pygtk-installer,代码行数:30,代码来源:build_installer.py

示例2: __init__

    def __init__(self, docker_client, tester, tester_name, 
                 tester_address, force_rm, nb_jobs, testsuite, 
                 testresults, use_fedora_selinux_policy):
        assert path.isabs(testsuite.path), 'testsuite needs to be an absolute path'
        assert path.isabs(testresults), 'testresults needs to be an absolute path'
        self.docker_client = docker_client
        self.force_rm = force_rm
        self.environment={"CGAL_TESTER" : tester,
                          "CGAL_TESTER_NAME" : tester_name,
                          "CGAL_TESTER_ADDRESS": tester_address,
                          "CGAL_NUMBER_OF_JOBS" : nb_jobs
        }
        self.host_config = docker.utils.create_host_config(binds={
            testsuite.path:
            {
                'bind': '/mnt/testsuite',
                'ro': True
            },
            testresults:
            {
                'bind': '/mnt/testresults',
                'ro': False
            }
        })

        if use_fedora_selinux_policy:
            self.host_config['Binds'][0] += 'z'
            self.host_config['Binds'][1] += 'z'
开发者ID:bo0ts,项目名称:cgal-testsuite-dockerfiles,代码行数:28,代码来源:cgal_docker.py

示例3: startstop

def startstop(action=None, stdout=os.devnull, stderr=None, stdin=os.devnull,
              pidfile='pid.txt', startmsg = 'started with pid %s' ):
    '''
        This is the "front-end"method for starting the daemon, stopping
        and restarting it.
    '''
    if len(action) > 1:
        setup()
        from os import path
        if not path.isabs(stdout):
            stdout = path.join(getAngelVarPath(), stdout)
        if not path.isabs(stderr):
            stderr = path.join(getAngelVarPath(), stderr)
        if not path.isabs(stdin):
            stdin = path.join(getAngelVarPath(), stdin)
        if not path.isabs(pidfile):
            pidfile = path.join(getAngelVarPath(), pidfile)
        try:
            pf  = file(pidfile,'r')
            pid = int(pf.read().strip())
            pf.close()
        except IOError:
            pid = None
        if 'stop' == action or 'restart' == action:
            if not pid:
                mess = "Could not stop, pid file '%s' missing.%s"
                sys.stderr.write(mess % (pidfile, os.linesep))
                sys.exit(1)
            try:
                countSIGTERM = 0
                sleepTime = 1
                while 1:
                    if countSIGTERM > 3:
                        sys.stderr.write("Process not responding, sending SIGKILL to process with PID %i.%s" % (pid, os.linesep))
                        os.kill(pid,SIGKILL)
                    else:
                        os.kill(pid,SIGTERM)
                    countSIGTERM += 1
                    time.sleep(sleepTime)
                    # send signal 0 straight away, no need to re-enter the loop
                    os.kill(pid, 0)
                    sleepTime = sleepTime + 1
            except OSError, err:
                err = str(err)
                if err.find("No such process") > 0:
                    os.remove(pidfile)
                    if 'stop' == action:
                        sys.exit(0)
                    action = 'start'
                    pid = None
                else:
                    print str(err)
                    sys.exit(1)
        if 'start' == action:
            if pid:
                mess = "Start aborded since pid file '%s' exists.%s"
                sys.stderr.write(mess % (pidfile, os.linesep))
                sys.exit(1)
            daemonize(stdout,stderr,stdin,pidfile,startmsg)
            return
开发者ID:infothrill,项目名称:angel-app-svnmirror,代码行数:60,代码来源:daemonizer.py

示例4: correct_resources_path

def correct_resources_path(previewdir):
    res_dir_path = join(previewdir, "resources")
    guard_slashes = blend4web.exporter.guard_slashes
    if exists(res_dir_path):
        shutil.rmtree(res_dir_path)
    os.mkdir(res_dir_path)
    root = bpy.context.user_preferences.addons[__package__].preferences.b4w_src_path
    json_path = join(previewdir, "preview.json")

    json_parsed = json.loads(blend4web.exporter.get_main_json_data())

    if "images" in json_parsed:
        for img in json_parsed["images"]:
            if isabs(img["filepath"]) or len(img["filepath"].split("..")) > 3:
                file_name = copy_resource(img["filepath"], previewdir)
                img["filepath"] = guard_slashes(join("resources", file_name))
    if "sounds" in json_parsed:
        for sound in json_parsed["sounds"]:
            if isabs(sound["filepath"]) or len(sound["filepath"].split("..")) > 3:
                file_name = copy_resource(sound["filepath"], previewdir)
                sound["filepath"] = guard_slashes(join("resources", file_name))
    if len(os.listdir(res_dir_path)):
        try:
            f  = open(json_path, "w", encoding="utf-8")
        except IOError as exp:
            raise FileError("Permission denied")
        else:
            f.write(json.dumps(json_parsed))
            f.close()
开发者ID:radziksh,项目名称:floe,代码行数:29,代码来源:server.py

示例5: sanityChecks

 def sanityChecks(self, cliargs):
     passed = HSN2Service.sanityChecks(self, cliargs)
     if path.isdir(cliargs.nugget):
         logging.error("'%s' is a directory" % cliargs.nugget)
         passed = False
     if not access(cliargs.nugget, X_OK):
         logging.error("'%s' isn't executable or does not exist!" % cliargs.nugget)
         passed = False
     if not path.isabs(cliargs.inputmapping):
         cliargs.inputmapping = self.mappings + cliargs.inputmapping
     if path.isdir(cliargs.inputmapping):
         logging.error("'%s' is a directory" % cliargs.inputmapping)
         passed = False
     elif not path.isfile(cliargs.inputmapping):
         logging.error("'%s' does not exist!" % cliargs.inputmapping)
         passed = False
     if not path.isabs(cliargs.outputmapping):
         cliargs.outputmapping = self.mappings + cliargs.outputmapping
     if path.isdir(cliargs.outputmapping):
         logging.error("'%s' is a directory" % cliargs.outputmapping)
         passed = False
     elif not path.isfile(cliargs.outputmapping):
         logging.error("'%s' does not exist!" % cliargs.outputmapping)
         passed = False
     if passed is True:
         cliargs.inputmapping = self.importMapping(cliargs.inputmapping)
         cliargs.outputmapping = self.importMapping(cliargs.outputmapping)
         if cliargs.inputmapping is None or cliargs.outputmapping is None:
             passed = False
     return passed
开发者ID:CERT-Polska,项目名称:hsn2-razorback,代码行数:30,代码来源:nuggetService.py

示例6: read_settings

def read_settings(path=None, override=None):
    if path:
        local_settings = get_settings_from_file(path)
        # Make the paths relative to the settings file
        for p in ['PATH', 'OUTPUT_PATH', 'THEME']:
            if p in local_settings and local_settings[p] is not None \
                    and not isabs(local_settings[p]):
                absp = os.path.abspath(os.path.normpath(os.path.join(
                    os.path.dirname(path), local_settings[p])))
                if p not in ('THEME') or os.path.exists(absp):
                    local_settings[p] = absp

        if isinstance(local_settings['PLUGIN_PATH'], six.string_types):
            logger.warning("Defining %s setting as string has been deprecated (should be a list)" % 'PLUGIN_PATH')
            local_settings['PLUGIN_PATH'] = [local_settings['PLUGIN_PATH']]
        else:
            if 'PLUGIN_PATH' in local_settings and local_settings['PLUGIN_PATH'] is not None:
                local_settings['PLUGIN_PATH'] = [os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(path), pluginpath)))
                                    if not isabs(pluginpath) else pluginpath for pluginpath in local_settings['PLUGIN_PATH']]
    else:
        local_settings = copy.deepcopy(DEFAULT_CONFIG)

    if override:
        local_settings.update(override)

    parsed_settings = configure_settings(local_settings)
    # This is because there doesn't seem to be a way to pass extra
    # parameters to docutils directive handlers, so we have to have a
    # variable here that we'll import from within Pygments.run (see
    # rstdirectives.py) to see what the user defaults were.
    global PYGMENTS_RST_OPTIONS
    PYGMENTS_RST_OPTIONS = parsed_settings.get('PYGMENTS_RST_OPTIONS', None)
    return parsed_settings
开发者ID:aftersomemath,项目名称:pelican,代码行数:33,代码来源:settings.py

示例7: __init__

    def __init__(self, name, test_definition):
        self.name = name
        test_definition = deep_merge(default_config, test_definition)
        # quick shortcuts
        self.test_env = test_definition['environment']
        self.test_meta = test_definition['meta']
        self.test_commands = test_definition.get('test_commands', [])
        # take care of commands ...
        self.test_commands = _build_exec_array(self.test_commands)
        self.test_meta['test_before'] = \
            _build_exec_array(self.test_meta.get('test_before', None))
        self.test_meta['test_after'] = \
            _build_exec_array(self.test_meta.get('test_after', None))

        # okay.
        # let's keep all file references relative to the configuration
        # file. easy to remember.
        configfilepath = realpath(dirname(self.test_meta.get('_configfile',
                                                             './dummy')))
        # self.TEMPLATE / .TEMPLATE_NAME
        tmp = self.test_meta['docker_compose_template']
        if not isabs(tmp):
            tmp = realpath(join(configfilepath, tmp))
        self.template = tmp
        self.template_name = basename(self.template)
        # self.BASEDIR
        tmp = self.test_meta.get('test_basedir', configfilepath)
        if not isabs(tmp):
            tmp = realpath(join(configfilepath, tmp))
        self.base_dir = tmp
        # self.SANITIZED_NAME, .TEST_DIR
        self.sanitized_name = resub("[^a-zA-Z0-9_]", "-", self.name)
        self.test_dir = dbg_tr_get_testdir(self.base_dir, self.sanitized_name)
        # extend SELF.TEST_ENV with TEST_DIR
        self.test_env['test_dir'] = self.test_dir
        # create SELF.COMMANDLINE
        self.commandline = copy.copy(default_commandline_start)
        for param in self.test_meta['docker_compose_params']:
            self.commandline.append(param)
        for key, val in self.test_env.items():
            self.commandline.append("-e")
            self.commandline.append("%s=%s" % (key, val))
        self.commandline.append("--rm")
        self.commandline.extend(copy.copy(default_commandline_end))
        self.commandline.append(self.test_meta['test_service'])
        # create .STATE, .RESULT, .EXCEPTION, .REASON
        self.state = self.NOTRUN
        self.results = []
        self.exception = None
        self.reason = None
        # log setup
        # NO LOGGING BEFORE HERE
        log_filename = join(self.base_dir, basename(self.test_dir)) + ".log"
        self.log = get_logger("t-%s" % self.name, filename=log_filename)
        # some debug output
        self.log.info("base commandline '%s'" % " ".join(self.commandline))
        self.log.debug("test directory '%s'" % self.test_dir)
        self.log.debug("template path '%s'" % self.template)
        for key, val in self.test_env.items():
            self.log.debug("env %s=%s" % (key, val))
开发者ID:mkoepf,项目名称:python-intmaniac,代码行数:60,代码来源:testrun.py

示例8: load_pipeline_from_template

def load_pipeline_from_template(name, func=None, args=None, kwargs=None):
    """Given a name, loads that pipeline from datalad.crawler.pipelines

    and later from other locations

    Parameters
    ----------
    name: str
        Name of the pipeline defining the filename. Or full path to it (TODO)
    args: dict, optional
        Positional args for the pipeline, passed as *args into the pipeline call
    kwargs: dict, optional
        Keyword args for the pipeline, passed as **kwargs into the pipeline call
    """

    if isabs(name) or exists(name):
        raise NotImplementedError("Don't know how to import straight path %s yet" % name)

    # explicit isabs since might not exist
    filename = name \
        if (isabs(name) or exists(name)) \
        else _find_pipeline(name)

    if filename:
        if not exists(filename):
            raise IOError("Pipeline file %s is N/A" % filename)
    else:
        raise ValueError("could not find pipeline for %s" % name)

    return load_pipeline_from_module(filename, func=func, args=args, kwargs=kwargs)
开发者ID:glalteva,项目名称:datalad,代码行数:30,代码来源:pipeline.py

示例9: SpawnPatchTarget

def SpawnPatchTarget(destination_folder, payload_path):
    try:
        if payload_path and not path.isabs(payload_path):
            payload_path = path.join(RoverSettings._LaunchedFromDirectory, payload_path)

        if not path.isabs(destination_folder):
            destination_folder = path.join(RoverSettings._LaunchedFromDirectory, destination_folder)

        if not path.exists(str(payload_path)):
            fallback_url = 'https://dotnetcli.blob.core.windows.net/dotnet/Sdk/rel-1.0.0/dotnet-dev-debian-x64.latest.tar.gz'               

            payload_filename    = 'dotnet.latest.tar.gz'
            payload_path        = path.join(RoverSettings._objDirectory, payload_filename)
            
            if not path.exists(payload_path):
                RoverPrint(RoverMods.Blue('is downloading latest .NET CLI for bootstrapping (%s)'%(payload_filename)))

            urlretrieve(fallback_url, payload_path)
        
        # lets force the path to be made absolute - assuming that the payload path is relative to the directory we launched the script from.
        # otherwise if we have an abs path already - fantastic.

        RoverShellCall('tar xf %s -C %s'%(payload_path, destination_folder))    
    except:
        RoverSettings._DevMode = True
        UnexpectedRoverException(sys.exc_info())
    
    RoverSettings.SetPatchTargetPath(path.join(RoverSettings._ScriptDirectory, destination_folder))
开发者ID:mairaw,项目名称:core,代码行数:28,代码来源:dotnet.bootstrap.py

示例10: __init__

 def __init__(self, protocol, path, mp,
              host=None,
              user=None,
              pw=None,
              fs_type=FsType.UNKNOWN,
              read_only=False,
              no_atime_updates=False,
              direct_attribute_access=False,
              domain=None):
     assert is_valid_protocol(protocol), "%s is not a valid protocol code" % protocol
     self.protocol = protocol
     self.path = path
     assert isabs(mp), "Mount point %s not absolute" % mp
     self.mp = mp
     if ' ' in self.mp:
         logger.warn("'%s': Mount points with spaces are not supported by get_mount_info()"
                     % self.mp)
     assert isabs(self.mp)
     self.host = host
     self.user = user
     self.pw = pw
     assert is_valid_fstype(fs_type), "%s is not a valid fs_type code" % fs_type
     self.fs_type = fs_type
     self.read_only = read_only
     self.no_atime_updates = no_atime_updates
     self.direct_attribute_access = direct_attribute_access
     self.domain = domain
开发者ID:quaddra,项目名称:engage-utils,代码行数:27,代码来源:mount.py

示例11: run_bam_to_bam

def run_bam_to_bam(subread_set_file, barcode_set_file, output_file_name,
                   nproc=1):
    bc = BarcodeSet(barcode_set_file)
    if len(bc.resourceReaders()) > 1:
        raise NotImplementedError("Multi-FASTA BarcodeSet input is not supported.")
    barcode_fasta = bc.toExternalFiles()[0]
    with SubreadSet(subread_set_file) as ds:
        # TODO(nechols)(2016-03-15): replace with BarcodedSubreadSet
        ds_new = SubreadSet(strict=True)
        for ext_res in ds.externalResources:
            subreads_bam = ext_res.bam
            scraps_bam = ext_res.scraps
            assert subreads_bam is not None
            if scraps_bam is None:
                raise TypeError("The input SubreadSet must include scraps.")
            new_prefix = op.join(op.dirname(output_file_name),
                re.sub(".subreads.bam", "_barcoded", op.basename(subreads_bam)))
            if not op.isabs(subreads_bam):
                subreads_bam = op.join(op.dirname(subread_set_file),
                    subreads_bam)
            if not op.isabs(scraps_bam):
                scraps_bam = op.join(op.dirname(subread_set_file), scraps_bam)
            args = [
                "bam2bam",
                "-j", str(nproc),
                "-b", str(nproc),
                "-o", new_prefix,
                "--barcodes", barcode_fasta,
                subreads_bam, scraps_bam
            ]
            print args
            log.info(" ".join(args))
            result = run_cmd(" ".join(args),
                             stdout_fh=sys.stdout,
                             stderr_fh=sys.stderr)
            if result.exit_code != 0:
                return result.exit_code
            subreads_bam = new_prefix + ".subreads.bam"
            scraps_bam = new_prefix + ".scraps.bam"
            assert op.isfile(subreads_bam), "Missing {f}".format(f=subreads_bam)
            # FIXME we need a more general method for this
            ext_res_new = ExternalResource()
            ext_res_new.resourceId = subreads_bam
            ext_res_new.metaType = 'PacBio.SubreadFile.SubreadBamFile'
            ext_res_new.addIndices([subreads_bam + ".pbi"])
            ext_res_inner = ExternalResources()
            ext_res_scraps = ExternalResource()
            ext_res_scraps.resourceId = scraps_bam
            ext_res_scraps.metaType = 'PacBio.SubreadFile.ScrapsBamFile'
            ext_res_scraps.addIndices([scraps_bam + ".pbi"])
            ext_res_inner.append(ext_res_scraps)
            ext_res_new.append(ext_res_inner)
            ds_new.externalResources.append(ext_res_new)
        ds._filters.clearCallbacks()
        ds_new._filters = ds._filters
        ds_new._populateMetaTypes()
        ds_new.updateCounts()
        ds_new.write(output_file_name)
    return 0
开发者ID:mpkocher,项目名称:pbcoretools,代码行数:59,代码来源:converters.py

示例12: _validate_paths

def _validate_paths(virtualenv_path, setup_or_req_file):
    """
    Validate that both the virtualenv folder path and the "other file" is an
    absolute path, additionally checking that the "other file" exists and is
    a file.
    """
    assert path.isabs(virtualenv_path)
    assert path.isabs(setup_or_req_file) and path.isfile(setup_or_req_file)
开发者ID:imoore76,项目名称:ship_it,代码行数:8,代码来源:virtualenv.py

示例13: pytest_configure

def pytest_configure(config):
    """
    pytest hook to configure plugin.
    """
    # Get registered options
    platform = config.getoption('--topology-platform')
    plot_format = config.getoption('--topology-plot-format')
    plot_dir = config.getoption('--topology-plot-dir')
    nml_dir = config.getoption('--topology-nml-dir')
    injection_file = config.getoption('--topology-inject')

    # Determine plot directory and create it if required
    if plot_dir:
        if not isabs(plot_dir):
            plot_dir = join(abspath(getcwd()), plot_dir)
        if not exists(plot_dir):
            makedirs(plot_dir)

    # Determine NML export directory and create it if required
    if nml_dir:
        if not isabs(nml_dir):
            nml_dir = join(abspath(getcwd()), nml_dir)
        if not exists(nml_dir):
            makedirs(nml_dir)

    # Parse attributes injection file
    from ..injection import parse_attribute_injection
    injected_attr = None
    if injection_file is not None:

        # Get a list of all testing directories
        search_paths = [
            abspath(arg) for arg in config.args if isdir(arg)
        ]

        injected_attr = parse_attribute_injection(
            injection_file,
            search_paths=search_paths
        )

    # Create and register plugin
    config._topology_plugin = TopologyPlugin(
        platform, plot_dir, plot_format.lstrip('.'), nml_dir, injected_attr
    )
    config.pluginmanager.register(config._topology_plugin)

    # Add test_id marker
    config.addinivalue_line(
        'markers',
        'test_id(id): assign a test identifier to the test'
    )

    # Add topology_compatible marker
    config.addinivalue_line(
        'markers',
        'platform_incompatible(platforms): '
        'mark a test as incompatible with a list of platform engines'
    )
开发者ID:baraserg,项目名称:topology,代码行数:58,代码来源:plugin.py

示例14: safe

def safe(arg, blacklist, matcher):
    '''
    Check whether an argument is safe to delete.

    Parameters
    ----------
    arg
        Input argument.
    blacklist
        A list of files that should be kept.
    matcher : str
        Name of the matcher: `str`, `fnmatch` or `re`.

    Returns
    -------
    bool
        True if argument is safe to delete, False otherwise.

    Raises
    ------
    Exception
        The matcher is unknown.
    '''
    path = abspath(expanduser(arg))

    if matcher == 'str':
        for pattern in blacklist:
            pattern = expanduser(pattern)
            if isabs(pattern):
                if pattern == path:
                    return False
            else:
                if pattern in path:
                    return False
        return True
    elif matcher == 'fnmatch':
        for pattern in blacklist:
            pattern = expanduser(pattern)
            if isabs(pattern):
                if fnmatch(path, pattern):
                    return False
            else:
                if fnsearch(path, pattern):
                    return False
        return True
    elif matcher == 're':
        for pattern in blacklist:
            pattern = expanduser(pattern)
            if isabs(pattern):
                if re.match(pattern, path):
                    return False
            else:
                if re.search(pattern, path):
                    return False
        return True
    else:
        raise Exception('unknown matcher {}'.format(matcher))
开发者ID:cykerway,项目名称:blrm,代码行数:57,代码来源:__main__.py

示例15: main

def main():
    parser = create_parser()
    try:
        args = parser.parse_args()
    except argparse.ArgumentError as exc:
        logging.exception('Error parsing arguments.')
        parser.error(str(exc))
        sys.exit(1)

    conf_file = args.config

    # load config file
    with open(conf_file, 'r') as yml_file:
        config = yaml.load(yml_file)

    # read config values
    bot_name = config.get("BOT_NAME",    '')
    daemon   = config.get("DAEMON",      False)
    token    = config.get("SLACK_TOKEN", '')
    implants = config.get("IMPLANTS",    '')
    logfile  = config.get("LOGFILE",     '')
    debug    = config.get("DEBUG",       True)

    # logging setup
    loglvl = logging.DEBUG if debug else logging.INFO
    if not op.isabs(logfile):
        logfile = op.join(op.dirname(op.abspath(conf_file)), logfile)
    setup_logging(logfile, loglvl)

    # add implants folders to sys.path and correct relative paths to be relative to the config file
    config_dir = op.dirname(op.abspath(conf_file))
    for name in implants:
        im_file = implants[name].get('file', '')
        if im_file and not op.isabs(im_file):
            im_file = implants[name]['file'] = op.join(config_dir, im_file)

        if op.exists(im_file):
            im_dir = op.dirname(im_file)
            if im_dir not in sys.path:
                sys.path.insert(0, im_dir)

    # setup bot
    setup_bot_and_guardian(bot_name, token, implants)

    # start
    if daemon:
        log.info('Launching daemon.')
        import daemon
        try:
            with daemon.DaemonContext(pidfile="daemon.pid",
                                      stdout=open("daemon_out.log", "wb"),
                                      stderr=open("daemon-err.log", "wb")):
                bot_loop()
        except:
            raise
    else:
        bot_loop()
开发者ID:PythonSanSebastian,项目名称:helbot,代码行数:57,代码来源:main.py


注:本文中的os.path.isabs函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。