summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRishi-k-s <rishikrishna.sr@gmail.com>2025-07-05 20:02:22 +0530
committerRishi-k-s <rishikrishna.sr@gmail.com>2025-07-05 20:04:39 +0530
commitf5c8ccc4146944983b094ef72c8095f10ca0958c (patch)
tree3ccd87dd386d7423d3c372589e8c434011388756
parent5c31884e4b186251d816fb60b53c63ee49ca7c76 (diff)
Added TUI for file explorer but have to change the selection procrssHEADmain
-rw-r--r--main.py18
-rw-r--r--question2.tcss17
-rw-r--r--requirement_files_for_git/__init__.py1
-rw-r--r--requirement_files_for_git/__pycache__/__init__.cpython-312.pycbin0 -> 244 bytes
-rw-r--r--requirement_files_for_git/__pycache__/check_for_git_installations.cpython-312.pycbin0 -> 781 bytes
-rw-r--r--requirement_files_for_git/check_for_git_installations.py15
-rw-r--r--test.py439
7 files changed, 483 insertions, 7 deletions
diff --git a/main.py b/main.py
index 7b9483b..d71a995 100644
--- a/main.py
+++ b/main.py
@@ -1,13 +1,17 @@
-from textual.app import App
+import os
+from requirement_files_for_git import check_for_git_installation
-class MyApp(App):
- pass
+def main():
+ check_for_git_installation()
+ get_logseq_path = input("Enter LogSeq Path : ")
+ update_page_name = "syncall.md"
+ file_path_logseq = os.path.join(get_logseq_path, update_page_name)
+ with open(file_path_logseq, "w") as the_update_page:
+ the_update_page.write("## Yay, succesfully prepared the logseq git sync files\n")
+
-def main():
- app = MyApp()
- app.run()
if __name__ == "__main__":
- main() \ No newline at end of file
+ main()
diff --git a/question2.tcss b/question2.tcss
new file mode 100644
index 0000000..d13cb49
--- /dev/null
+++ b/question2.tcss
@@ -0,0 +1,17 @@
+Screen {
+ layout: grid;
+ grid-size: 2;
+ grid-gutter: 2;
+ padding: 2;
+}
+#question {
+ width: 100%;
+ height: 100%;
+ column-span: 2;
+ content-align: center bottom;
+ text-style: bold;
+}
+
+Button {
+ width: 100%;
+} \ No newline at end of file
diff --git a/requirement_files_for_git/__init__.py b/requirement_files_for_git/__init__.py
new file mode 100644
index 0000000..8fd80fb
--- /dev/null
+++ b/requirement_files_for_git/__init__.py
@@ -0,0 +1 @@
+from .check_for_git_installations import check_for_git_installation \ No newline at end of file
diff --git a/requirement_files_for_git/__pycache__/__init__.cpython-312.pyc b/requirement_files_for_git/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..03560c6
--- /dev/null
+++ b/requirement_files_for_git/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/requirement_files_for_git/__pycache__/check_for_git_installations.cpython-312.pyc b/requirement_files_for_git/__pycache__/check_for_git_installations.cpython-312.pyc
new file mode 100644
index 0000000..9385091
--- /dev/null
+++ b/requirement_files_for_git/__pycache__/check_for_git_installations.cpython-312.pyc
Binary files differ
diff --git a/requirement_files_for_git/check_for_git_installations.py b/requirement_files_for_git/check_for_git_installations.py
new file mode 100644
index 0000000..6a83e40
--- /dev/null
+++ b/requirement_files_for_git/check_for_git_installations.py
@@ -0,0 +1,15 @@
+import subprocess
+
+
+def check_for_git_installation() -> str:
+ result = subprocess.run(["which git"], shell=True, capture_output=True, text=True)
+ print(result.stdout)
+ if(result.stdout!= ""):
+ print(f"found git at {result.stdout}")
+ return result.stdout
+ else:
+ return ""
+
+
+if (__name__ == "__main__"):
+ check_for_git_installation() \ No newline at end of file
diff --git a/test.py b/test.py
new file mode 100644
index 0000000..9531018
--- /dev/null
+++ b/test.py
@@ -0,0 +1,439 @@
+#!/usr/bin/env python3
+"""
+Simple LogSeq Directory Selector - A cute terminal-based LogSeq folder picker
+"""
+
+import os
+import stat
+from pathlib import Path
+from datetime import datetime
+from typing import List, Optional, Tuple
+
+from textual.app import App, ComposeResult
+from textual.containers import Container, Horizontal, Vertical, Center
+from textual.widgets import (
+ Header,
+ Footer,
+ Static,
+ DataTable,
+ Input,
+ Button
+)
+from textual.reactive import reactive
+from textual.binding import Binding
+from textual.message import Message
+from textual import events
+
+
+class LogSeqValidator:
+ """Validates LogSeq directory structure"""
+
+ @staticmethod
+ def validate_logseq_structure(directory: Path) -> Tuple[bool, List[str]]:
+ """
+ Validate if directory follows LogSeq structure
+ Returns (is_valid, summary_list)
+ """
+ if not directory.exists() or not directory.is_dir():
+ return False, ["šŸ“ Path doesn't exist or isn't a directory"]
+
+ summary = []
+ is_valid = True
+
+ # Check for essential LogSeq items
+ required_items = ["logseq", "pages", "journals"]
+
+ for item in required_items:
+ item_path = directory / item
+ if item_path.exists() and item_path.is_dir():
+ summary.append(f"āœ… {item}/")
+ else:
+ summary.append(f"āŒ {item}/")
+ is_valid = False
+
+ # Quick check for content
+ try:
+ pages_dir = directory / "pages"
+ if pages_dir.exists():
+ md_count = len(list(pages_dir.glob("*.md")))
+ summary.append(f"šŸ“„ {md_count} pages")
+
+ journals_dir = directory / "journals"
+ if journals_dir.exists():
+ journal_count = len(list(journals_dir.glob("*.md")))
+ summary.append(f"šŸ“… {journal_count} journals")
+ except:
+ pass
+
+ return is_valid, summary
+
+
+class FileTable(DataTable):
+ """Cute file table for navigation"""
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.current_directory: Optional[Path] = None
+ self.directory_history: List[Path] = []
+ self.setup_table()
+
+ def setup_table(self):
+ """Setup the table columns"""
+ self.add_column("šŸ“ Name", key="name", width=50)
+ self.add_column("šŸ“Š Type", key="type", width=8)
+ self.add_column("šŸ“ Size", key="size", width=12)
+
+ def load_directory(self, directory: Path, add_to_history: bool = True):
+ """Load files from directory into table"""
+ if add_to_history and self.current_directory and self.current_directory != directory:
+ self.directory_history.append(self.current_directory)
+
+ self.current_directory = directory
+ self.clear()
+
+ if not directory.exists() or not directory.is_dir():
+ return
+
+ try:
+ entries = []
+
+ # Add back button if we have history
+ if self.directory_history:
+ entries.append(("šŸ”™ Back", "NAV", ""))
+
+ # Add parent directory if not root
+ if directory.parent != directory:
+ entries.append(("ā¬†ļø Up", "NAV", ""))
+
+ # Get directory contents
+ directories = []
+ files = []
+
+ for item in directory.iterdir():
+ try:
+ # Skip some hidden files but keep important ones
+ if item.name.startswith('.') and item.name not in ['.logseq']:
+ continue
+
+ stat_info = item.stat()
+
+ if item.is_dir():
+ try:
+ item_count = len(list(item.iterdir()))
+ size = f"{item_count} items"
+ except:
+ size = "folder"
+ directories.append((f"šŸ“ {item.name}", "DIR", size))
+ else:
+ size = self._format_size(stat_info.st_size)
+ files.append((f"šŸ“„ {item.name}", "FILE", size))
+
+ except (PermissionError, OSError):
+ if item.is_dir():
+ directories.append((f"šŸ“ {item.name}", "DIR", "locked"))
+ else:
+ files.append((f"šŸ“„ {item.name}", "FILE", "locked"))
+
+ # Sort and combine
+ directories.sort(key=lambda x: x[0].lower())
+ files.sort(key=lambda x: x[0].lower())
+
+ entries.extend(directories)
+ entries.extend(files)
+
+ # Add rows to table
+ for entry in entries:
+ self.add_row(*entry)
+
+ except PermissionError:
+ self.add_row("šŸ”’ Permission denied", "ERROR", "")
+
+ def go_back(self) -> Optional[Path]:
+ """Go back to previous directory"""
+ if self.directory_history:
+ return self.directory_history.pop()
+ return None
+
+ def _format_size(self, size: int) -> str:
+ """Format file size in human-readable format"""
+ for unit in ['B', 'KB', 'MB', 'GB']:
+ if size < 1024.0:
+ return f"{size:.0f}{unit}"
+ size /= 1024.0
+ return f"{size:.0f}TB"
+
+
+class LogSeqStatus(Static):
+ """Cute status widget for LogSeq validation"""
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.current_path: Optional[Path] = None
+ self.is_valid = False
+
+ def check_logseq_structure(self, path: Path):
+ """Check and display LogSeq structure validation"""
+ self.current_path = path
+
+ is_valid, summary = LogSeqValidator.validate_logseq_structure(path)
+ self.is_valid = is_valid
+
+ if is_valid:
+ header = "šŸŽ‰ Valid LogSeq Directory!"
+ header_style = "bold green"
+ else:
+ header = "āŒ Not a LogSeq Directory"
+ header_style = "bold red"
+
+ status_text = f"[{header_style}]{header}[/{header_style}]\n\n"
+
+ # Show summary
+ for item in summary:
+ status_text += f"{item}\n"
+
+ # Show path
+ status_text += f"\nšŸ“‚ [dim]{str(path)}[/dim]"
+
+ self.update(status_text)
+
+
+class LogSeqDirectorySelector(App):
+ """Simple and cute LogSeq Directory Selector"""
+
+ CSS = """
+ Screen {
+ layout: vertical;
+ }
+
+ #header-container {
+ height: 6;
+ background: $primary;
+ color: $text;
+ padding: 1;
+ margin-bottom: 1;
+ }
+
+ #main-container {
+ height: 1fr;
+ layout: horizontal;
+ margin-bottom: 1;
+ }
+
+ #files-panel {
+ width: 2fr;
+ background: $surface;
+ border: solid $primary;
+ padding: 1;
+ margin-right: 1;
+ }
+
+ #status-panel {
+ width: 1fr;
+ background: $surface;
+ border: solid $primary;
+ padding: 1;
+ }
+
+ #path-input {
+ width: 100%;
+ margin-bottom: 1;
+ }
+
+ #buttons-container {
+ height: 4;
+ layout: horizontal;
+ align: center middle;
+ margin-top: 1;
+ }
+
+ Button {
+ margin: 0 1;
+ min-width: 15;
+ }
+
+ FileTable {
+ height: 1fr;
+ }
+
+ LogSeqStatus {
+ height: 1fr;
+ }
+
+ .title {
+ text-align: center;
+ margin-bottom: 1;
+ }
+ """
+
+ BINDINGS = [
+ Binding("q", "quit", "Quit"),
+ Binding("r", "refresh", "Refresh"),
+ Binding("ctrl+l", "focus_path", "Focus Path"),
+ Binding("enter", "open_selected", "Open"),
+ Binding("backspace", "go_back", "Back"),
+ Binding("ctrl+s", "select_current", "Select"),
+ ]
+
+ current_directory = reactive(Path.cwd())
+ selected_directory: Optional[Path] = None
+
+ def __init__(self):
+ super().__init__()
+ self.title = "LogSeq Directory Selector"
+ self.sub_title = "Find your LogSeq folder šŸ“"
+
+ def compose(self) -> ComposeResult:
+ """Compose the cute UI"""
+ yield Header(show_clock=True)
+
+ with Container(id="header-container"):
+ yield Static("[bold]šŸ” LogSeq Directory Selector[/bold]", classes="title")
+ yield Input(
+ placeholder="šŸ  Enter path or browse below...",
+ value=str(self.current_directory),
+ id="path-input"
+ )
+
+ with Container(id="main-container"):
+ with Container(id="files-panel"):
+ yield Static("šŸ“‚ [bold]Files & Folders[/bold]")
+ yield FileTable(id="file-table")
+
+ with Container(id="status-panel"):
+ yield Static("āœ… [bold]LogSeq Check[/bold]")
+ yield LogSeqStatus(id="logseq-status")
+
+ with Center(id="buttons-container"):
+ yield Button("šŸ”™ Back", id="back-btn", variant="default")
+ yield Button("šŸ”„ Refresh", id="refresh-btn", variant="primary")
+ yield Button("āœ… Select This Folder", id="select-btn", variant="success")
+
+ yield Footer()
+
+ def on_mount(self) -> None:
+ """Initialize the cute app"""
+ self.refresh_all()
+
+ def on_file_table_row_selected(self, event: DataTable.RowSelected) -> None:
+ """Handle cute file selection"""
+ table = self.query_one("#file-table", FileTable)
+
+ if table.current_directory and event.row_key is not None:
+ row_data = table.get_row(event.row_key)
+ filename = row_data[0]
+
+ # Handle navigation
+ if filename == "šŸ”™ Back":
+ self.action_go_back()
+ elif filename == "ā¬†ļø Up":
+ self.current_directory = table.current_directory.parent
+ self.refresh_all()
+ elif row_data[1] == "DIR":
+ # Remove emoji and get actual folder name
+ folder_name = filename.replace("šŸ“ ", "")
+ selected_path = table.current_directory / folder_name
+ self.check_logseq_structure(selected_path)
+
+ def on_input_submitted(self, event: Input.Submitted) -> None:
+ """Handle path input"""
+ if event.input.id == "path-input":
+ try:
+ new_path = Path(event.value).expanduser().resolve()
+ if new_path.exists() and new_path.is_dir():
+ self.current_directory = new_path
+ self.refresh_all()
+ else:
+ self.notify("🚫 Invalid path or not a directory", severity="error")
+ except Exception as e:
+ self.notify(f"āŒ Error: {str(e)}", severity="error")
+
+ def on_button_pressed(self, event: Button.Pressed) -> None:
+ """Handle cute button presses"""
+ if event.button.id == "select-btn":
+ self.action_select_current()
+ elif event.button.id == "refresh-btn":
+ self.action_refresh()
+ elif event.button.id == "back-btn":
+ self.action_go_back()
+
+ def action_open_selected(self) -> None:
+ """Open selected folder"""
+ table = self.query_one("#file-table", FileTable)
+
+ if table.cursor_row is not None and table.current_directory:
+ row_data = table.get_row(table.cursor_row)
+ filename = row_data[0]
+
+ if filename == "šŸ”™ Back":
+ self.action_go_back()
+ elif filename == "ā¬†ļø Up":
+ self.current_directory = table.current_directory.parent
+ self.refresh_all()
+ elif row_data[1] == "DIR":
+ folder_name = filename.replace("šŸ“ ", "")
+ new_path = table.current_directory / folder_name
+ self.current_directory = new_path
+ self.refresh_all()
+
+ def action_go_back(self) -> None:
+ """Go back cutely"""
+ table = self.query_one("#file-table", FileTable)
+ previous_dir = table.go_back()
+
+ if previous_dir:
+ self.current_directory = previous_dir
+ self.refresh_all()
+ else:
+ self.notify("šŸ  Already at the starting point!")
+
+ def action_select_current(self) -> None:
+ """Select current directory as LogSeq folder"""
+ status_widget = self.query_one("#logseq-status", LogSeqStatus)
+
+ if hasattr(status_widget, 'is_valid') and status_widget.is_valid:
+ self.selected_directory = self.current_directory
+ self.notify(f"šŸŽ‰ Selected: {self.current_directory.name}", title="LogSeq Directory Selected!", severity="information")
+ # You could add code here to save the selection or exit
+ print(f"Selected LogSeq directory: {self.current_directory}")
+ else:
+ self.notify("āŒ Can't select: Not a valid LogSeq directory", severity="error")
+
+ def action_refresh(self) -> None:
+ """Refresh cutely"""
+ self.refresh_all()
+ self.notify("šŸ”„ Refreshed!")
+
+ def action_focus_path(self) -> None:
+ """Focus the path input"""
+ self.query_one("#path-input").focus()
+
+ def check_logseq_structure(self, path: Optional[Path] = None) -> None:
+ """Check LogSeq structure"""
+ target_path = path or self.current_directory
+ logseq_status = self.query_one("#logseq-status", LogSeqStatus)
+ logseq_status.check_logseq_structure(target_path)
+
+ def refresh_all(self) -> None:
+ """Refresh everything cutely"""
+ self.sub_title = f"šŸ“‚ {self.current_directory.name}"
+
+ # Update path input
+ path_input = self.query_one("#path-input", Input)
+ path_input.value = str(self.current_directory)
+
+ # Update file table
+ table = self.query_one("#file-table", FileTable)
+ table.load_directory(self.current_directory)
+
+ # Check current directory
+ self.check_logseq_structure()
+
+
+def main():
+ """Run the cute LogSeq directory selector"""
+ app = LogSeqDirectorySelector()
+ app.run()
+
+
+if __name__ == "__main__":
+ main() \ No newline at end of file