pymud 0.19.0__py3-none-any.whl → 0.19.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pymud/__main__.py CHANGED
@@ -1,4 +1,4 @@
1
- import sys, os, json, platform, shutil
1
+ import sys, os, json, platform, shutil, logging
2
2
  from .pymud import main
3
3
  from .settings import Settings
4
4
 
@@ -31,6 +31,12 @@ CFG_TEMPLATE = {
31
31
  "display_title" : ["yourid", "yourpassword", ""],
32
32
  }
33
33
  }
34
+ },
35
+ "keys" : {
36
+ "f3" : "#ig",
37
+ "f4" : "#clear",
38
+ "f11" : "#close",
39
+ "f12" : "#exit",
34
40
  }
35
41
  }
36
42
 
@@ -75,6 +81,15 @@ if __name__ == "__main__":
75
81
 
76
82
  input('所有内容已初始化完毕, 请按回车进入PyMUD.')
77
83
 
84
+ if (len(args) == 2) and (args[1] == "withlog"):
85
+ # 指定带log时,打印log信息
86
+ # 所有级别log都存入文件
87
+ logging.basicConfig(level=logging.NOTSET,
88
+ format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
89
+ datefmt='%m-%d %H:%M',
90
+ filename='myapp.log',
91
+ filemode='a')
92
+
78
93
  cfg = "pymud.cfg"
79
94
  if os.path.exists(cfg):
80
95
  with open(cfg, "r", encoding="utf8", errors="ignore") as fp:
pymud/pymud.py CHANGED
@@ -1,4 +1,4 @@
1
- import asyncio, functools, re, logging, math, json, os
1
+ import asyncio, functools, re, logging, math, json, os, webbrowser
2
2
  import importlib.util
3
3
  from prompt_toolkit.shortcuts import set_title
4
4
  from prompt_toolkit.output import ColorDepth
@@ -49,7 +49,30 @@ class STATUS_DISPLAY(Enum):
49
49
  FLOAT = 3
50
50
 
51
51
  class PyMudApp:
52
+ """
53
+ PYMUD程序管理主对象,对窗体、操作及所有会话进行管理。
54
+
55
+ PyMudApp对象不需要手动创建,在命令行中执行 ``python -m pymud`` 时会自动创建对象实例。
56
+
57
+ 构造函数参数:
58
+ - ``cfg_data``: 替代配置数据,由本地pymud.cfg文件读取,用于覆盖settings.py中的默认Settings数据
59
+
60
+ 可替代字典: 含义请查阅 `应用配置及本地化 <settings.html>`_
61
+ - sessions: 用于创建菜单栏会话的字典
62
+ - client: 用于配置客户端属性的字典
63
+ - text: 用于各默认显示文字内容的字典
64
+ - server: 用于服务器选项的配置字典
65
+ - styles: 用于显示样式的定义字典
66
+ - keys: 用于快捷键定义的字典
67
+
68
+ *替代配置按不同的dict使用dict.update进行更新覆盖,因此可以仅指定需替代的部分。*
69
+ """
70
+
52
71
  def __init__(self, cfg_data = None) -> None:
72
+ """
73
+ 构造PyMudApp对象实例,并加载替代配置。
74
+ """
75
+
53
76
  if cfg_data and isinstance(cfg_data, dict):
54
77
  for key in cfg_data.keys():
55
78
  if key == "sessions":
@@ -65,6 +88,7 @@ class PyMudApp:
65
88
  elif key == "keys":
66
89
  Settings.keys.update(cfg_data[key])
67
90
 
91
+ self._mouse_support = True
68
92
  self._plugins = DotDict() # 增加 插件 字典
69
93
  self._globals = DotDict() # 增加所有session使用的全局变量
70
94
  self.sessions = {}
@@ -81,8 +105,10 @@ class PyMudApp:
81
105
  self.keybindings.add(Keys.Backspace)(self.delete_selection)
82
106
  self.keybindings.add(Keys.ControlLeft, is_global = True)(self.change_session) # Control-左右箭头切换当前会话
83
107
  self.keybindings.add(Keys.ControlRight, is_global = True)(self.change_session)
108
+ self.keybindings.add(Keys.F1, is_global=True)(lambda event: webbrowser.open(Settings.__website__))
109
+ self.keybindings.add(Keys.F2, is_global=True)(self.toggle_mousesupport)
84
110
 
