本文整理汇总了Golang中euphoria/io/scope.New函数的典型用法代码示例。如果您正苦于以下问题:Golang New函数的具体用法?Golang New怎么用?Golang New使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了New函数的17个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: TestTemplateEmailer
func TestTemplateEmailer(t *testing.T) {
Convey("TemplateEmailer", t, func() {
tmpl, err := template.New("test").Parse(`
{{define "test.html"}}html part{{end}}
{{define "test.txt"}}text part{{end}}
{{define "test.hdr"}}Subject: test{{end}}`)
So(err, ShouldBeNil)
e := &TemplateEmailer{
Deliverer: &TestDeliverer{},
Templater: &templates.Templater{Templates: map[string]*template.Template{"test": tmpl}},
}
Convey("Send test email", func() {
c := e.Deliverer.(MockDeliverer).Inbox("[email protected]")
msgID, err := e.Send(scope.New(), "[email protected]", "test", nil)
So(err, ShouldBeNil)
email := parseEmail(<-c)
So(email.Header.Get("Message-ID"), ShouldEqual, msgID)
So(email.Header.Get("Subject"), ShouldEqual, "test")
So(string(email.Text), ShouldEqual, "text part")
So(string(email.HTML), ShouldEqual, "html part")
})
})
}
开发者ID:rmasoni,项目名称:heim,代码行数:26,代码来源:emailer_test.go
示例2: main
func main() {
go func() {
// goto: http://localhost:6060/debug/pprof/ for goroutine info!
fmt.Println(http.ListenAndServe("localhost:6060", nil))
}()
bcfg := babel.BotConfig{
Nick: "babelbot",
RoomName: "test",
Cmds: []plugin.CmdPluginDialer{
plugin.CmdPluginDialer{
Cmd: "python",
Args: []string{"log_everything.py"},
},
},
}
ws := &connection.WSConnectionDialer{
UrlFormat: connection.EUPHORIA_URL_FORMAT,
}
ctx := scope.New()
proto.SetLogger(ctx, logrus.StandardLogger())
err := bcfg.Start(ctx, ws)
if err != nil {
proto.GetLogger(ctx).Errorf("bcfg.Start failure in main(): %s", err)
}
}
开发者ID:cpalone,项目名称:heimbabelbot,代码行数:28,代码来源:singlebot.go
示例3: TestRunHandler
func TestRunHandler(t *testing.T) {
ctrl := &Controller{}
ctx := scope.New()
Convey("Successfully runs", t, func() {
term := &testTerm{}
runHandler(ctx, testHandler{}, cmdConsole(ctrl, "test", term), []string{"test"})
So(term.String(), ShouldEqual, "ok\r\n")
})
Convey("Usage error", t, func() {
Convey("Handler serves usage", func() {
term := &testTerm{}
runHandler(ctx, testHandlerWithUsage{}, cmdConsole(ctrl, "test", term), nil)
So(term.String(), ShouldEqual,
"error: invalid number of arguments: 0\r\nusage\r\n\r\nOPTIONS:\r\n")
})
Convey("Handler doesn't serve usage", func() {
term := &testTerm{}
runHandler(ctx, testHandler{}, cmdConsole(ctrl, "test", term), nil)
So(term.String(), ShouldEqual, "error: invalid number of arguments: 0\r\n")
})
})
}
开发者ID:logan,项目名称:heim,代码行数:25,代码来源:handler_test.go
示例4: TestRoomPresence
func TestRoomPresence(t *testing.T) {
userA := newSession("A", "A1", "ip1")
userA2 := newSession("A", "A2", "ip2")
userB := newSession("B", "B1", "ip3")
ctx := scope.New()
kms := security.LocalKMS()
kms.SetMasterKey(make([]byte, security.AES256.KeySize()))
roomp, err := NewRoom(ctx, kms, false, "test", "testver")
if err != nil {
t.Fatal(err)
}
room := roomp.(*memRoom)
client := &proto.Client{Agent: &proto.Agent{}}
client.FromRequest(ctx, &http.Request{})
Convey("First join", t, func() {
_, err := room.Join(ctx, userA)
So(err, ShouldBeNil)
So(room.identities, ShouldResemble,
map[proto.UserID]proto.Identity{"A": userA.Identity()})
So(room.live, ShouldResemble,
map[proto.UserID][]proto.Session{"A": []proto.Session{userA}})
})
Convey("Second join", t, func() {
_, err := room.Join(ctx, userB)
So(err, ShouldBeNil)
So(room.identities["B"], ShouldResemble, userB.Identity())
So(room.live["B"], ShouldResemble, []proto.Session{userB})
})
Convey("Duplicate join", t, func() {
_, err := room.Join(ctx, userA2)
So(err, ShouldBeNil)
So(room.live["A"], ShouldResemble, []proto.Session{userA, userA2})
})
Convey("Deduplicate part", t, func() {
So(room.Part(ctx, userA), ShouldBeNil)
So(room.identities["A"], ShouldResemble, userA.Identity())
So(room.live["A"], ShouldResemble, []proto.Session{userA2})
})
Convey("More parts", t, func() {
So(room.Part(ctx, userA2), ShouldBeNil)
So(room.identities["A"], ShouldBeNil)
So(room.live["A"], ShouldBeNil)
So(room.Part(ctx, userB), ShouldBeNil)
So(room.identities["B"], ShouldBeNil)
So(room.live["B"], ShouldBeNil)
})
}
开发者ID:logan,项目名称:heim,代码行数:56,代码来源:room_test.go
示例5: Join
func (s *EtcdServer) Join(root, id, era string) cluster.Cluster {
desc := &cluster.PeerDesc{
ID: id,
Era: era,
}
c, err := etcd.EtcdCluster(scope.New(), root, s.addr, desc)
if err != nil {
panic(fmt.Sprintf("error joining cluster: %s", err))
}
return c
}
开发者ID:logan,项目名称:heim,代码行数:11,代码来源:testetcd.go
示例6: TestBackend
func TestBackend(t *testing.T) {
etcd, err := clustertest.StartEtcd()
if err != nil {
t.Fatal(err)
}
if etcd == nil {
t.Fatal("etcd not available in PATH, can't test backend")
}
defer etcd.Shutdown()
dsn := *dsn
if env := os.Getenv("DSN"); env != "" {
// for running in CI container
dsn = env
}
db, err := sql.Open("postgres", dsn)
if err != nil {
t.Fatalf("sql.Open: %s", err)
}
// Drop all tables.
for _, item := range schema {
if _, err := db.Exec("DROP TABLE IF EXISTS " + item.Name + " CASCADE"); err != nil {
t.Fatalf("failed to drop table %s: %s", item.Name, err)
}
}
if _, err := db.Exec("DROP TABLE IF EXISTS gorp_migrations"); err != nil {
t.Fatal(err)
}
// Recreate all tables.
src := migrate.FileMigrationSource{"migrations"}
if _, err := migrate.Exec(db, "postgres", src, migrate.Up); err != nil {
t.Fatal(err)
}
// Start up backend.
c := etcd.Join("/test", "testcase", "era")
desc := &cluster.PeerDesc{
ID: "testcase",
Era: "era",
Version: "testver",
}
b, err := NewBackend(scope.New(), dsn, c, desc)
if err != nil {
t.Fatal(err)
}
defer b.Close()
// Run test suite.
backend.IntegrationTest(t, func() proto.Backend { return nonClosingBackend{b} })
}
开发者ID:robot0x,项目名称:heim,代码行数:53,代码来源:integration_test.go
示例7: main
func main() {
logger := &log.Logger{
Handler: cli.New(os.Stdout),
Level: log.DebugLevel,
}
ctx := scope.New()
ctx.Set("logger", logger)
b := bot.NewBot(ctx, []proto.Handler{&handlers.PingHandler{}, &handlers.PongHandler{}}, connection.NewWSDialer(ctx.Fork(), fmt.Sprintf(url, "test")))
if err := b.Run(); err != nil {
logger.Fatalf("Bot.Run: Fatal error (%s)", err)
}
}
开发者ID:cpalone,项目名称:maimai.v3,代码行数:12,代码来源:maimai.go
示例8: handleRoomStatic
func (s *Server) handleRoomStatic(w http.ResponseWriter, r *http.Request) {
if !s.allowRoomCreation {
roomName := mux.Vars(r)["room"]
_, err := s.b.GetRoom(scope.New(), roomName)
if err != nil {
if err == proto.ErrRoomNotFound {
http.Error(w, "404 page not found", http.StatusNotFound)
return
}
}
}
s.serveGzippedFile(w, r, "index.html", false)
}
开发者ID:chauthai,项目名称:heim,代码行数:13,代码来源:handlers.go
示例9: TestMemLogLatest
func TestMemLogLatest(t *testing.T) {
ctx := scope.New()
msgs := []proto.Message{
{ID: 1, Content: "A"},
{ID: 2, Content: "B"},
{ID: 15, Content: "C"},
{ID: 19, Content: "D"},
{ID: 20, Content: "E"},
}
Convey("Partial response", t, func() {
log := newMemLog()
slice, err := log.Latest(ctx, 5, 0)
So(err, ShouldBeNil)
So(slice, ShouldNotBeNil)
So(len(slice), ShouldEqual, 0)
log.post(&msgs[0])
log.post(&msgs[1])
log.post(&msgs[2])
slice, err = log.Latest(ctx, 5, 0)
So(err, ShouldBeNil)
So(slice, ShouldResemble, msgs[:3])
})
Convey("Full response", t, func() {
log := newMemLog()
for _, msg := range msgs {
posted := msg
log.post(&posted)
}
slice, err := log.Latest(ctx, 3, 0)
So(err, ShouldBeNil)
So(slice, ShouldResemble, msgs[2:])
})
Convey("Before", t, func() {
log := newMemLog()
for _, msg := range msgs {
posted := msg
log.post(&posted)
}
slice, err := log.Latest(ctx, 3, 20)
So(err, ShouldBeNil)
So(slice, ShouldResemble, msgs[1:4])
})
}
开发者ID:logan,项目名称:heim,代码行数:49,代码来源:log_test.go
示例10: Run
func Run(args []string) {
out = tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
if len(args) == 0 {
generalHelp()
return
}
exe := filepath.Base(os.Args[0])
cmd, ok := subcommands[args[0]]
if !ok {
fmt.Fprintf(os.Stderr, "%s: invalid command: %s\n", exe, args[0])
fmt.Fprintf(os.Stderr, "Run '%s help' for usage.\n", exe)
os.Exit(2)
}
flags := cmd.flags()
if err := flags.Parse(args[1:]); err != nil {
fmt.Fprintf(os.Stderr, "%s %s: %s\n", exe, args[0], err)
os.Exit(2)
}
ctx := logging.LoggingContext(scope.New(), os.Stdout, fmt.Sprintf("[%s] ", args[0]))
logging.Logger(ctx).Printf("starting up")
if err := cmd.run(ctx, flags.Args()); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
timeout := time.After(10 * time.Second)
completed := make(chan struct{})
go func() {
ctx.WaitGroup().Wait()
close(completed)
}()
fmt.Println("waiting for graceful shutdown...")
select {
case <-timeout:
fmt.Println("timed out")
os.Exit(1)
case <-completed:
fmt.Println("ok")
os.Exit(0)
}
}
开发者ID:logan,项目名称:heim,代码行数:46,代码来源:subcommands.go
示例11: TestRunCommand
func TestRunCommand(t *testing.T) {
ctx := scope.New()
Convey("Unregistered command prints error", t, func() {
term := &testTerm{}
runCommand(ctx, nil, "asdf", term, nil)
So(term.String(), ShouldEqual, "invalid command: asdf\r\n")
})
Convey("Registered command is invoked", t, func() {
save := handlers
defer func() { handlers = save }()
handlers = map[string]handler{}
register("test", testHandler{})
term := &testTerm{}
runCommand(ctx, &Controller{}, "test", term, []string{"arg"})
So(term.String(), ShouldEqual, "ok\r\n")
})
}
开发者ID:logan,项目名称:heim,代码行数:19,代码来源:handler_test.go
示例12: NewBot
// NewBot creates a bot with the given configuration. It will create a bolt DB
// if it does not already exist at the specified location.
func NewBot(cfg BotConfig) (*Bot, error) {
db, err := bolt.Open(cfg.DbPath, 0666, nil)
if err != nil {
return nil, err
}
ctx := scope.New()
logger := logrus.New()
logger.Level = logrus.DebugLevel
cmd := make(chan interface{})
rooms := make(map[string]*Room)
return &Bot{
Rooms: rooms,
BotName: cfg.Name,
ctx: ctx,
DB: db,
Logger: logger,
cmd: cmd,
}, nil
}
开发者ID:Trinigo,项目名称:gobot,代码行数:21,代码来源:base.go
示例13: AddRoom
// AddRoom adds a new Room to the bot with the given configuration. The context
// for this room is distinct from the Bot's context.
func (b *Bot) AddRoom(cfg RoomConfig) {
b.Logger.Debugf("%s", len(cfg.AddlHandlers))
ctx := scope.New()
logger := logrus.New()
logger.Level = logrus.DebugLevel
room := Room{
RoomName: cfg.RoomName,
password: cfg.Password,
Ctx: ctx,
outbound: make(chan *proto.Packet, 5),
inbound: make(chan *proto.Packet, 5),
BotName: b.BotName,
msgID: 0,
Logger: logger,
Handlers: cfg.AddlHandlers,
DB: b.DB,
conn: cfg.Conn,
}
b.Rooms[room.RoomName] = &room
}
开发者ID:Trinigo,项目名称:gobot,代码行数:22,代码来源:base.go
示例14: handleRoomStatic
func (s *Server) handleRoomStatic(w http.ResponseWriter, r *http.Request) {
ctx := scope.New()
// Before creating an agent cookie, make this visitor look like a human.
if err := r.ParseForm(); err != nil {
s.serveErrorPage("bad request", http.StatusBadRequest, w, r)
return
}
r.Form.Set("h", "1")
// Tag the agent.
client, cookie, _, err := getClient(ctx, s, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if cookie != nil {
w.Header().Add("Set-Cookie", cookie.String())
}
// Parameterize and serve the page.
prefix := mux.Vars(r)["prefix"]
roomName := mux.Vars(r)["room"]
room, err := s.resolveRoom(ctx, prefix, roomName, client)
if err != nil {
if err == proto.ErrRoomNotFound {
if !s.allowRoomCreation || prefix != "" {
s.serveErrorPage("room not found", http.StatusNotFound, w, r)
return
}
} else {
s.serveErrorPage(err.Error(), http.StatusInternalServerError, w, r)
return
}
}
params := map[string]interface{}{"RoomTitle": strings.TrimPrefix(room.Title(), "&")}
s.servePage("room.html", params, w, r)
}
开发者ID:logan,项目名称:heim,代码行数:38,代码来源:handlers.go
示例15: TestRoomBroadcast
func TestRoomBroadcast(t *testing.T) {
userA := newSession("A", "A1", "ip1")
userB := newSession("B", "B1", "ip2")
userC := newSession("C", "C1", "ip3")
ctx := scope.New()
kms := security.LocalKMS()
kms.SetMasterKey(make([]byte, security.AES256.KeySize()))
roomp, err := NewRoom(ctx, kms, false, "test", "testver")
if err != nil {
t.Fatal(err)
}
room := roomp.(*memRoom)
client := &proto.Client{Agent: &proto.Agent{}}
client.FromRequest(ctx, &http.Request{})
Convey("Setup", t, func() {
_, err := room.Join(ctx, userA)
So(err, ShouldBeNil)
_, err = room.Join(ctx, userB)
So(err, ShouldBeNil)
_, err = room.Join(ctx, userC)
So(err, ShouldBeNil)
})
Convey("Multiple exclude", t, func() {
So(room.broadcast(ctx, proto.SendType, proto.Message{Content: "1"}, userA, userB),
ShouldBeNil)
So(userA.history, ShouldResemble,
[]message{
{
cmdType: proto.JoinEventType,
payload: &proto.PresenceEvent{
SessionID: "B",
IdentityView: proto.IdentityView{ID: "B"},
},
},
{
cmdType: proto.JoinEventType,
payload: &proto.PresenceEvent{
SessionID: "C",
IdentityView: proto.IdentityView{ID: "C"},
},
},
})
So(userB.history, ShouldResemble,
[]message{
{
cmdType: proto.JoinEventType,
payload: &proto.PresenceEvent{
SessionID: "C",
IdentityView: proto.IdentityView{ID: "C"},
},
},
})
So(userC.history, ShouldResemble,
[]message{{cmdType: proto.SendEventType, payload: proto.Message{Content: "1"}}})
})
Convey("No exclude", t, func() {
So(room.broadcast(ctx, proto.SendType, proto.Message{Content: "2"}), ShouldBeNil)
So(userA.history, ShouldResemble,
[]message{
{
cmdType: proto.JoinEventType,
payload: &proto.PresenceEvent{
SessionID: "B",
IdentityView: proto.IdentityView{ID: "B"},
},
},
{
cmdType: proto.JoinEventType,
payload: &proto.PresenceEvent{
SessionID: "C",
IdentityView: proto.IdentityView{ID: "C"},
},
},
{
cmdType: proto.SendEventType,
payload: proto.Message{Content: "2"},
},
})
So(userB.history, ShouldResemble,
[]message{
{
cmdType: proto.JoinEventType,
payload: &proto.PresenceEvent{
SessionID: "C",
IdentityView: proto.IdentityView{ID: "C"},
},
},
{cmdType: proto.SendEventType, payload: proto.Message{Content: "2"}},
})
So(userC.history, ShouldResemble,
[]message{
{cmdType: proto.SendEventType, payload: proto.Message{Content: "1"}},
{cmdType: proto.SendEventType, payload: proto.Message{Content: "2"}},
})
//.........这里部分代码省略.........
开发者ID:logan,项目名称:heim,代码行数:101,代码来源:room_test.go
示例16: TestDeleteMessage
func TestDeleteMessage(t *testing.T) {
ctx := scope.New()
kms := security.LocalKMS()
kms.SetMasterKey(make([]byte, security.AES256.KeySize()))
session := mock.TestSession("test", "T1", "ip1")
sendMessage := func(room proto.Room) (proto.Message, error) {
msg := proto.Message{
Sender: proto.SessionView{
SessionID: "test",
IdentityView: proto.IdentityView{ID: "test"},
},
Content: "test",
}
if managedRoom, ok := room.(proto.ManagedRoom); ok {
key, err := managedRoom.MessageKey(ctx)
if err != nil {
return proto.Message{}, err
}
if key != nil {
mkey := key.ManagedKey()
if err := kms.DecryptKey(&mkey); err != nil {
return proto.Message{}, err
}
if err := proto.EncryptMessage(&msg, key.KeyID(), &mkey); err != nil {
return proto.Message{}, err
}
}
}
return room.Send(ctx, session, msg)
}
Convey("Delete message in public room", t, func() {
ctrl := &Controller{
backend: &mock.TestBackend{},
kms: kms,
}
term := &testTerm{}
public, err := ctrl.backend.CreateRoom(ctx, kms, false, "public")
So(err, ShouldBeNil)
sent, err := sendMessage(public)
So(err, ShouldBeNil)
runCommand(ctx, ctrl, "delete-message", term, []string{"public:" + sent.ID.String()})
deleted, err := public.GetMessage(ctx, sent.ID)
So(err, ShouldBeNil)
So(time.Time(deleted.Deleted).IsZero(), ShouldBeFalse)
})
Convey("Delete message in private room", t, func() {
ctrl := &Controller{
backend: &mock.TestBackend{},
kms: kms,
}
term := &testTerm{}
private, err := ctrl.backend.CreateRoom(ctx, kms, true, "private")
So(err, ShouldBeNil)
runCommand(ctx, ctrl, "lock-room", term, []string{"private"})
sent, err := sendMessage(private)
So(err, ShouldBeNil)
runCommand(ctx, ctrl, "delete-message", term, []string{"private:" + sent.ID.String()})
deleted, err := private.GetMessage(ctx, sent.ID)
So(err, ShouldBeNil)
So(time.Time(deleted.Deleted).IsZero(), ShouldBeFalse)
})
}
开发者ID:logan,项目名称:heim,代码行数:75,代码来源:message_test.go
示例17: TestGrants
func TestGrants(t *testing.T) {
Convey("Grant a capability on a room", t, func() {
kms := security.LocalKMS()
kms.SetMasterKey(make([]byte, security.AES256.KeySize()))
ctx := scope.New()
client := &proto.Client{Agent: &proto.Agent{}}
client.FromRequest(ctx, &http.Request{})
backend := &mock.TestBackend{}
room, err := backend.CreateRoom(ctx, kms, true, "test")
So(err, ShouldBeNil)
rkey, err := room.MessageKey(ctx)
So(err, ShouldBeNil)
mkey := rkey.ManagedKey()
So(kms.DecryptKey(&mkey), ShouldBeNil)
// Sign in as alice and send an encrypted message with aliceSendTime
// as the nonce.
aliceSendTime := time.Now()
msgNonce := []byte(snowflake.NewFromTime(aliceSendTime).String())
aliceKey := &security.ManagedKey{
KeyType: security.AES256,
Plaintext: make([]byte, security.AES256.KeySize()),
}
grant, err := security.GrantSharedSecretCapability(aliceKey, rkey.Nonce(), nil, mkey.Plaintext)
So(err, ShouldBeNil)
alice := mock.TestSession("Alice", "A1", "ip1")
_, err = room.Join(ctx, alice)
So(err, ShouldBeNil)
msg := proto.Message{
ID: snowflake.NewFromTime(aliceSendTime),
UnixTime: proto.Time(aliceSendTime),
Content: "hello",
}
iv, err := base64.URLEncoding.DecodeString(grant.CapabilityID())
So(err, ShouldBeNil)
payload := grant.EncryptedPayload()
So(aliceKey.BlockCrypt(iv, aliceKey.Plaintext, payload, false), ShouldBeNil)
key := &security.ManagedKey{
KeyType: security.AES128,
}
So(json.Unmarshal(aliceKey.Unpad(payload), &key.Plaintext), ShouldBeNil)
digest, ciphertext, err := security.EncryptGCM(
key, msgNonce, []byte(msg.Content), []byte("Alice"))
So(err, ShouldBeNil)
digestStr := base64.URLEncoding.EncodeToString(digest)
cipherStr := base64.URLEncoding.EncodeToString(ciphertext)
msg.Content = digestStr + "/" + cipherStr
_, err = room.Send(ctx, alice, msg)
So(err, ShouldBeNil)
// Now sign in as bob and decrypt the message.
bobKey := &security.ManagedKey{
KeyType: security.AES256,
Plaintext: make([]byte, security.AES256.KeySize()),
}
//bobKey.Plaintext[0] = 1
grant, err = security.GrantSharedSecretCapability(bobKey, rkey.Nonce(), nil, mkey.Plaintext)
So(err, ShouldBeNil)
iv, err = base64.URLEncoding.DecodeString(grant.CapabilityID())
So(err, ShouldBeNil)
payload = grant.EncryptedPayload()
So(bobKey.BlockCrypt(iv, bobKey.Plaintext, payload, false), ShouldBeNil)
key = &security.ManagedKey{
KeyType: security.AES128,
}
So(json.Unmarshal(bobKey.Unpad(payload), &key.Plaintext), ShouldBeNil)
bob := mock.TestSession("Bob", "B1", "ip2")
_, err = room.Join(ctx, bob)
So(err, ShouldBeNil)
log, err := room.Latest(ctx, 1, 0)
So(err, ShouldBeNil)
So(len(log), ShouldEqual, 1)
msg = log[0]
parts := strings.Split(msg.Content, "/")
So(len(parts), ShouldEqual, 2)
digest, err = base64.URLEncoding.DecodeString(parts[0])
So(err, ShouldBeNil)
ciphertext, err = base64.URLEncoding.DecodeString(parts[1])
So(err, ShouldBeNil)
plaintext, err := security.DecryptGCM(key, msgNonce, digest, ciphertext, []byte("Alice"))
So(err, ShouldBeNil)
So(string(plaintext), ShouldEqual, "hello")
})
}
开发者ID:logan,项目名称:heim,代码行数:96,代码来源:grants_test.go
注:本文中的euphoria/io/scope.New函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论