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


Python JobItem.waitEmpty方法代码示例

本文整理汇总了Python中twext.enterprise.jobs.jobitem.JobItem.waitEmpty方法的典型用法代码示例。如果您正苦于以下问题:Python JobItem.waitEmpty方法的具体用法?Python JobItem.waitEmpty怎么用?Python JobItem.waitEmpty使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在twext.enterprise.jobs.jobitem.JobItem的用法示例。


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

示例1: test_addressbookObjectRevisions

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_addressbookObjectRevisions(self):
        """
        Verify that all extra addressbook object revisions are deleted by FindMinValidRevisionWork and RevisionCleanupWork
        """

        # get sync token
        addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
        token = yield addressbook.syncToken()

        # make changes
        card1Object = yield self.addressbookObjectUnderTest(self.transactionUnderTest(), name="card1.vcf", addressbook_name="addressbook", home="user01")
        yield card1Object.remove()
        card2Object = yield self.addressbookObjectUnderTest(self.transactionUnderTest(), name="card2.vcf", addressbook_name="addressbook", home="user01")
        yield card2Object.remove()

        # Get object revisions
        rev = schema.ADDRESSBOOK_OBJECT_REVISIONS
        revisionRows = yield Select(
            [rev.REVISION],
            From=rev,
        ).on(self.transactionUnderTest())
        self.assertNotEqual(len(revisionRows), 0)

        # do FindMinValidRevisionWork
        yield self.transactionUnderTest().enqueue(FindMinValidRevisionWork, notBefore=datetime.datetime.utcnow())
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        # Get the minimum valid revision and check it
        minValidRevision = yield self.transactionUnderTest().calendarserverValue("MIN-VALID-REVISION")
        self.assertEqual(int(minValidRevision), max([row[0] for row in revisionRows]) + 1)

        # do RevisionCleanupWork
        yield self.transactionUnderTest().enqueue(RevisionCleanupWork, notBefore=datetime.datetime.utcnow())
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        # Get group1 object revision
        rev = schema.ADDRESSBOOK_OBJECT_REVISIONS
        revisionRows = yield Select(
            [rev.REVISION],
            From=rev,
        ).on(self.transactionUnderTest())
        self.assertEqual(len(revisionRows), 0)

        # old sync token fails
        addressbook = yield self.addressbookUnderTest(home="user01", name="addressbook")
        yield self.failUnlessFailure(addressbook.resourceNamesSinceToken(token), SyncTokenValidException)
开发者ID:eventable,项目名称:CalendarServer,代码行数:50,代码来源:test_revision_cleanup.py

示例2: test_old

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_old(self):
        """
        Verify that old inbox items are removed
        """
        self.patch(config.InboxCleanup, "ItemLifeBeyondEventEndDays", -1)

        # Predate some inbox items
        inbox = yield self.calendarUnderTest(home="user01", name="inbox")
        oldDate = datetime.datetime.utcnow() - datetime.timedelta(days=float(config.InboxCleanup.ItemLifetimeDays), seconds=10)

        itemsToPredate = ["cal2.ics", "cal3.ics"]
        co = schema.CALENDAR_OBJECT
        yield Update(
            {co.CREATED: oldDate},
            Where=co.RESOURCE_NAME.In(Parameter("itemsToPredate", len(itemsToPredate))).And(
                co.CALENDAR_RESOURCE_ID == inbox._resourceID)
        ).on(self.transactionUnderTest(), itemsToPredate=itemsToPredate)

        # do cleanup
        yield self.transactionUnderTest().enqueue(CleanupOneInboxWork, homeID=inbox.ownerHome()._resourceID, notBefore=datetime.datetime.utcnow())
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        # check that old items are deleted
        inbox = yield self.calendarUnderTest(home="user01", name="inbox")
        items = yield inbox.objectResources()
        names = [item.name() for item in items]
        self.assertEqual(set(names), set(["cal1.ics"]))
开发者ID:eventable,项目名称:CalendarServer,代码行数:30,代码来源:test_inbox_cleanup.py

示例3: test_inboxCleanupWorkQueueing

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_inboxCleanupWorkQueueing(self):
        """
        Verify that InboxCleanupWork queues one CleanupOneInboxBoxWork per home
        """
        self.patch(config.InboxCleanup, "CleanupPeriodDays", -1)

        class FakeCleanupOneInboxWork(WorkItem):
            scheduledHomeIDs = []

            @classmethod
            def reschedule(cls, txn, seconds, homeID):
                cls.scheduledHomeIDs.append(homeID)
                pass

        self.patch(CleanupOneInboxWork, "reschedule", FakeCleanupOneInboxWork.reschedule)

        # do cleanup
        yield InboxCleanupWork.reschedule(self.transactionUnderTest(), 0)
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        ch = schema.CALENDAR_HOME
        workRows = yield Select(
            [ch.OWNER_UID],
            From=ch,
            Where=ch.RESOURCE_ID.In(Parameter("scheduledHomeIDs", len(FakeCleanupOneInboxWork.scheduledHomeIDs))),
        ).on(self.transactionUnderTest(), scheduledHomeIDs=FakeCleanupOneInboxWork.scheduledHomeIDs)
        homeUIDs = [workRow[0] for workRow in workRows]
        self.assertEqual(set(homeUIDs), set(['user01', 'user02'])) # two homes
