Skip to content

Commit

Permalink
extract Oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
semicontinuity committed Jun 19, 2022
1 parent 5131d32 commit 13b34da
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 35 deletions.
48 changes: 40 additions & 8 deletions fsel/app.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import json
import os
import sys
from typing import Callable, List, Tuple, Dict
from typing import Callable, List, Tuple, Dict, AnyStr

from fsel.sdk import FsListFiles, update_recents, run_dialog, ItemSelectionDialog, full_path, item_model, field_or_else, \
FsModel, ListBoxes, SelectPathDialog
FsModel, ListBoxes, SelectPathDialog, Oracle


def load_settings():
Expand Down Expand Up @@ -46,12 +46,12 @@ def run(self, recent_items):

class AppSelectInPanes(FsApp):

def run(self, folder: str, file_lister: Callable[[List], List[Tuple[str, int]]], root_history):
fs_model = FsModel(self.root, root_history, file_lister)
def run(self, dir: str, fs_model, root_history):
fs_oracle = FsOracle(self.root, root_history)

rel_path = os.path.relpath(folder, self.root)
rel_path = os.path.relpath(dir, self.root)
initial_path = rel_path.split('/') if rel_path != '.' else []
folder_lists = ListBoxes(fs_model, initial_path)
folder_lists = ListBoxes(fs_model, fs_oracle, initial_path)
if folder_lists.is_empty():
sys.exit(2)

Expand Down Expand Up @@ -87,6 +87,38 @@ def find_root(folder, settings: Dict) -> Tuple[str, str]:
path = parent_path


class FsOracle(Oracle):
def __init__(self, root: AnyStr, root_history: Dict):
self.root = root
self.root_history = root_history
self.visit_history = {}

def memorize(self, path: List[AnyStr], name: AnyStr, persistent: bool):
storage = self.root_history if persistent else self.visit_history
storage[self.string_path(path)] = name

def recall_chosen_name(self, path):
string_path = self.string_path(path)
return self.visit_history.get(string_path) or \
self.root_history.get(string_path)

def recall_choice(self, path, items) -> int:
string_path = self.string_path(path)
return FsOracle.recall_choice_in(self.visit_history, string_path, items) or \
FsOracle.recall_choice_in(self.root_history, string_path, items)

@staticmethod
def recall_choice_in(storage, path, items) -> int:
if path in storage:
last_name = storage[path]
if last_name is not None:
return item_model.index_of_item_text(last_name, items)

@staticmethod
def string_path(path):
return '/'.join(path)


if __name__ == "__main__":
if sys.stdin.isatty():
path_args = [arg for arg in sys.argv[1:] if not arg.startswith('-')]
Expand Down Expand Up @@ -115,8 +147,8 @@ def find_root(folder, settings: Dict) -> Tuple[str, str]:
path = app.run([(name, False) for name in recent])
else:
app = AppSelectInPanes(root)
path = app.run(folder, FsListFiles(app.root, target_is_file, target_is_executable),
root_history = field_or_else(settings_for_root, 'history', {}))
lister = FsListFiles(app.root, target_is_file, target_is_executable)
path = app.run(folder, FsModel(root, lister), root_history = field_or_else(settings_for_root, 'history', {}))

if path is None:
sys.exit(1)
Expand Down
39 changes: 12 additions & 27 deletions fsel/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,9 @@ def is_suitable_file_path(self, path):


class FsModel:
def __init__(self, root: AnyStr, root_history: Dict, file_lister: Callable[[List], List[Tuple[str, int]]]):
def __init__(self, root: AnyStr, file_lister: Callable[[List], List[Tuple[str, int]]]):
self.root = root
self.file_lister = file_lister
self.root_history = root_history
self.visit_history = {}

def list_items(self, path: List) -> List[Tuple[str, int]]:
""" Each item is a tuple; last element of tuple is int with item attributes (same as in st_mode) """
Expand All @@ -143,30 +141,16 @@ def list_folders(self, path: List) -> List[Tuple[str, int]]:
def full_path(self, items_path):
return os.path.join(self.root, *[item_model.item_text(i) for i in items_path])


class Oracle:
def memorize(self, path: List[AnyStr], name: AnyStr, persistent: bool):
storage = self.root_history if persistent else self.visit_history
storage[self.string_path(path)] = name
pass

def recall_chosen_name(self, path):
string_path = self.string_path(path)
return self.visit_history.get(string_path) or \
self.root_history.get(string_path)
pass

def recall_choice(self, path, items):
string_path = self.string_path(path)
return FsModel.recall_choice_in(self.visit_history, string_path, items) or \
FsModel.recall_choice_in(self.root_history, string_path, items)

@staticmethod
def recall_choice_in(storage, path, items):
if path in storage:
last_name = storage[path]
if last_name is not None:
return item_model.index_of_item_text(last_name, items)

@staticmethod
def string_path(path):
return '/'.join(path)
pass


class JsonModel:
Expand Down Expand Up @@ -209,7 +193,7 @@ def max_item_text_length(self, items):
def item_text(self, item: Tuple[str, int]):
return item[0]

def index_of_item_text(self, text, items):
def index_of_item_text(self, text, items) -> int:
for i, item in enumerate(items):
if text == self.item_text(item):
return i
Expand Down Expand Up @@ -291,8 +275,9 @@ class ListBoxes:
boxes: List[CustomListBox]
search_string: str = ''

def __init__(self, tree_model, initial_path):
def __init__(self, tree_model, oracle: Oracle, initial_path):
self.tree_model = tree_model
self.oracle = oracle
self.boxes = self.boxes_for_path(initial_path)
self.expand_lists()

Expand Down Expand Up @@ -322,7 +307,7 @@ def expand_lists(self):
if self.is_at_leaf(index):
break
path = self.path(index)
name = self.tree_model.recall_chosen_name(path)
name = self.oracle.recall_chosen_name(path)
index += 1
a_list = self.make_box_or_none(path)
if a_list is None or a_list.cur_line is None:
Expand Down Expand Up @@ -360,13 +345,13 @@ def make_box_or_none(self, path: List) -> Optional[CustomListBox]:

def make_box(self, path, items: List[Tuple[str, int]]):
box = CustomListBox(item_model.max_item_text_length(items), len(items), items, path, lambda: self.search_string)
choice = self.tree_model.recall_choice(path, items)
choice = self.oracle.recall_choice(path, items)
box.cur_line = box.choice = 0 if choice is None else choice
return box

def memorize_choice_in_list(self, index, persistent: bool):
parent_path = [] if index == 0 else self.path(index - 1)
self.tree_model.memorize(parent_path, item_model.item_text(self.selected_item_in_list(index)), persistent)
self.oracle.memorize(parent_path, item_model.item_text(self.selected_item_in_list(index)), persistent)

def index_of_last_list(self):
return len(self.boxes) - 1
Expand Down

0 comments on commit 13b34da

Please sign in to comment.