85
- used_keys = [Keys.PageUp, Keys.PageDown, Keys.ControlZ, Keys.ControlC, Keys.ControlR, Keys.Up, Keys.Down, Keys.Left, Keys.Right, Keys.ControlLeft, Keys.ControlRight, Keys.Backspace, Keys.Delete]
111
+ used_keys = [Keys.PageUp, Keys.PageDown, Keys.ControlZ, Keys.ControlC, Keys.ControlR, Keys.Up, Keys.Down, Keys.Left, Keys.Right, Keys.ControlLeft, Keys.ControlRight, Keys.Backspace, Keys.Delete, Keys.F1, Keys.F2]
86
112
 
87
113
  for key, binding in Settings.keys.items():
88
114
  if (key not in used_keys) and binding and isinstance(binding, str):
@@ -95,6 +121,7 @@ class PyMudApp:
95
121
  try:
96
122
  clipboard = PyperclipClipboard()
97
123
  clipboard.set_text("test pyperclip")
124
+ clipboard.set_text("")
98
125
  except:
99
126
  clipboard = None
100
127
 
@@ -102,7 +129,7 @@ class PyMudApp:
102
129
  layout = Layout(self.root_container, focused_element=self.commandLine),
103
130
  enable_page_navigation_bindings=True,
104
131
  style=self.style,
105
- mouse_support=True,
132
+ mouse_support=to_filter(self._mouse_support),
106
133
  full_screen=True,
107
134
  color_depth=ColorDepth.TRUE_COLOR,
108
135
  clipboard=clipboard,
@@ -279,6 +306,11 @@ class PyMudApp:
279
306
  children=[
280
307
  MenuItem(Settings.text["about"], handler = self.act_about)
281
308
  ]
309
+ ),
310
+
311
+ MenuItem(
312
+ "", # 增加一个空名称MenuItem,阻止右侧空白栏点击响应
313
+ children=[]
282
314
  )
283
315
  ],
284
316
  floats=[
@@ -346,11 +378,13 @@ class PyMudApp:
346
378
  b.cursor_down(lines)
347
379
 
348
380
  def page_up(self, event: KeyPressEvent) -> None:
349
- lines = (self.app.output.get_size().rows - 5) // 2 - 1
381
+ #lines = (self.app.output.get_size().rows - 5) // 2 - 1
382
+ lines = self.get_height() // 2 - 1
350
383
  self.scroll(-1 * lines)
351
384
 
352
385
  def page_down(self, event: KeyPressEvent) -> None:
353
- lines = (self.app.output.get_size().rows - 5) // 2 - 1
386
+ #lines = (self.app.output.get_size().rows - 5) // 2 - 1
387
+ lines = self.get_height() // 2 - 1
354
388
  self.scroll(lines)
355
389
 
356
390
  def custom_key_press(self, event: KeyPressEvent):
@@ -404,6 +438,13 @@ class PyMudApp:
404
438
  new_key = keys[idx-1]
405
439
  self.activate_session(new_key)
406
440
 
441
+ def toggle_mousesupport(self, event: KeyPressEvent):
442
+ self._mouse_support = not self._mouse_support
443
+ if self._mouse_support:
444
+ self.app.renderer.output.enable_mouse_support()
445
+ else:
446
+ self.app.renderer.output.disable_mouse_support()
447
+
407
448
  def copy(self, raw = False):
408
449
  b = self.consoleView.buffer
409
450
  if b.selection_state:
@@ -472,6 +513,10 @@ class PyMudApp:
472
513
  self.sessions[name] = session
473
514
  self.activate_session(name)
474
515
 
516
+ for plugin in self._plugins.values():
517
+ if isinstance(plugin, Plugin):
518
+ plugin.onSessionCreate(session)
519
+
475
520
  result = True
476
521
  else:
477
522
  self.set_status(f"错误!已存在一个名为{name}的会话,请更换名称再试.")
@@ -497,12 +542,17 @@ class PyMudApp:
497
542
  result = await self.show_dialog_as_float(dlgQuery)
498
543
  if result:
499
544
  self.current_session.disconnect()
545
+
546
+ # 增加延时等待确保会话关闭
547
+ while self.current_session.connected:
548
+ await asyncio.sleep(0.1)
549
+
500
550
  else:
501
551
  return
502
552
 
503
553
  for plugin in self._plugins.values():
504
554
  if isinstance(plugin, Plugin):
505
- plugin.onSessionCreate(self.current_session)
555
+ plugin.onSessionDestroy(self.current_session)
506
556
 
507
557
  name = self.current_session.name
508
558
  self.current_session.clean()
@@ -600,6 +650,11 @@ class PyMudApp:
600
650
  result = await self.show_dialog_as_float(dlgQuery)
601
651
  if result:
602
652
  session.disconnect()
653
+
654
+ # 增加延时等待确保会话关闭
655
+ while session.connected:
656
+ await asyncio.sleep(0.1)
657
+
603
658
  else:
604
659
  return
605
660
 
@@ -651,10 +706,13 @@ class PyMudApp:
651
706
  ]