开发者ID:eventable,项目名称:CalendarServer,代码行数:31,代码来源:test_inbox_cleanup.py

示例4: test_processReply

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_processReply(self):
        # Make sure an unknown token in an older email is deleted
        msg = email.message_from_string(self.dataFile('good_reply_past'))
        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.UNKNOWN_TOKEN_OLD)

        # Make sure an unknown token is not processed
        msg = email.message_from_string(self.dataFile('good_reply_future'))
        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.UNKNOWN_TOKEN)

        # Make sure a known token *is* processed
        txn = self.store.newTransaction()
        yield txn.imipCreateToken(
            "urn:x-uid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
            "mailto:[email protected]",
            "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
            token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
        )
        yield txn.commit()

        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.INJECTION_SUBMITTED)

        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
开发者ID:eventable,项目名称:CalendarServer,代码行数:27,代码来源:test_inbound.py

示例5: test_work

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_work(self):

        calendar = """BEGIN:VCALENDAR
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
VERSION:2.0
METHOD:REPLY
BEGIN:VEVENT
UID:12345-67890
DTSTAMP:20130208T120000Z
DTSTART:20180601T120000Z
DTEND:20180601T130000Z
ORGANIZER:urn:x-uid:user01
ATTENDEE:mailto:[email protected];PARTSTAT=ACCEPTED
END:VEVENT
END:VCALENDAR
"""
        txn = self.store.newTransaction()
        yield txn.enqueue(
            IMIPReplyWork,
            organizer="urn:x-uid:user01",
            attendee="mailto:[email protected]",
            icalendarText=calendar
        )
        yield txn.commit()
        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
开发者ID:eventable,项目名称:CalendarServer,代码行数:27,代码来源:test_inbound.py

示例6: test_notificationObjectRevisions

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_notificationObjectRevisions(self):
        """
        Verify that all extra notification object revisions are deleted by FindMinValidRevisionWork and RevisionCleanupWork
        """

        # get sync token
        home = yield self.homeUnderTest(name="user01")
        token = yield home.syncToken()

        # make notification changes as side effect of sharing
        yield self._createCalendarShare()

        # Get object revisions
        rev = schema.NOTIFICATION_OBJECT_REVISIONS
        revisionRows = yield Select(
            [rev.REVISION],
            From=rev,
        ).on(self.transactionUnderTest())
        self.assertNotEqual(len(revisionRows), 0)

        # do FindMinValidRevisionWork
        yield self.transactionUnderTest().enqueue(FindMinValidRevisionWork, notBefore=datetime.datetime.utcnow())
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        # Get the minimum valid revision and check it
        minValidRevision = yield self.transactionUnderTest().calendarserverValue("MIN-VALID-REVISION")
        self.assertEqual(int(minValidRevision), max([row[0] for row in revisionRows]) + 1)

        # do RevisionCleanupWork
        yield self.transactionUnderTest().enqueue(RevisionCleanupWork, notBefore=datetime.datetime.utcnow())
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        # Get group1 object revision
        rev = schema.NOTIFICATION_OBJECT_REVISIONS
        revisionRows = yield Select(
            [rev.REVISION],
            From=rev,
        ).on(self.transactionUnderTest())
        self.assertEqual(len(revisionRows), 0)

        # old sync token fails
        home = yield self.homeUnderTest(name="user01")
        yield self.failUnlessFailure(home.resourceNamesSinceToken(token, "1"), SyncTokenValidException)
        yield self.failUnlessFailure(home.resourceNamesSinceToken(token, "infinity"), SyncTokenValidException)
开发者ID:eventable,项目名称:CalendarServer,代码行数:48,代码来源:test_revision_cleanup.py

示例7: test_workFailure

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_workFailure(self):
        self.sender.smtpSender.shouldSucceed = False

        txn = self.store.newTransaction()
        yield txn.enqueue(
            IMIPInvitationWork,
            fromAddr=ORGANIZER,
            toAddr=ATTENDEE,
            icalendarText=initialInviteText.replace("\n", "\r\n"),
        )
        yield txn.commit()
        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
开发者ID:eventable,项目名称:CalendarServer,代码行数:14,代码来源:test_outbound.py

