def setUp(self):
        self.client = Redis()
        self.client.flushdb()

        self.ac = AutoComplete(self.client)

        self.timeout = 3
class TestAutoComplete(unittest.TestCase):
    def setUp(self):
        self.client = Redis()
        self.client.flushdb()

        self.ac = AutoComplete(self.client)

        self.timeout = 3

    def test_feed_and_hint(self):
        self.ac.feed("黄晓明", 100)
        self.ac.feed("黄健翔", 70)
        self.ac.feed("黄健宏", 50)

        self.assertEqual(self.ac.hint("黄", 5), ["黄晓明", "黄健翔", "黄健宏"])

        self.assertEqual(self.ac.hint("黄健", 5), ["黄健翔", "黄健宏"])

        self.assertEqual(self.ac.hint("黄健", 1), ["黄健翔"])

    def test_expire_feature_works(self):
        print("创建一个只存在 {0} 秒钟的自动补全结果。".format(self.timeout))
        self.ac.feed("Redis", timeout=self.timeout)
        i = self.timeout
        while i != 0:
            print("倒数 {0} 秒钟……".format(i))
            sleep(1)
            i -= 1

        self.assertEqual(self.ac.hint("Re", 10), [])
        print("时间到,自动补全结果已自动被移除!")
Esempio n. 3
0
    def setUp(self):
        self.client = Redis(decode_responses=True)
        self.client.flushdb()

        self.ac = AutoComplete(self.client)

        self.timeout = 3
    def test_auto_complete(self):
        auto_complete = AutoComplete(self.client)
        auto_complete.feed("黄晓明", 3)
        auto_complete.feed("黄建宏", 2)
        auto_complete.feed("黄晓军", 1)

        assert auto_complete.hint("黄") == ["黄晓明", "黄建宏", "黄晓军"]
        assert auto_complete.hint("黄晓") == ["黄晓明", "黄晓军"]
Esempio n. 5
0
class TestAutoComplete(unittest.TestCase):
    def setUp(self):
        self.client = Redis(decode_responses=True)
        self.client.flushdb()

        self.ac = AutoComplete(self.client)

    def test_feed_and_hint(self):
        self.ac.feed("黄晓明", 100)
        self.ac.feed("黄健翔", 70)
        self.ac.feed("黄健宏", 50)

        self.assertEqual(self.ac.hint("黄", 5), ["黄晓明", "黄健翔", "黄健宏"])

        self.assertEqual(self.ac.hint("黄健", 5), ["黄健翔", "黄健宏"])

        self.assertEqual(self.ac.hint("黄健", 1), ["黄健翔"])