652
707
 
653
708
  def get_statusbar_right_text(self):
654
- con_str, tri_status = "", ""
709
+ con_str, mouse_support, tri_status = "", "", ""
710
+ if not self._mouse_support:
711
+ mouse_support = "鼠标已禁用 "
712
+
655
713
  if self.current_session:
656
714
  if self.current_session._ignore:
657
- tri_status = "全局禁用"
715
+ tri_status = "全局禁用 "
658
716
 
659
717
  if not self.current_session.connected:
660
718
  con_str = "未连接"
@@ -678,7 +736,7 @@ class PyMudApp:
678
736
  else:
679
737
  con_str = "已连接:{:.0f}秒".format(sec)
680
738
 
681
- return "{} {} {} {} ".format(tri_status, con_str, Settings.__appname__, Settings.__version__)
739
+ return "{}{}{} {} {} ".format(mouse_support, tri_status, con_str, Settings.__appname__, Settings.__version__)
682
740
 
683
741
  def get_statuswindow_text(self):
684
742
  text = ""
@@ -692,13 +750,38 @@ class PyMudApp:
692
750
  self.app.invalidate()
693
751
 
694
752
  def handle_session(self, *args):
695
- "\x1b[1m命令\x1b[0m: #session {名称} {宿主机} {端口} {编码}\n" \
696
- " 创建一个远程连接会话,使用指定编码格式连接到远程宿主机的指定端口并保存为 {名称} \n" \
697
- " 如, #session newstart mud.pkuxkx.net 8080 GBK \n" \
698
- " 当不指定编码格式时, 默认使用utf-8编码 \n" \
699
- " 如, #session newstart mud.pkuxkx.net 8081 \n" \
700
- " 可以直接使用#{名称}将指定会话切换为当前会话,如#newstart \n" \
701
- "\x1b[1m相关\x1b[0m: help, exit\n"
753
+ '''
754
+ 嵌入命令 #session 的执行函数,创建一个远程连接会话。
755
+ 该函数不应该在代码中直接调用。
756
+
757
+ 使用:
758
+ - #session {Name} {Host} {Port} {Encoding}
759
+ - 当不指定 Encoding: 时, 默认使用utf-8编码
760
+ - 可以直接使用 #{名称} 切换会话和操作会话命令
761
+
762
+ 参数:
763
+ :Name: 会话名称
764
+ :Host: 服务器域名或IP地址
765
+ :Port: 端口号
766
+ :Encoding: 编码格式,不指定时默认为 utf8
767
+
768
+ 示例:
769
+ ``#session {名称} {宿主机} {端口} {编码}``
770
+ 创建一个远程连接会话,使用指定编码格式连接到远程宿主机的指定端口并保存为 {名称} 。其中,编码可以省略,此时使用Settings.server["default_encoding"]的值,默认为utf8
771
+ ``#session newstart mud.pkuxkx.net 8080 GBK``
772
+ 使用GBK编码连接到mud.pkuxkx.net的8080端口,并将该会话命名为newstart
773
+ ``#session newstart mud.pkuxkx.net 8081``
774
+ 使用UTF8编码连接到mud.pkuxkx.net的8081端口,并将该会话命名为newstart
775
+ ``#newstart``
776
+ 将名称为newstart的会话切换为当前会话
777
+ ``#newstart give miui gold``
778
+ 使名称为newstart的会话执行give miui gold指令,但不切换到该会话
779
+
780
+ 相关命令:
781
+ - #close
782
+ - #exit
783
+
784
+ '''
702
785
 
703
786
  nothandle = True
704
787
 
@@ -717,72 +800,6 @@ class PyMudApp:
717
800
  if nothandle:
718
801
  self.set_status("错误的#session命令")
719
802
 