示例8: test_cascade_delete_cleanup

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_cascade_delete_cleanup(self):
        """
        Test that when work associated with L{txdav.caldav.datastore.scheduling.work.ScheduleWork}
        is removed with the L{ScheduleWork} item being removed, the associated L{JobItem} runs and
        removes itself and the L{ScheduleWork}.
        """

        ScheduleWorkMixin._queued = 0
        txn = self.transactionUnderTest()
        home = yield self.homeUnderTest(name="user01")
        yield ScheduleOrganizerWork.schedule(
            txn,
            "12345-67890",
            "create",
            home,
            None,
            None,
            self.calendar_new,
            "urn:uuid:user01",
            2,
            True,
        )
        yield self.commit()
        self.assertEqual(ScheduleWorkMixin._queued, 1)

        jobs = yield JobItem.all(self.transactionUnderTest())
        work = yield jobs[0].workItem()
        yield WorkItem.delete(work)
        yield self.commit()

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 1)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 1)
        self.assertEqual(baseWork[0].jobID, jobs[0].jobID)

        work = yield jobs[0].workItem()
        self.assertTrue(work is None)
        yield self.commit()

        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        jobs = yield JobItem.all(self.transactionUnderTest())
        self.assertEqual(len(jobs), 0)
        work = yield ScheduleOrganizerWork.all(self.transactionUnderTest())
        self.assertEqual(len(work), 0)
        baseWork = yield ScheduleWork.all(self.transactionUnderTest())
        self.assertEqual(len(baseWork), 0)
开发者ID:eventable,项目名称:CalendarServer,代码行数:50,代码来源:test_work.py

示例9: test_processReplyMissingAttendee

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_processReplyMissingAttendee(self):
        msg = email.message_from_string(self.dataFile('reply_missing_attendee'))

        txn = self.store.newTransaction()
        yield txn.imipCreateToken(
            "urn:x-uid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
            "mailto:[email protected]",
            "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
            token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
        )
        yield txn.commit()

        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.INJECTION_SUBMITTED)

        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
开发者ID:eventable,项目名称:CalendarServer,代码行数:18,代码来源:test_inbound.py

示例10: test_basicWork

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_basicWork(self):
        """
        Verify that an L{TestWork} item can be enqueued and executed.
        """

        # do FindMinValidRevisionWork
        yield TestWork.schedule(self.storeUnderTest(), 0, 1, 2, 3)

        work = yield TestWork.all(self.transactionUnderTest())
        self.assertEqual(len(work), 1)
        self.assertEqual(work[0].delay, 3)
        job = yield JobItem.querysimple(self.transactionUnderTest(), jobID=work[0].jobID)
        self.assertEqual(len(job), 1)
        self.assertEqual(job[0].priority, 1)
        self.assertEqual(job[0].weight, 2)
        yield self.commit()

        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)
开发者ID:eventable,项目名称:CalendarServer,代码行数:20,代码来源:test_load_work.py

示例11: test_ImportComponentOrganizer

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_ImportComponentOrganizer(self):

        component = Component.allFromString(DATA_WITH_ORGANIZER)
        yield importCollectionComponent(self.store, component)

        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)

        txn = self.store.newTransaction()
        home = yield txn.calendarHomeWithUID("user01")
        collection = yield home.childWithName("calendar")

        # Verify properties have been set
        collectionProperties = collection.properties()
        for element, value in (
            (davxml.DisplayName, "I'm the organizer"),
            (customxml.CalendarColor, "#0000FFFF"),
        ):
            self.assertEquals(
                value,
                collectionProperties[PropertyName.fromElement(element)]
            )

        # Verify the organizer's child objects
        objects = yield collection.listObjectResources()
        self.assertEquals(len(objects), 1)

        # Verify the attendees' child objects
        home = yield txn.calendarHomeWithUID("user02")
        collection = yield home.childWithName("calendar")
        objects = yield collection.listObjectResources()
        self.assertEquals(len(objects), 1)

        home = yield txn.calendarHomeWithUID("user03")
        collection = yield home.childWithName("calendar")
        objects = yield collection.listObjectResources()
        self.assertEquals(len(objects), 1)

        home = yield txn.calendarHomeWithUID("mercury")
        collection = yield home.childWithName("calendar")
        objects = yield collection.listObjectResources()
        self.assertEquals(len(objects), 1)

        yield txn.commit()
开发者ID:eventable,项目名称:CalendarServer,代码行数:45,代码来源:test_importer.py

