本文整理汇总了Python中Mailman.Utils类的典型用法代码示例。如果您正苦于以下问题:Python Utils类的具体用法?Python Utils怎么用?Python Utils使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Utils类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Python代码示例。
示例1: topic_details
def topic_details(mlist, doc, user, cpuser, userlang, varhelp):
# Find out which topic the user wants to get details of
reflist = varhelp.split("/")
name = None
topicname = _("<missing>")
if len(reflist) == 1:
topicname = urllib.unquote_plus(reflist[0])
for name, pattern, description, emptyflag in mlist.topics:
if name == topicname:
break
else:
name = None
if not name:
options_page(mlist, doc, user, cpuser, userlang, _("Requested topic is not valid: %(topicname)s"))
print doc.Format()
return
table = Table(border=3, width="100%")
table.AddRow([Center(Bold(_("Topic filter details")))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, bgcolor=mm_cfg.WEB_SUBHEADER_COLOR)
table.AddRow([Bold(Label(_("Name:"))), Utils.websafe(name)])
table.AddRow([Bold(Label(_("Pattern (as regexp):"))), "<pre>" + Utils.websafe(pattern) + "</pre>"])
table.AddRow([Bold(Label(_("Description:"))), Utils.websafe(description)])
# Make colors look nice
for row in range(1, 4):
table.AddCellInfo(row, 0, bgcolor=mm_cfg.WEB_ADMINITEM_COLOR)
options_page(mlist, doc, user, cpuser, userlang, table.Format())
print doc.Format()
开发者ID:KWMSources,项目名称:mailman_config,代码行数:30,代码来源:options.py
示例2: process
def process(mlist, msg, msgdata):
# Extract the sender's address and find them in the user database
sender = msgdata.get('original_sender', msg.get_sender())
try:
ack = mlist.getMemberOption(sender, mm_cfg.AcknowledgePosts)
if not ack:
return
except Errors.NotAMemberError:
return
# Okay, they want acknowledgement of their post. Give them their original
# subject. BAW: do we want to use the decoded header?
origsubj = msgdata.get('origsubj', msg.get('subject', _('(no subject)')))
# Get the user's preferred language
lang = msgdata.get('lang', mlist.getMemberLanguage(sender))
# Now get the acknowledgement template
realname = mlist.real_name
text = Utils.maketext(
'postack.txt',
{'subject' : Utils.oneline(origsubj, Utils.GetCharSet(lang)),
'listname' : realname,
'listinfo_url': mlist.GetScriptURL('listinfo', absolute=1),
'optionsurl' : mlist.GetOptionsURL(sender, absolute=1),
}, lang=lang, mlist=mlist, raw=1)
# Craft the outgoing message, with all headers and attributes
# necessary for general delivery. Then enqueue it to the outgoing
# queue.
subject = _('%(realname)s post acknowledgement')
usermsg = Message.UserNotification(sender, mlist.GetBouncesEmail(),
subject, text, lang)
usermsg.send(mlist)
开发者ID:EdLeafe,项目名称:mailman_config,代码行数:30,代码来源:Acknowledge.py
示例3: errcheck
def errcheck (self, action):
"""Performs all error checks. Returns None is all's good. Otherwise
returns a string with error message."""
if not can_create_lists(self.curr_user):
return 'You are not authorized to creates lists on this server'
if len(self.owner) <= 0:
return 'Cannot create list without a owner.'
if self.ln == '':
return 'You forgot to enter the list name'
if '@' in self.ln:
return 'List name must not include "@": %s' % self.safeln
if action == 'create' and Utils.list_exists(self.ln):
return 'List already exists: %s' % self.safe_ln
if mm_cfg.VIRTUAL_HOST_OVERVIEW and \
not mm_cfg.VIRTUAL_HOSTS.has_key(self.hn):
safehostname = Utils.websafe(self.hn)
return 'Unknown virtual host: %s' % safehostname
return None
开发者ID:skarra,项目名称:GNU-Mailman-SSO,代码行数:25,代码来源:ctl.py
示例4: __sendAdminBounceNotice
def __sendAdminBounceNotice(self, member, msg):
# BAW: This is a bit kludgey, but we're not providing as much
# information in the new admin bounce notices as we used to (some of
# it was of dubious value). However, we'll provide empty, strange, or
# meaningless strings for the unused %()s fields so that the language
# translators don't have to provide new templates.
siteowner = Utils.get_site_email(self.host_name)
text = Utils.maketext(
"bounce.txt",
{
"listname": self.real_name,
"addr": member,
"negative": "",
"did": _("disabled"),
"but": "",
"reenable": "",
"owneraddr": siteowner,
},
mlist=self,
)
subject = _("Bounce action notification")
umsg = Message.UserNotification(self.GetOwnerEmail(), siteowner, subject, lang=self.preferred_language)
# BAW: Be sure you set the type before trying to attach, or you'll get
# a MultipartConversionError.
umsg.set_type("multipart/mixed")
umsg.attach(MIMEText(text, _charset=Utils.GetCharSet(self.preferred_language)))
if isinstance(msg, StringType):
umsg.attach(MIMEText(msg))
else:
umsg.attach(MIMEMessage(msg))
umsg.send(self)
开发者ID:EmilyDirsh,项目名称:Paperboy,代码行数:31,代码来源:Bouncer.py
示例5: scrub_msg822
def scrub_msg822(self, part):
# submessage
submsg = part.get_payload(0)
omask = os.umask(002)
try:
url = save_attachment(self.mlist, part, self.dir)
finally:
os.umask(omask)
subject = submsg.get('subject', _('no subject'))
subject = Utils.oneline(subject, self.lcset)
date = submsg.get('date', _('no date'))
who = submsg.get('from', _('unknown sender'))
who = Utils.oneline(who, self.lcset)
size = len(str(submsg))
self.msgtexts.append(unicode(_("""\
An embedded message was scrubbed...
From: %(who)s
Subject: %(subject)s
Date: %(date)s
Size: %(size)s
URL: %(url)s
"""), self.lcset))
# Replace this part because subparts should not be walk()-ed.
del part['content-type']
part.set_payload('blah blah', 'us-ascii')
开发者ID:atsuoishimoto,项目名称:mailman-2.1-ja,代码行数:25,代码来源:Scrubber.py
示例6: _cleanup
def _cleanup(self):
"""Clean up upon exit from the main processing loop.
Called when the Runner's main loop is stopped, this should perform
any necessary resource deallocation. Its return value is irrelevant.
"""
Utils.reap(self._kids)
开发者ID:kaushikmit,项目名称:mailman,代码行数:7,代码来源:Runner.py
示例7: loginpage
def loginpage(mlist, scriptname, msg='', frontpage=None):
url = mlist.GetScriptURL(scriptname)
if frontpage:
actionurl = url
else:
actionurl = Utils.GetRequestURI(url)
if msg:
msg = FontAttr(msg, color='#ff0000', size='+1').Format()
# give an HTTP 401 for authentication failure
print 'Status: 401 Unauthorized'
if scriptname == 'admindb':
who = _('Moderator')
else:
who = _('Administrator')
# Language stuff
charset = Utils.GetCharSet(mlist.preferred_language)
print 'Content-type: text/html; charset=' + charset + '\n\n'
print Utils.maketext(
'admlogin.html',
{'listname': mlist.real_name,
'path' : actionurl,
'message' : msg,
'who' : who,
}, mlist=mlist)
print mlist.GetMailmanFooter()
开发者ID:EdLeafe,项目名称:mailman_config,代码行数:25,代码来源:Auth.py
示例8: send_response
def send_response(self):
# Helper
def indent(lines):
return [' ' + line for line in lines]
# Quick exit for some commands which don't need a response
if not self.respond:
return
resp = [Utils.wrap(_("""\
The results of your email command are provided below.
Attached is your original message.
"""))]
if self.results:
resp.append(_('- Results:'))
resp.extend(indent(self.results))
# Ignore empty lines
unprocessed = [line for line in self.commands[self.lineno:]
if line and line.strip()]
if unprocessed:
resp.append(_('\n- Unprocessed:'))
resp.extend(indent(unprocessed))
if not unprocessed and not self.results:
# The user sent an empty message; return a helpful one.
resp.append(Utils.wrap(_("""\
No commands were found in this message.
To obtain instructions, send a message containing just the word "help".
""")))
if self.ignored:
resp.append(_('\n- Ignored:'))
resp.extend(indent(self.ignored))
resp.append(_('\n- Done.\n\n'))
# Encode any unicode strings into the list charset, so we don't try to
# join unicode strings and invalid ASCII.
charset = Utils.GetCharSet(self.msgdata['lang'])
encoded_resp = []
for item in resp:
if isinstance(item, UnicodeType):
item = item.encode(charset, 'replace')
encoded_resp.append(item)
results = MIMEText(NL.join(encoded_resp), _charset=charset)
# Safety valve for mail loops with misconfigured email 'bots. We
# don't respond to commands sent with "Precedence: bulk|junk|list"
# unless they explicitly "X-Ack: yes", but not all mail 'bots are
# correctly configured, so we max out the number of responses we'll
# give to an address in a single day.
#
# BAW: We wait until now to make this decision since our sender may
# not be self.msg.get_sender(), but I'm not sure this is right.
recip = self.returnaddr or self.msg.get_sender()
if not self.mlist.autorespondToSender(recip, self.msgdata['lang']):
return
msg = Message.UserNotification(
recip,
self.mlist.GetBouncesEmail(),
_('The results of your email commands'),
lang=self.msgdata['lang'])
msg.set_type('multipart/mixed')
msg.attach(results)
orig = MIMEMessage(self.msg)
msg.attach(orig)
msg.send(self.mlist)
开发者ID:jdk2588,项目名称:systers-gsoc10-membership,代码行数:60,代码来源:CommandRunner.py
示例9: do_command
def do_command(self, cmd, args=None):
if args is None:
args = ()
# Try to import a command handler module for this command
modname = 'Mailman.Commands.cmd_' + cmd
try:
__import__(modname)
handler = sys.modules[modname]
# ValueError can be raised if cmd has dots in it.
except (ImportError, ValueError):
# If we're on line zero, it was the Subject: header that didn't
# contain a command. It's possible there's a Re: prefix (or
# localized version thereof) on the Subject: line that's messing
# things up. Pop the prefix off and try again... once.
#
# If that still didn't work it isn't enough to stop processing.
# BAW: should we include a message that the Subject: was ignored?
if not self.subjcmdretried and args:
self.subjcmdretried += 1
cmd = args.pop(0)
return self.do_command(cmd, args)
return self.lineno <> 0
# with Dlists, we don't allow email subscription
if DlistUtils.enabled(self.mlist) and (cmd == 'subscribe' or cmd == 'join'):
realname = self.mlist.real_name
domain = Utils.get_domain()
self.results.append(Utils.wrap(_("""\
This list cannot be subscribed to via email.
Please use the website at http://%(domain)s/mailman/listinfo/%(realname)s .
""")))
return self.lineno <> 0 # superstitious behavior as they do it above
return handler.process(self, args)
开发者ID:jdk2588,项目名称:systers-gsoc10-membership,代码行数:33,代码来源:CommandRunner.py
示例10: create
def create(self, email):
if self.exists:
raise ListAlreadyExists
langs = [mm_cfg.DEFAULT_SERVER_LANGUAGE]
pw = Utils.MakeRandomPassword()
pw_hashed = Utils.sha_new(pw).hexdigest()
urlhost = mm_cfg.DEFAULT_URL_HOST
host_name = mm_cfg.DEFAULT_EMAIL_HOST
web_page_url = mm_cfg.DEFAULT_URL_PATTERN % urlhost
# TODO: Add some atomicity. We should roll back changes using
# a try/else if something (like MTA alias update) fails
# before the function terminates.
try:
oldmask = os.umask(002)
self.mlist.Create(self.name, email, pw_hashed, langs=langs,
emailhost=host_name, urlhost=urlhost)
self.mlist.preferred_language = langs[0]
# Reply-To set to list address
self.mlist.reply_goes_to_list = 2
self.mlist.reply_to_address = "%[email protected]%s" % (self.list, self.domain)
# Allow messages from [email protected]
self.mlist.acceptable_aliases = "%[email protected]%s\n" % (self.list, self.domain)
self.mlist.subject_prefix = "[%s] " % (self.list)
self.mlist.msg_footer = ""
self.mlist.subscribe_policy = 2 # Confirm and approve
self.mlist.max_message_size = 20480 # 20M
self.mlist.Save()
finally:
os.umask(oldmask)
self.mlist.Unlock()
if mm_cfg.MTA:
modname = 'Mailman.MTA.' + mm_cfg.MTA
__import__(modname)
sys.modules[modname].create(self.mlist)
siteowner = Utils.get_site_email(self.mlist.host_name, 'owner')
text = Utils.maketext(
'newlist.txt',
{'listname' : self.name,
'password' : pw,
'admin_url' : self.mlist.GetScriptURL('admin', absolute=1),
'listinfo_url': self.mlist.GetScriptURL('listinfo', absolute=1),
'requestaddr' : self.mlist.GetRequestEmail(),
'siteowner' : siteowner,
}, mlist=self.mlist)
msg = Message.UserNotification(email, siteowner, 'Your new mailing list: %s' % self.name,
text, self.mlist.preferred_language)
msg.send(self.mlist)
开发者ID:truls,项目名称:dikumail.dk,代码行数:59,代码来源:util.py
示例11: do_reject
def do_reject(mlist):
listowner = mlist.GetOwnerEmail()
if mlist.nonmember_rejection_notice:
raise Errors.RejectMessage, \
Utils.wrap(_(mlist.nonmember_rejection_notice))
else:
raise Errors.RejectMessage, Utils.wrap(_("""\
You are not allowed to post to this mailing list, and your message has been
automatically rejected. If you think that your messages are being rejected in
error, contact the mailing list owner at %(listowner)s."""))
开发者ID:EdLeafe,项目名称:mailman_config,代码行数:10,代码来源:Moderate.py
示例12: do_reject
def do_reject(mlist):
listowner = mlist.GetOwnerEmail()
if mlist.nonmember_rejection_notice:
raise Errors.RejectMessage, \
Utils.wrap(_(mlist.nonmember_rejection_notice))
else:
raise Errors.RejectMessage, Utils.wrap(_("""\
Your message has been rejected, probably because you are not subscribed to the
mailing list and the list's policy is to prohibit non-members from posting to
it. If you think that your messages are being rejected in error, contact the
mailing list owner at %(listowner)s."""))
开发者ID:jurov,项目名称:gnu-mailman,代码行数:11,代码来源:Moderate.py
示例13: show_pending_unsubs
def show_pending_unsubs(mlist, form):
# Add the pending unsubscription request section
lang = mlist.preferred_language
pendingunsubs = mlist.GetUnsubscriptionIds()
if not pendingunsubs:
return 0
table = Table(border=2)
table.AddRow([Center(Bold(_('User address/name'))),
Center(Bold(_('Your decision'))),
Center(Bold(_('Reason for refusal')))
])
# Alphabetical order by email address
byaddrs = {}
for id in pendingunsubs:
addr = mlist.GetRecord(id)
byaddrs.setdefault(addr, []).append(id)
addrs = byaddrs.keys()
addrs.sort()
num = 0
for addr, ids in byaddrs.items():
# Eliminate duplicates
for id in ids[1:]:
mlist.HandleRequest(id, mm_cfg.DISCARD)
id = ids[0]
addr = mlist.GetRecord(id)
try:
fullname = Utils.uncanonstr(mlist.getMemberName(addr), lang)
except Errors.NotAMemberError:
# They must have been unsubscribed elsewhere, so we can just
# discard this record.
mlist.HandleRequest(id, mm_cfg.DISCARD)
continue
num += 1
# While the address may be a unicode, it must be ascii
paddr = addr.encode('us-ascii', 'replace')
table.AddRow(['%s<br><em>%s</em>' % (paddr, Utils.websafe(fullname)),
RadioButtonArray(id, (_('Defer'),
_('Approve'),
_('Reject'),
_('Discard')),
values=(mm_cfg.DEFER,
mm_cfg.UNSUBSCRIBE,
mm_cfg.REJECT,
mm_cfg.DISCARD),
checked=0),
TextBox('comment-%d' % id, size=45)
])
if num > 0:
form.AddItem('<hr>')
form.AddItem(Center(Header(2, _('Unsubscription Requests'))))
form.AddItem(table)
return num
开发者ID:atsuoishimoto,项目名称:mailman-2.1-ja,代码行数:52,代码来源:admindb.py
示例14: openidreg_overview
def openidreg_overview(lang, msg=''):
# Present the general listinfo overview
hostname = Utils.get_domain()
# Set up the document and assign it the correct language. The only one we
# know about at the moment is the server's default.
doc = Document()
# doc.set_language(lang)
doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
legend = _(" OpenID Registeration for Systers Mailing Lists")
doc.SetTitle(legend)
table = Table(border=0, width="100%")
table.AddRow([Center(Header(2, legend))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2,
bgcolor=mm_cfg.WEB_HEADER_COLOR)
# Skip any mailing lists that isn't advertised.
if msg:
greeting = FontAttr(msg, color="ff5060", size="+1")
else:
greeting = FontAttr(_('Welcome!'), size='+2')
welcome = [greeting]
mailmanlink = Link(mm_cfg.MAILMAN_URL, _('Mailman')).Format()
# set up some local variables
adj = msg and _('right') or ''
siteowner = Utils.get_site_email()
welcome.extend(
(_(''' This is the Systers OpenID registeration form . To enable your systers account fill in the following entries.
<p>or Go back to the listinfo page if already using it '''),
Link(Utils.ScriptURL('listinfo'),
_('the mailing lists overview page')),
_(''' <p>If you are having trouble using the lists, please contact '''),
Link('mailto:' + siteowner, siteowner),
'.<p>',
FormatOpenIDLogin(),
'<p>'))
table.AddRow([apply(Container, welcome)])
table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2)
doc.AddItem(table)
doc.AddItem('<hr>')
doc.AddItem(MailmanLogo())
print doc.Format()
开发者ID:jdk2588,项目名称:systers-gsoc10-membership,代码行数:52,代码来源:openidreg.py
示例15: __init__
def __init__(self, whichq, slice=None, numslices=1, recover=False):
self._whichq = whichq
# Create the directory if it doesn't yet exist.
Utils.makedirs(self._whichq, 0770)
# Fast track for no slices
self._lower = None
self._upper = None
# BAW: test performance and end-cases of this algorithm
if numslices <> 1:
self._lower = ((shamax + 1) * slice) / numslices
self._upper = (((shamax + 1) * (slice + 1)) / numslices) - 1
if recover:
self.recover_backup_files()
开发者ID:kaushikmit,项目名称:mailman,代码行数:13,代码来源:Switchboard.py
示例16: SendSubscribeAck
def SendSubscribeAck(self, name, password, digest, text=""):
pluser = self.getMemberLanguage(name)
# Need to set this here to get the proper l10n of the Subject:
i18n.set_language(pluser)
if self.welcome_msg:
welcome = Utils.wrap(self.welcome_msg) + "\n"
else:
welcome = ""
if self.umbrella_list:
addr = self.GetMemberAdminEmail(name)
umbrella = Utils.wrap(
_(
"""\
Note: Since this is a list of mailing lists, administrative
notices like the password reminder will be sent to
your membership administrative address, %(addr)s."""
)
)
else:
umbrella = ""
# get the text from the template
text += Utils.maketext(
"subscribeack.txt",
{
"real_name": self.real_name,
"host_name": self.host_name,
"welcome": welcome,
"umbrella": umbrella,
"emailaddr": self.GetListEmail(),
"listinfo_url": self.GetScriptURL("listinfo", absolute=True),
"optionsurl": self.GetOptionsURL(name, absolute=True),
"password": password,
"user": self.getMemberCPAddress(name),
},
lang=pluser,
mlist=self,
)
if digest:
digmode = _(" (Digest mode)")
else:
digmode = ""
realname = self.real_name
msg = Message.UserNotification(
self.GetMemberAdminEmail(name),
self.GetRequestEmail(),
_('Welcome to the "%(realname)s" mailing list%(digmode)s'),
text,
pluser,
)
msg["X-No-Archive"] = "yes"
msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
开发者ID:jurov,项目名称:gnu-mailman,代码行数:51,代码来源:Deliverer.py
示例17: show_pending_subs
def show_pending_subs(mlist, form):
# Add the subscription request section
pendingsubs = mlist.GetSubscriptionIds()
if not pendingsubs:
return 0
form.AddItem('<hr>')
form.AddItem(Center(Header(2, _('Subscription Requests'))))
table = Table(border=2)
table.AddRow([Center(Bold(_('Address/name'))),
Center(Bold(_('Your decision'))),
Center(Bold(_('Reason for refusal')))
])
# Alphabetical order by email address
byaddrs = {}
for id in pendingsubs:
addr = mlist.GetRecord(id)[1]
byaddrs.setdefault(addr, []).append(id)
addrs = byaddrs.items()
addrs.sort()
num = 0
for addr, ids in addrs:
# Eliminate duplicates
for id in ids[1:]:
mlist.HandleRequest(id, mm_cfg.DISCARD)
id = ids[0]
time, addr, fullname, passwd, digest, lang = mlist.GetRecord(id)
fullname = Utils.uncanonstr(fullname, mlist.preferred_language)
radio = RadioButtonArray(id, (_('Defer'),
_('Approve'),
_('Reject'),
_('Discard')),
values=(mm_cfg.DEFER,
mm_cfg.SUBSCRIBE,
mm_cfg.REJECT,
mm_cfg.DISCARD),
checked=0).Format()
if addr not in mlist.ban_list:
radio += ('<br>' + '<label>' +
CheckBox('ban-%d' % id, 1).Format() +
' ' + _('Permanently ban from this list') +
'</label>')
# While the address may be a unicode, it must be ascii
paddr = addr.encode('us-ascii', 'replace')
table.AddRow(['%s<br><em>%s</em>' % (paddr, Utils.websafe(fullname)),
radio,
TextBox('comment-%d' % id, size=40)
])
num += 1
if num > 0:
form.AddItem(table)
return num
开发者ID:jurov,项目名称:gnu-mailman,代码行数:51,代码来源:admindb.py
示例18: lists_of_member
def lists_of_member(safeuser):
hostname = mm_cfg.DEFAULT_URL_HOST
onlists = []
for listname in Utils.list_names():
# The current list will always handle things in the mainline
if listname == Utils.list_names():
continue
glist = MailList.MailList(listname, lock=0)
if glist.host_name <> hostname:
continue
if not glist.isMember(safeuser):
continue
onlists.append(glist)
return onlists
开发者ID:jdk2588,项目名称:systers-gsoc10-membership,代码行数:14,代码来源:oiduserpage.py
示例19: __init__
def __init__(self, text=''):
from Mailman.pythonlib.StringIO import StringIO
# NOTE: text if supplied must begin with valid rfc822 headers. It can
# also begin with the body of the message but in that case you better
# make sure that the first line does NOT contain a colon!
Message.__init__(self, StringIO(text))
# RFC 2822 requires a Date: header, and while most MTAs add one if
# it's missing, qmail does not.
if not self.get('date'):
self['Date'] = Utils.formatdate(localtime=1)
# RFC 2822 recommends a Message-ID: header, and while most MTAs add
# one if it's missing, qmail does not.
if not self.get('message-id'):
self['Message-ID'] = Utils.make_msgid(idstring='Mailman')
开发者ID:OS2World,项目名称:APP-SERVER-MailMan,代码行数:14,代码来源:Message.py
示例20: finish
def finish(self, filebase, preserve=False):
bakfile = os.path.join(self._whichq, filebase + '.bak')
try:
if preserve:
psvfile = os.path.join(config.SHUNTQUEUE_DIR,
filebase + '.psv')
# Create the directory if it doesn't yet exist.
Utils.makedirs(config.SHUNTQUEUE_DIR, 0770)
os.rename(bakfile, psvfile)
else:
os.unlink(bakfile)
except EnvironmentError, e:
elog.exception('Failed to unlink/preserve backup file: %s',
bakfile)
开发者ID:kaushikmit,项目名称:mailman,代码行数:14,代码来源:Switchboard.py
注:本文中的Mailman.Utils类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论