720
- def handle_help(self, *args):
721
- "\x1b[1m命令\x1b[0m: #help {主题}\n" \
722
- " 当不带参数时, #help会列出所有可用的帮助主题\n" \
723
- "\x1b[1m相关\x1b[0m: session, exit\n"
724
-
725
- if self.current_session:
726
- if len(args) == 0: # 不带参数,打印所有支持的help主题
727
- self._print_all_help()
728
-
729
- elif len(args) >= 1: # 大于1个参数,第1个为 topic, 其余参数丢弃
730
- topic = args[0]
731
-
732
- if topic in ("exit", "close", "session", "help"):
733
- command = getattr(self, f"handle_{topic}", None)
734
- docstring = command.__doc__
735
- elif topic in self.current_session._commands_alias.keys():
736
- command = self.current_session._commands_alias[topic]
737
- docstring = self.current_session._cmds_handler[command].__doc__
738
- elif topic in self.current_session._sys_commands:
739
- docstring = self.current_session._cmds_handler[topic].__doc__
740
- else:
741
- docstring = f"未找到主题{topic}, 请确认输入是否正确."
742
-
743
- self.current_session.writetobuffer(docstring)
744
-
745
- else:
746
- self.act_about()
747
-
748
- def _print_all_help(self):
749
- """打印所有可用的help主题, 并根据终端尺寸进行排版"""
750
- width = self.get_width()
751
-
752
- cmds = ["exit", "close", "session", "all", "help"]
753
- cmds.extend(Session._commands_alias.keys())
754
- cmds.extend(Session._sys_commands)
755
- cmds.sort()
756
-
757
- cmd_count = len(cmds)
758
- left = (width - 8) // 2
759
- right = width - 8 - left
760
- self.current_session.writetobuffer("#"*left + " HELP " + "#"*right, newline = True)
761
- cmd_per_line = (width - 2) // 20
762
- lines = math.ceil(cmd_count / cmd_per_line)
763
- left_space = (width - cmd_per_line * 20) // 2
764
-
765
- for idx in range(0, lines):
766
- start = idx * cmd_per_line
767
- end = (idx + 1) * cmd_per_line
768
- if end > cmd_count: end = cmd_count
769
- line_cmds = cmds[start:end]
770
- self.current_session.writetobuffer(" " * left_space)
771
- for cmd in line_cmds:
772
- if cmd in Session._sys_commands:
773
- self.current_session.writetobuffer(f"{cmd.upper():<20}")
774
- else:
775
- self.current_session.writetobuffer(f"\x1b[32m{cmd.upper():<20}\x1b[0m")
776
-
777
- self.current_session.writetobuffer("", newline = True)
778
-
779
- self.current_session.writetobuffer("#"*width, newline = True)
780
-
781
- def handle_exit(self, *args):
782
- "\x1b[1m命令\x1b[0m: #exit \n" \
783
- " 退出PYMUD程序\n" \
784
- "\x1b[1m相关\x1b[0m: session\n"
785
-
786
803
  def enter_pressed(self, buffer: Buffer):
787
804
  cmd_line = buffer.text
788
805
  space_index = cmd_line.find(" ")
@@ -795,31 +812,15 @@ class PyMudApp:
795
812
  if self.current_session:
796
813
  self.current_session.last_command = cmd_line
797
814
 
798
- if cmd_line == "#exit":
799
- self.act_exit()
800
-
801
- elif cmd_line == "#close":
802
- self.close_session()
803
-
804
- elif cmd_line.startswith("#session"):
815
+ if cmd_line.startswith("#session"):
805
816
  cmd_tuple = cmd_line[1:].split()
806
817
  self.handle_session(*cmd_tuple[1:])
807
818
 
808
- elif cmd_line.startswith("#help"):
809
- #self.act_about()
810
- cmd_tuple = cmd_line[1:].split()
811
- self.handle_help(*cmd_tuple[1:])
812
-
813
- elif cmd_line[1:] in self.sessions.keys():
814
- self.activate_session(cmd_line[1:])
815
-
816
819
  else:
817
820
  if self.current_session:
818
821
  if len(cmd_line) == 0:
819
822
  self.current_session.writeline("")
820
823
  else:
821
- # 增加额外处置:当创建代码块出现异常时,直接执行本行内容
822
- # 是为了解决find-draw里面原图的有关内容,会出现引号、括号不匹配情况
823
824
  try:
824
825
  cb = CodeBlock(cmd_line)
825
826
  cb.execute(self.current_session)
@@ -962,7 +963,6 @@ class PyMudApp:
962
963
 
963
964
 
964
965
  def main(cfg_data = None):
965
- logging.disable()
966
966
  app = PyMudApp(cfg_data)
967
967
  app.run()
968
968