示例12: test_update_delete_old_nonextant

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_update_delete_old_nonextant(self):
        """
        Verify that old missing groups are deleted from group cache
        """

        oldGroupPurgeIntervalSeconds = config.AutomaticPurging.GroupPurgeIntervalSeconds
        store = self.storeUnderTest()

        for uid in (u"testgroup", u"emptygroup",):

            config.AutomaticPurging.GroupPurgeIntervalSeconds = oldGroupPurgeIntervalSeconds
            txn = store.newTransaction()
            group = yield txn.groupByUID(uid)
            yield txn.addDelegateGroup(delegator=u"sagen", delegateGroupID=group.groupID, readWrite=True)
            group = yield txn.groupByUID(uid, create=False)
            yield txn.commit()

            self.assertNotEqual(group, None)
            self.assertTrue(group.extant)

            # Remove the group, still cached
            yield self.directory.removeRecords([uid])
            txn = store.newTransaction()
            yield self.groupCacher.update(txn)
            group = yield txn.groupByUID(uid, create=False)
            yield txn.commit()
            yield JobItem.waitEmpty(store.newTransaction, reactor, 60)

            txn = store.newTransaction()
            group = yield txn.groupByUID(uid, create=False)
            yield txn.commit()
            self.assertNotEqual(group, None)
            self.assertFalse(group.extant)

            # delete the group
            config.AutomaticPurging.GroupPurgeIntervalSeconds = "0.0"

            txn = store.newTransaction()
            yield self.groupCacher.update(txn)
            group = yield txn.groupByUID(uid, create=False)
            yield txn.commit()
            self.assertEqual(group, None)
开发者ID:eventable,项目名称:CalendarServer,代码行数:44,代码来源:test_groups.py

示例13: test_iMIP_delivery

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_iMIP_delivery(self):

        data = """BEGIN:VCALENDAR
VERSION:2.0
METHOD:REQUEST
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ORGANIZER;CN="User 01":mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
END:VEVENT
END:VCALENDAR
"""

        results = []
        class FakeSender(object):
            def outbound(self, txn, fromAddr, toAddr, calendar):
                results.append((fromAddr, toAddr))
                return succeed(None)
        self.patch(IMIPInvitationWork, "mailSender", FakeSender())

        scheduler = iMIPProcessing.FakeSchedule(
            LocalCalendarUser("mailto:[email protected]", None),
            Component.fromString(data)
        )
        scheduler.txn = self.transactionUnderTest()
        recipients = (RemoteCalendarUser("mailto:[email protected]"),)
        responses = ScheduleResponseQueue("REQUEST", responsecode.OK)

        delivery = ScheduleViaIMip(scheduler, recipients, responses, False)
        yield delivery.generateSchedulingResponses()

        self.assertEqual(len(responses.responses), 1)
        self.assertEqual(str(responses.responses[0].reqstatus), iTIPRequestStatus.MESSAGE_SENT)

        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)

        self.assertEqual(len(results), 1)
        self.assertEqual(results[0], ("mailto:[email protected]", "mailto:[email protected]",))
开发者ID:eventable,项目名称:CalendarServer,代码行数:44,代码来源:test_delivery.py

示例14: test_processReplyMissingAttachment

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_processReplyMissingAttachment(self):

        msg = email.message_from_string(
            self.dataFile('reply_missing_attachment')
        )

        # stick the token in the database first
        txn = self.store.newTransaction()
        yield txn.imipCreateToken(
            "urn:x-uid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
            "mailto:[email protected].com",
            "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
            token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
        )
        yield txn.commit()

        result = (yield self.receiver.processReply(msg))
        self.assertEquals(result, MailReceiver.REPLY_FORWARDED_TO_ORGANIZER)

        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
开发者ID:eventable,项目名称:CalendarServer,代码行数:22,代码来源:test_inbound.py

示例15: test_orphans

# 需要导入模块: from twext.enterprise.jobs.jobitem import JobItem [as 别名]
# 或者: from twext.enterprise.jobs.jobitem.JobItem import waitEmpty [as 别名]
    def test_orphans(self):
        """
        Verify that orphaned Inbox items are removed
        """
        self.patch(config.InboxCleanup, "ItemLifetimeDays", -1)
        self.patch(config.InboxCleanup, "ItemLifeBeyondEventEndDays", -1)

        # create orphans by deleting events
        cal = yield self.calendarUnderTest(home="user01", name="calendar")
        for item in (yield cal.objectResourcesWithNames(["cal1.ics", "cal3.ics"])):
            yield item.purge()

        # do cleanup
        yield self.transactionUnderTest().enqueue(CleanupOneInboxWork, homeID=cal.ownerHome()._resourceID, notBefore=datetime.datetime.utcnow())
        yield self.commit()
        yield JobItem.waitEmpty(self.storeUnderTest().newTransaction, reactor, 60)

        # check that orphans are deleted
        inbox = yield self.calendarUnderTest(home="user01", name="inbox")
        items = yield inbox.objectResources()
        names = [item.name() for item in items]
        self.assertEqual(set(names), set(["cal2.ics"]))
开发者ID:eventable,项目名称:CalendarServer,代码行数:24,代码来源:test_inbox_cleanup.py


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