You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.9 KiB

7 years ago
7 years ago
  1. #!/usr/bin/python3
  2. from string import ascii_lowercase
  3. import argparse
  4. import os
  5. import re
  6. import cmd2
  7. from candidate_cache import CandidateCache
  8. from dictionary import DICTS
  9. from word_remove_dialog import RemoveWordsActivity
  10. LOWERCASE = set(ascii_lowercase)
  11. # argparsers
  12. dictionary_manage_parser = argparse.ArgumentParser()
  13. commands = dictionary_manage_parser.add_mutually_exclusive_group(required=True)
  14. commands.add_argument(
  15. "-l", "--list", action="store_true", help="List available dictionaries"
  16. )
  17. commands.add_argument("-s", "--switch", help="Dictionary to swap to")
  18. letter_set_manage = argparse.ArgumentParser()
  19. letter_set_manage.add_argument("letter", nargs="+")
  20. guessing = argparse.ArgumentParser()
  21. guessing.add_argument("pattern", help="Pattern to match")
  22. hide_exclude = argparse.ArgumentParser()
  23. commands = hide_exclude.add_mutually_exclusive_group(required=True)
  24. commands.add_argument(
  25. "-e",
  26. "--edit",
  27. help="Change which words will be hidden from view",
  28. action="store_true",
  29. )
  30. commands.add_argument(
  31. "-c", "--commit", help="Move excluded words to be hidden words", action="store_true"
  32. )
  33. commands.add_argument(
  34. "-s",
  35. "--show",
  36. help="Show which words are in the current exclude list",
  37. action="store_true",
  38. )
  39. class MainLoop(cmd2.Cmd):
  40. """Loop for wordscape commands
  41. """
  42. prompt = "<{}> $ "
  43. def __init__(self):
  44. self.dict = "default"
  45. self.excludes = set()
  46. self.hidden = set()
  47. self.init_letters(input("Enter letters: "))
  48. self.cache = CandidateCache()
  49. super().__init__()
  50. def init_letters(self, letters):
  51. if not isinstance(letters, str):
  52. letters = "".join(letters)
  53. letters = letters.lower()
  54. self.letters = [l for l in letters if l in LOWERCASE]
  55. self.prompt = MainLoop.prompt.format(", ".join(self.letters))
  56. @property
  57. def candidates(self):
  58. return self.cache.get(self.dict, self.letters)
  59. def filter(self, regex):
  60. return set(filter(regex.match, self.candidates))
  61. @cmd2.with_argparser(dictionary_manage_parser)
  62. def do_dict(self, args):
  63. """list/switch dict"""
  64. if args.list:
  65. print(
  66. "\n".join(
  67. (
  68. "{} {}".format("*" if key == self.dict else " ", key)
  69. for key in DICTS.keys()
  70. )
  71. )
  72. )
  73. else:
  74. DICTS[args.switch]
  75. self.dict = args.switch
  76. @cmd2.with_argparser(letter_set_manage)
  77. def do_change_letters(self, args):
  78. """Change the letters on the board"""
  79. self.init_letters(args.letter)
  80. @cmd2.with_argparser(guessing)
  81. def do_find(self, args):
  82. """Find words that match a pattern"""
  83. pattern = re.compile(args.pattern + "$")
  84. matching_words = self.filter(pattern)
  85. app = RemoveWordsActivity(matching_words - self.hidden, self.excludes)
  86. if os.name == "nt":
  87. app.run(fork=False)
  88. else:
  89. app.run()
  90. was_canceled, new_exludes = app.get_results()
  91. if not was_canceled:
  92. self.excludes.update(new_exludes)
  93. @cmd2.with_argparser(hide_exclude)
  94. def do_hide(self, args):
  95. """Hide words that are in the exclude list"""
  96. if args.show:
  97. print("\n".join(sorted(self.excludes)))
  98. return
  99. if args.commit:
  100. self.hidden.update(self.excludes)
  101. self.excludes = set()
  102. return
  103. if args.edit:
  104. app = RemoveWordsActivity(self.excludes, self.hidden)
  105. if os.name == "nt":
  106. app.run(fork=False)
  107. else:
  108. app.run()
  109. was_canceled, results = app.get_results()
  110. if not was_canceled:
  111. result_set = set(results)
  112. self.excludes = self.hidden - result_set
  113. self.hidden = result_set
  114. return
  115. if __name__ == "__main__":
  116. MainLoop().cmdloop()