Esempio n. 6
0
class DemoApp(MDApp):
    user = None
    id = None
    identifier = None
    kind = None
    dialog = None
    Enter = False  # Indicate whether Pressing Enter will save the added RFID
    roster, names = find_roster()  # Look for Students Roster
    auto_complete = AutoComplete(
        names)  # Object which generates name suggestions
    suggestions = []  # Suggested names in case of roster
    current_count = 0  # Number of characters currently in the text field
    input_mode = False
    index = 0
    menu_items = []
    original_input = ""
    received = False

    def build(self):
        self.theme_cls.primary_palette = "Gray"
        self.title = "Smart Cabinet Admin Application"

        Window.bind(on_key_down=self._on_keyboard_down)

        screen = Builder.load_string(KV)
        return screen

    def _on_keyboard_down(self, *args):
        if self.root.current != "admin_routine" or not self.received:
            # Ignore keys unless in admin_routine and there is no dialog and
            return

        if args[2] == 41:
            # Escape button
            if self.dialog:
                self.dismiss()

            self.shrink_suggestions()
            return

        elif args[3] and args[3] in ALLOWED_CHARS:
            # an allowed character
            self.root.ids.identifier.text += args[3]
            self.original_input += args[3]
            if self.root.ids.identifier.text[:-1] in self.suggestions:
                # If a name is highlighted and user inputs letter, add letter to the suggested name
                self.original_input = self.root.ids.identifier.text[:-1] + args[
                    3]
                self.root.ids.identifier.text = self.original_input
                self.index = 0

        elif args[2] == 42 and self.root.ids.identifier.text:
            # backspace and there is a letter to delete
            self.original_input = self.root.ids.identifier.text
            self.root.ids.identifier.text = self.root.ids.identifier.text[:-1]
            self.original_input = self.original_input[:-1]
            self.index = 0
            if not self.root.ids.identifier.text:
                self.shrink_suggestions()
                return

        elif args[2] == 40:
            # If Enter key is pressed
            if self.dialog:
                # If dialog is open
                self.send_identifier()
                self.original_input = ""

            elif self.root.ids.identifier.text and self.received:
                # If dialog is closed, and Enter key is pressed:
                # If suggestions are shown, copy highlighted text and shrink suggestions
                # self.index = 0
                self.validate_identifier()
                self.shrink_suggestions()
            return

        # elif not self.roster or self.kind != "student":
        #     return

        elif args[
                2] == 81 and self.root.ids.identifier.text and not self.dialog:
            # down arrow
            self.index += 1
            self.index = min(self.index, len(self.suggestions) - 1)
        elif args[
                2] == 82 and self.root.ids.identifier.text and not self.dialog:
            # up arrow
            self.index -= 1
            self.index = max(self.index, 0)
        else:
            return

        # menu_items: [input text, 5 suggestions]
        if not self.roster or self.kind != "student":
            return
        if not self.menu_items:
            self.menu_items = [
                self.root.ids.identifier, self.root.ids.name0,
                self.root.ids.name1, self.root.ids.name2, self.root.ids.name3,
                self.root.ids.name4
            ]
        self.suggestions = [self.original_input] + self.auto_complete.auto(
            self.original_input, max_sugg=5)

        if len(self.suggestions) == 1:
            self.shrink_suggestions()
            return

        self.show_suggestions()
        self.highlight_suggestions()

        if self.index == 0:
            self.root.ids.identifier.text = self.original_input
        for idx in range(1, 6):
            # Populate the name suggestions as needed
            try:
                self.menu_items[idx].text = self.suggestions[idx]
            except IndexError:
                self.menu_items[idx].text = ""
                pass

    def show_suggestions(self):
        self.input_mode = True
        # Show suggestions
        self.root.ids.name_list.size_hint_y = (len(self.suggestions) -
                                               1) * 0.06
        self.root.ids.name_list.pos_hint = {
            "center_y": 0.47 - (len(self.suggestions) - 1) / 2 * .06,
            "center_x": .5
        }

    def shrink_suggestions(self):
        self.input_mode = False
        self.root.ids.name_list.size_hint_y = 0
        self.root.ids.name_list.pos_hint = {"center_y": .47, "center_x": .5}

    def highlight_suggestions(self):
        for idx in range(1, 6):
            if idx == self.index:
                if not self.menu_items[self.index].text:
                    continue
                self.menu_items[self.index].bg_color = SUGG_COLOR
            else:
                self.menu_items[idx].bg_color = SUGG_MENU_COLOR

        self.root.ids.identifier.text = self.menu_items[self.index].text

    def on_start(self):
        return

    def on_stop(self):
        try:
            self.user.close()
        except AttributeError:
            pass

    def connect2(self):
        self.user = Admin(gui=True)
        self.root.transition = SlideTransition(direction='left')
        self.root.current = "access_screen"
        self.root.ids.spinner2.active = False

    def connect(self):
        self.root.ids.spinner2.active = True
        executor = concurrent.futures.ThreadPoolExecutor()
        f = executor.submit(self.connect2)

    def admin_routine(self, kind):
        # Go to admin_routine screen and save the kind of RFID to be added
        self.root.transition = SlideTransition(direction='left')
        self.root.current = "admin_routine"
        self.kind = kind

    def get_id(self):
        # Get the Scanned ID, and allow user to input name (identifier)
        self.root.ids.id_label.text = ""
        self.root.ids.spinner.active = True
        executor = concurrent.futures.ThreadPoolExecutor()
        f = executor.submit(self.receive)

    def receive(self):
        self.user.send_msg(self.kind.encode())
        self.id = self.user.get_msg().decode()
        self.root.ids.id_label.text = self.id
        self.root.ids.identifier.hint_text = "Enter Name"

        self.received = True
        self.root.ids.spinner.active = False

    def back_btn(self):
        if self.received:
            return
        self.root.transition = SlideTransition(direction='right')
        self.root.current = "access_screen"
        self.root.ids.identifier.text = ""
        self.root.ids.id_label.text = ""

    def validate_identifier(self):
        self.identifier = self.root.ids.identifier
        if not self.identifier.text:
            return

        self.dialog = MDDialog(
            title='Name Check',
            text=f"Are you sure you want to save {self.identifier.text}?",
            size_hint=(0.8, 1),
            buttons=[ConfirmBtn(on_release=self.send_identifier)],
        )
        self.dialog.open()

    def dismiss(self):
        if self.dialog:
            self.dialog.dismiss()
            self.dialog = None

    def send_identifier(self, *args):
        print(self.identifier.text, "Sent!")
        self.dismiss()
        name = self.identifier.text.strip()
        self.user.send_msg(name.encode())
        self.root.ids.id_label.text = "SAVED"

        self.identifier.hint_text = ""
        self.identifier.disabled = True
        self.root.ids.get_id.disabled = False
        self.original_input = ""
        self.index = 0
        self.suggestions = []
        self.menu_items = []
        self.received = False